试图在StackOverflow信誉分布上计算Gini指数?


11

我正在尝试使用SO Data Explorer在SO信誉分布上计算基尼系数。我要实现的方程式是: 其中: =网站上的用户数; =用户序列号(1-225,000); =用户信誉。niyi

G(S)=1n1(n+12(i=1n(n+1i)yii=1nyi))
niyii

这就是我的实现方式(从此处复制):

DECLARE @numUsers int
SELECT @numUsers = COUNT(*) FROM Users
DECLARE @totalRep float
SELECT @totalRep = SUM(Users.Reputation) FROM Users
DECLARE @giniNominator float
SELECT @giniNominator = SUM( (@numUsers + 1 - CAST(Users.Id as Float)) * 
                              CAST(Users.Reputation as Float)) FROM Users
DECLARE @giniCalc float
SELECT @giniCalc = (@numUsers + 1 - 2*(@giniNominator / @totalRep)) / @numUsers
SELECT @giniCalc

我的结果是(当前)-0.53,但是这没有任何意义:我不确定哪怕它会变成负数,甚至在绝对价值上,我都希望不平等程度会更接近于1,因为声誉如何拥有的越多,它就会增长。

我是否在不知不觉中忽略了有关声誉/用户分布的某些假设?

我做错了什么?


您是对的,但我不确定为什么会影响计算?
yossale 2012年

3
我猜您的问题是关于Gini索引的性质和计算,而不是关于如何在SQL中实现(如果我错了,请纠正我)。如果是后者,我们应该将此迁移到SO。继续我的假设,我已经从SE数据站点复制了您的代码,但是如果您还可以为那些不太懂SQL的人也可以用伪代码重写它,则可能会有所帮助。
gung-恢复莫妮卡

@gung谢谢-我问的是计算,而不是SQL实现。我将用伪代码重新编写它
yossale 2012年

Answers:


1

使用SQL进行计算的方法如下:

with balances as (
    select '2018-01-01' as date, balance
    from unnest([1,2,3,4,5]) as balance -- Gini coef: 0.2666666666666667
    union all
    select '2018-01-02' as date, balance
    from unnest([3,3,3,3]) as balance -- Gini coef: 0.0
    union all
    select '2018-01-03' as date, balance
    from unnest([4,5,1,8,6,45,67,1,4,11]) as balance -- Gini coef: 0.625
),
ranked_balances as (
    select date, balance, row_number() over (partition by date order by balance desc) as rank
    from balances
)
SELECT date, 
    -- (1 − 2B) https://en.wikipedia.org/wiki/Gini_coefficient
    1 - 2 * sum((balance * (rank - 1) + balance / 2)) / count(*) / sum(balance) AS gini
FROM ranked_balances
GROUP BY date
ORDER BY date ASC
-- verify here http://shlegeris.com/gini

解释在这里https://medium.com/@medvedev1088/calculating-gini-coefficient-in-bigquery-3bc162c82168


12

SQL不太容易阅读代码,但是如果有帮助的话,如果我要计算基尼系数,这就是我会做的(用简单的英语)。

  1. 图出X(即,人与SO代表数)nx
  2. 从最低到最高排序x
  3. x
  4. nxn×
  5. 1(1/n)
  6. 瞧!

我从R函数(在ineq包中)中非常简单明了的代码中采取了这些步骤来计算基尼系数。作为记录,下面是该代码:

> ineq::Gini
function (x) 
{
    n <- length(x)
    x <- sort(x)
    G <- sum(x * 1:n)
    G <- 2 * G/(n * sum(x))
    G - 1 - (1/n)
}
<environment: namespace:ineq>

它看起来与您的SQL代码有些相似,但是就像我说的那样,我真的很难读懂它!


谢谢,你非常多!我错过了排序部分!解释了很多……
yossale 2012年

超。我有兴趣知道这个值是什么,所以在您计算时可能要留下评论!
smillig

好吧,当我汇总值时(例如,如果有10个人,得到1,3或5分,那么我只有3个等级:1:3,2:5,3:10)并乘以(多少得分)*得分*(得分等级),我得到-0.98,如果不是错误的符号,这将是有意义的。但是我不确定我的小捷径会如何影响基尼
系数

3×24×3.5

4

G=2μññ-1个一世Ĵ|X一世-XĴ|
μX

1

根据提供的方程式,添加到@smillig答案:

SELECT something AS x into #t FROM sometable
SELECT *,ROW_NUMBER() OVER(ORDER BY x) AS i INTO #tt FROM #t
SELECT 2.0*SUM(x*i)/(COUNT(x)*SUM(x))-1.0-(1.0/COUNT(x)) AS gini FROM #tt

给我测试集:

0.45503253636587840

与R的ineq库Gini(x)相同


;以t AS(SELECT CAST(收入AS浮动)AS x FROM#数据),tt AS(SELECT *,ROW_NUMBER()OVER(ORDER BY x)AS i FROM t)SELECT 2.0 * SUM(x * i)/( COUNT(x)* SUM(x))-1.0-(1.0 / COUNT(x))
Chris
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.