Vous essayez de calculer l'index Gini sur la distribution de réputation StackOverflow?


11

J'essaie de calculer l'index Gini sur la distribution de réputation SO à l'aide de SO Data Explorer. L'équation que j'essaie de mettre en œuvre est la suivante: Où:n= nombre d'utilisateurs sur le site; i= identifiant de série de l'utilisateur (1 - 1 225 000); yi= réputation de l'utilisateuri.

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

Voici comment je l'ai implémenté (copié d' ici ):

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

Mon résultat est (actuellement) -0,53, mais cela n'a aucun sens: je ne sais même pas comment il aurait pu devenir négatif, et même en valeur abs, je m'attendais à ce que l'inégalité soit beaucoup plus proche de 1, étant donné la réputation grandit plus vous en avez.

Suis-je inconsciemment en train d'ignorer certaines hypothèses sur la distribution de la réputation / des utilisateurs?

Qu'est-ce que je fais mal?


Vous avez raison, mais je ne suis pas sûr de voir pourquoi cela devrait affecter le calcul?
yossale

3
Je suppose que votre question porte sur la nature et le calcul de l'index Gini, et non sur la façon de l'implémenter en SQL (corrigez-moi si je me trompe). Dans ce dernier cas, nous devons migrer vers SO. En continuant avec mon hypothèse, j'ai copié votre code à partir du site de données SE, mais cela pourrait aider si vous pouvez également le réécrire en pseudo-code pour ceux qui ne lisent pas bien SQL.
gung - Réintégrer Monica

@gung thanks - Je pose des questions sur le calcul, pas sur l'implémentation SQL. Je le
réécrirai

Réponses:


1

Voici comment vous pouvez le calculer avec 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

L'explication est ici https://medium.com/@medvedev1088/calculating-gini-coefficient-in-bigquery-3bc162c82168


12

Je ne peux pas lire le SQLcode très facilement, mais si cela aide, si je devais calculer le coefficient de Gini, c'est ce que je ferais (en anglais simple).

  1. nx
  2. x
  3. x
  4. nxn×
  5. 1(1/n)
  6. Voila!

J'ai pris ces mesures à partir du code remarquablement simple de la Rfonction (dans le package ineq ) pour calculer le coefficient de Gini. Pour mémoire, voici ce 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>

Il ressemble un peu à votre SQLcode, mais comme je l'ai dit, je ne peux pas vraiment le lire très facilement!


Merci vous très bien! J'ai raté la partie tri! cela explique beaucoup de choses ...
yossale

Super. Je suis intéressé à savoir quelle est la valeur, alors laissez peut-être un commentaire lorsque vous aurez fait le calcul!
smillig

Eh bien, quand j'ai agrégé les valeurs (c'est-à-dire s'il y a 10 personnes, avec 1,3 ou 5 points, alors je n'ai que 3 classements: 1: 3,2: 5,3: 10) et multiplié le (combien avec ce score) * score * (rang de score) J'ai obtenu -0,98, ce qui aurait été logique sans le mauvais signe. Mais je ne sais pas comment mon petit raccourci
affecte l'

3×24×3.5

4

G=2μn(n1)ij|xixj|
μx

1

Ajout à la réponse @smillig, basé sur l'équation fournie:

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

M'a donné sur mon set de test:

0,45503253636587840

Ce qui est le même que les bibliothèques ineq de R Gini (x)


; AVEC t AS (SELECT CAST (revenu 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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.