StackOverflow itibar dağıtımında Gini dizinini hesaplamaya mı çalışıyorsunuz?


11

SO Data Explorer kullanarak SO itibar dağıtım Gini dizini hesaplamak çalışıyorum. Uygulamaya çalıştığım denklem şudur: Burada: = sitedeki kullanıcı sayısı; = kullanıcı seri kimliği (1 - 1,225,000); = kullanıcısının itibarı .niyii

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

Ben bu şekilde ( buradan kopyalanan ) uyguladım :

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

Benim sonucum (şu anda) -0.53, ama mantıklı değil: Nasıl olumsuz olabileceğinden bile emin değilim ve abs değerinde bile, itibarın nasıl olduğu göz önüne alındığında eşitsizliğin 1'e çok daha yakın olmasını beklerdim. ne kadar çok büyürse.

Ünün / kullanıcıların dağılımı ile ilgili bazı varsayımları bilmeden yok sayıyor muyum?

Neyi yanlış yapıyorum?


Haklısın, ama bunun neden hesaplamayı etkilemesi gerektiğinden emin değilim?
yossale

3
Sorunuzun Gini endeksinin doğası ve hesaplanması hakkında olduğunu ve SQL'de nasıl uygulanacağını değil (yanlışsam beni düzelt) hakkında olduğunu tahmin ediyorum. İkincisi, bunu SO'ya taşımalıyız. Varsayımımla devam edersek, kodunuzu SE veri sitesinden kopyaladım, ancak SQL'i iyi okuyamayanlar için sözde kodda yeniden yazabiliyorsanız yardımcı olabilir.
gung - Monica'yı eski durumuna döndürün

@gung thanks - SQL uygulaması değil, hesaplama hakkında soruyorum. Ben sözde kodla yeniden yazacağım
yossale

Yanıtlar:


1

SQL ile nasıl hesaplayabileceğiniz aşağıda açıklanmıştır:

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

Açıklama burada https://medium.com/@medvedev1088/calculating-gini-coefficient-in-bigquery-3bc162c82168


12

SQLKodu çok kolay okuyamıyorum , ancak yardımcı olursa, Gini katsayısını hesaplayacak olsaydım, bunu yapardım (düz İngilizce).

  1. Üzerinden Şekil ve x (yani. Böylece temsilcisi olan kişi sayısı)nx
  2. Sıralama en düşükten en yükseğe kadarx
  3. x
  4. nxn×
  5. 1(1/n)
  6. İşte bu kadar!

Bu adımları Gini katsayısını hesaplamak için Rfonksiyondaki ( ineq paketindeki) oldukça basit koddan aldım . Kayıt için şu kod:

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

Kodunuza biraz benziyor SQL, ama dediğim gibi, bunu gerçekten çok kolay okuyamıyorum!


Teşekkür size çok fazla! Sıralama bölümünü kaçırdım! bu çok açıklıyor ...
yossale

Süper. Değerin ne olduğunu bilmekle ilgileniyorum, belki de hesaplama yaparken bir yorum bırakın!
smillig

Değerleri topladığımda (yani 1,3 veya 5 puanlı 10 kişi varsa, o zaman sadece 3 derecem var: 1: 3,2: 5,3: 10) ve * puan * (puan sırası) -0,98 aldım, bu yanlış işaret olmasaydı mantıklı olurdu. Ama küçük kısayolumun gini ölçeğini nasıl etkilediğinden emin değilim
yossale

3×24×3.5

4

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

1

Sağlanan denklemi temel alarak @smillig cevabına ekleme:

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

Beni test setimde verdi:

,45503253636587840

Hangi R ineq kütüphaneleri Gini (x) ile aynı


; AS OLARAK (DÖNEM SEÇ (FLOAT OLARAK gelir) AS # verilerden x), tt AS (SEÇ *, ROW_NUMBER () AŞIRI (SİPARİŞ İLE x) t i TARAFINDAN SEÇİN) 2.0 * TOPLA (x * i) / ( COUNT (x) * TOPLA (x)) - 1.0- (1.0 / COUNT (x)) AS gini Tt
Chris
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.