Mencoba menghitung indeks Gini di distribusi reputasi StackOverflow?

11

Saya mencoba menghitung indeks Gini pada distribusi reputasi SO menggunakan SO Data Explorer. Persamaan yang saya coba terapkan adalah ini: Di mana: = jumlah pengguna di situs; = nomor seri pengguna (1 - 1.225.000); = reputasi pengguna .niyii

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

Inilah cara saya mengimplementasikannya (disalin dari sini ):

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

Hasil saya (saat ini) -0,53, tetapi tidak masuk akal: Saya tidak yakin bagaimana itu bisa menjadi negatif, dan bahkan dalam nilai abs, saya akan mengharapkan ketidaksetaraan lebih dekat ke 1, mengingat bagaimana reputasi tumbuh semakin Anda memilikinya.

Apakah saya tanpa sadar mengabaikan beberapa asumsi tentang distribusi reputasi / pengguna?

Apa yang saya lakukan salah?

Yossale
sumber
Anda benar, tetapi saya tidak yakin saya mengerti mengapa ini harus memengaruhi perhitungan?
Yossale
3
Saya menduga bahwa pertanyaan Anda adalah tentang sifat & perhitungan indeks Gini, & bukan tentang bagaimana mengimplementasikannya dalam SQL (koreksi saya jika saya salah). Jika yang terakhir, kita harus memigrasi ini ke SO. Melanjutkan asumsi saya, saya telah menyalin kode Anda dari situs data SE, tetapi mungkin membantu jika Anda juga dapat menulis ulang dalam pseudo-code bagi mereka yang mungkin tidak membaca SQL dengan baik.
gung - Reinstate Monica
@ung terima kasih - Saya bertanya tentang perhitungan, bukan implementasi SQL. Saya akan menulisnya kembali dalam kode pseudo
yossale

Jawaban:

1

Berikut ini cara menghitungnya dengan 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

Penjelasan di sini https://medium.com/@medvedev1088/calculating-gini-coefisien-in-bigquery-3bc162c82168

medvedev1088
sumber
12

Saya tidak dapat membaca SQLkode dengan sangat mudah, tetapi jika ini membantu, jika saya akan menghitung koefisien Gini, inilah yang akan saya lakukan (dalam bahasa Inggris).

  1. Cari tahu dari (mis. Jumlah orang dengan perwakilan pada SO)xnx
  2. Sortir dari terendah ke tertinggix
  3. Jumlah setiap dikalikan dengan urutannya di peringkat (mis. Jika ada 10 orang, perwakilan untuk orang dengan perwakilan terendah dikalikan 1 dan perwakilan orang dengan perwakilan tertinggi dikalikan 10)x
  4. Ambil nilai itu dan bagilah dengan produk dan jumlah (mis. rep) dan kemudian gandakan hasilnya dengan 2x n × Σnxn×
  5. Ambil hasil itu dan kurangi nilai darinya.1(1/n)
  6. Voila!

Saya mengambil langkah-langkah tersebut dari kode yang sangat lurus ke depan dalam Rfungsi (dalam paket inqq ) untuk menghitung koefisien Gini. Sebagai catatan, ini kode itu:

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

Tampaknya agak mirip dengan SQLkode Anda , tetapi seperti yang saya katakan, saya tidak bisa benar-benar membacanya dengan mudah!

smillig
sumber
Terima kasih Anda sangat banyak! Saya melewatkan bagian penyortiran! itu menjelaskan banyak ...
yossale
Super. Saya tertarik mengetahui nilainya, jadi mungkin beri komentar ketika Anda sudah membuat perhitungan!
smillig
Nah, ketika saya mengumpulkan nilai-nilai (yaitu jika ada 10 orang, dengan 1,3, atau 5 poin, maka saya hanya memiliki 3 peringkat: 1: 3,2: 5,3: 10) dan mengalikannya (berapa banyak dengan skor itu) * skor * (peringkat skor) saya dapatkan -0,98, yang akan masuk akal jika bukan karena tanda yang salah. Tapi saya tidak yakin bagaimana cara pintas kecil saya mempengaruhi skala gini
yossale
Apakah Anda tidak harus menetapkan skor rata-rata? Yaitu untuk 1: 3 berlaku , untuk 2: 5 berlaku dll? Atau apakah kamu melakukan itu? 4 × 3.53×24×3.5
Bjorn
4

Saya percaya, ada empat formulasi setara dari indeks Gini. Bagi saya, yang paling alami adalah statistik-U: di mana adalah rata-rata . Anda dapat memeriksa ulang perhitungan Anda dengan rumus ini. Jelas, hasilnya pasti tidak negatif. Untuk apa yang saya ketahui tentang indeks Gini, distribusi reputasi di CV harus memiliki indeks Gini di atas 0,9; apakah 0.98 masuk akal atau tidak, saya tidak bisa mengatakannya.μx

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

Menambah jawaban @smillig, berdasarkan persamaan yang disediakan:

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

Memberi saya pada set tes saya:

0.45503253636587840

Yang sama dengan perpustakaan R's ineq Gini (x)

Chris
sumber
; DENGAN t AS (SELECT CAST (penghasilan AS FLOAT) AS x DARI # data), tt AS (PILIH *, ROW_NUMBER () LEBIH (ORDER DENGAN x) SEBAGAI DARI) t SELECT 2.0 * SUM (x * i) / ( COUNT (x) * SUM (x)) - 1.0- (1.0 / COUNT (x)) SEBAGAI gini DARI tt
Chris