Versuchen Sie, den Gini-Index für die StackOverflow-Reputationsverteilung zu berechnen?

11

Ich versuche, den Gini-Index für die SO-Reputationsverteilung mit SO Data Explorer zu berechnen. Die Gleichung, die ich zu implementieren versuche, lautet: Wobei:n= Anzahl der Benutzer auf der Site; i= Benutzer-Seriennummer (1 - 1.225.000); yi= Ruf des Benutzersi.

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

So habe ich es implementiert (von hier kopiert ):

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

Mein Ergebnis ist (derzeit) -0,53, aber es macht keinen Sinn: Ich bin mir nicht sicher, wie es negativ geworden sein könnte, und selbst im abs-Wert hätte ich erwartet, dass die Ungleichung angesichts des guten Rufs viel näher bei 1 liegt wächst, je mehr du es hast.

Ignoriere ich unwissentlich eine Annahme über die Verteilung des Rufs / der Benutzer?

Was mache ich falsch?

Yossale
quelle
Sie haben Recht, aber ich bin mir nicht sicher, warum dies die Berechnung beeinflussen sollte.
Yossale
3
Ich vermute, dass Ihre Frage die Art und Berechnung des Gini-Index betrifft und nicht die Implementierung in SQL (korrigieren Sie mich, wenn ich falsch liege). In letzterem Fall sollten wir dies auf SO migrieren. Ich gehe davon aus, dass ich Ihren Code von der SE-Datenseite kopiert habe, aber es könnte hilfreich sein, wenn Sie ihn auch in Pseudocode für diejenigen umschreiben können, die SQL möglicherweise nicht gut lesen.
Gung - Reinstate Monica
@gung danke - ich frage nach der Berechnung, nicht nach der SQL-Implementierung. Ich werde es in Pseudocode neu schreiben
Yossale

Antworten:

1

So können Sie es mit SQL berechnen:

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

Erläuterungen finden Sie hier https://medium.com/@medvedev1088/calculating-gini-coefficient-in-bigquery-3bc162c82168

medvedev1088
quelle
12

Ich kann den SQLCode nicht leicht lesen , aber wenn es hilft, wenn ich den Gini-Koeffizienten berechnen würde, würde ich dies tun (in einfachem Englisch).

  1. Finden Sie das von x heraus (dh die Anzahl der Personen mit rep auf SO)nx
  2. Sortiere vom niedrigsten zum höchstenx
  3. x
  4. nxn×
  5. 1(1/n)
  6. Voila!

Ich habe diese Schritte aus dem bemerkenswert einfachen Code in der RFunktion (im ineq- Paket) zur Berechnung des Gini-Koeffizienten gemacht. Für die Aufzeichnung ist hier dieser Code:

> 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>

Es sieht Ihrem SQLCode etwas ähnlich , aber wie gesagt, ich kann das nicht so einfach lesen!

smillig
quelle
Dank Sie sehr viel! Ich habe den Sortierteil verpasst! das erklärt viel ...
yossale
Super. Ich bin daran interessiert zu wissen, was der Wert ist, also hinterlasse vielleicht einen Kommentar, wenn du die Berechnung gemacht hast!
Smillig
Nun, wenn ich die Werte aggregiert habe (dh wenn es 10 Personen mit 1,3 oder 5 Punkten gibt, dann habe ich nur 3 Ränge: 1: 3,2: 5,3: 10) und die (wie viele) multipliziert habe mit dieser Punktzahl) * Punktzahl * (Rang der Punktzahl) Ich habe -0,98 erhalten, was ohne das falsche Vorzeichen Sinn gemacht hätte. Aber ich bin nicht sicher, wie meine kleine Abkürzung die Gini-Skala beeinflusst
Yossale
3×24×3.5
4

G=2μn(n- -1)ichj|xich- -xj|
μx
StasK
quelle
1

Hinzufügen zu @smillig Antwort, basierend auf der angegebenen Gleichung:

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

Gab mir auf meinem Test-Set:

0,45503253636587840

Welches ist das gleiche wie Rs ineq Bibliotheken Gini (x)

Chris
quelle
; MIT t AS (SELECT CAST (Einkommen AS FLOAT) AS x FROM #data), 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)) AS gini FROM tt
Chris