กำลังพยายามคำนวณดัชนี Gini จากการกระจายชื่อเสียงของ StackOverflow หรือไม่


11

ฉันพยายามคำนวณดัชนี Gini ในการกระจายชื่อเสียง SO โดยใช้ SO Data Explorer สมการที่ฉันพยายามนำมาใช้คือ: โดยที่: = จำนวนผู้ใช้บนไซต์; = หมายเลขประจำตัวผู้ใช้ (1 - 1,225,000); = ชื่อเสียงของผู้ใช้ฉันniyii

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 แต่มันก็ไม่สมเหตุสมผล: ฉันไม่แน่ใจว่ามันจะกลายเป็นลบได้อย่างไรและแม้กระทั่งในค่า abs ฉันก็คาดว่าความไม่เท่าเทียมกันจะใกล้เคียงกับ 1 มากเพียงใดเนื่องจากชื่อเสียง เติบโตยิ่งคุณมีมัน

ฉันไม่สนใจสมมติฐานบางประการเกี่ยวกับการเผยแพร่ชื่อเสียง / ผู้ใช้หรือไม่?

ฉันทำอะไรผิด


คุณพูดถูก แต่ฉันไม่แน่ใจว่าฉันเห็นว่าทำไมสิ่งนี้จึงมีผลต่อการคำนวณ
yossale

3
ฉันเดาว่าคำถามของคุณเกี่ยวกับธรรมชาติและการคำนวณของดัชนี Gini และไม่เกี่ยวกับวิธีการนำไปใช้ใน SQL (แก้ไขฉันหากฉันผิด) หากหลังเราควรย้ายข้อมูลนี้ไปยัง SO ต่อจากข้อสันนิษฐานของฉันฉันได้คัดลอกรหัสของคุณจากเว็บไซต์ข้อมูล SE แต่มันอาจช่วยถ้าคุณสามารถเขียนมันซ้ำในรหัสหลอกสำหรับผู้ที่อาจอ่าน SQL ไม่ดี
gung - Reinstate Monica

@ gung ขอบคุณ - ฉันถามเกี่ยวกับการคำนวณไม่ใช่การใช้ SQL ฉันจะเขียนมันในโค้ดหลอก
yossale

คำตอบ:


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รหัสได้ง่ายนัก แต่ถ้ามันช่วยได้ถ้าฉันจะคำนวณค่าสัมประสิทธิ์ Gini นี่คือสิ่งที่ฉันต้องทำ (เป็นภาษาอังกฤษธรรมดา)

  1. คิดออกของ (เช่นจำนวนคนที่มีตัวแทนบน SO)xnx
  2. จัดเรียงจากต่ำสุดไปสูงสุดx
  3. หาผลรวมแต่ละคูณด้วยลำดับในอันดับ (เช่นถ้ามี 10 คนตัวแทนสำหรับบุคคลที่มีตัวแทนต่ำสุดจะถูกคูณด้วย 1 และตัวแทนของบุคคลที่มีตัวแทนสูงสุดจะได้รับการคูณด้วย 10)x
  4. นำค่านั้นมาหารด้วยผลคูณของและผลรวมของ (เช่น. rep) แล้วคูณผลลัพธ์ด้วย 2x n × nxn×
  5. รับผลลัพธ์นั้นและลบค่าจากมัน1(1/n)
  6. Voila!

ฉันทำตามขั้นตอนเหล่านั้นจากรหัสตรงไปข้างหน้าอย่างน่าทึ่งในRฟังก์ชั่น (ในแพ็คเกจineq ) สำหรับการคำนวณค่าสัมประสิทธิ์ Gini สำหรับบันทึกรหัสต่อไปนี้คือ:

> 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

ซูเปอร์ ฉันสนใจที่จะรู้ว่ามูลค่าคืออะไรดังนั้นอาจแสดงความคิดเห็นเมื่อคุณทำการคำนวณ!
smillig

เมื่อฉันรวมค่า (เช่นถ้ามี 10 คนมีทั้ง 1,3 หรือ 5 คะแนนจากนั้นฉันมีเพียง 3 ระดับ: 1: 3,2: 5,3: 10) และคูณ (เท่าไหร่ ด้วยคะแนนนั้น) * คะแนน * (อันดับของคะแนน) ฉันได้ -0.98 ซึ่งคงจะสมเหตุสมผลถ้าไม่ใช่สำหรับเครื่องหมายผิด แต่ฉันไม่แน่ใจว่าทางลัดเล็ก ๆ ของฉันมีผลต่อระดับ
Gini อย่างไร

คุณไม่ต้องกำหนดคะแนนเฉลี่ยหรือไม่ เช่น 1: 3 ใช้สำหรับ 2: 5 ใช้เป็นต้น หรือคุณทำอย่างนั้น? 4 × 3.53×24×3.5
Björn

4

ฉันเชื่อว่ามีสี่สูตรเทียบเท่าของดัชนี Gini สำหรับฉันคนที่เป็นธรรมชาติที่สุดคือ U-statistic: ที่เป็นค่าเฉลี่ยของ 's คุณสามารถตรวจสอบการคำนวณของคุณอีกครั้งด้วยสูตรนี้ เห็นได้ชัดว่าผลลัพธ์จะต้องไม่เป็นลบ สำหรับสิ่งที่ฉันรู้เกี่ยวกับดัชนี Gini การกระจายชื่อเสียงใน CV ควรมีดัชนี Gini สูงกว่า 0.9 ไม่ว่า 0.98 จะสมเหตุสมผลหรือไม่ฉันไม่สามารถพูดได้μx

G=2μn(n1)ij|xixj|
μ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

ให้ฉันในชุดทดสอบของฉัน:

.45503253636587840

ซึ่งเหมือนกับไลบรารี ineq ของ R Gini (x)


; ด้วย t AS (SELECT CAST (รายรับลอย) ตาม x จาก #data), tt AS (SELECT *, ROW_NUMBER () มากกว่า (เรียงตาม x) ตามฉันจาก t) เลือก 2.0 * SUM (x * i) / ( COUNT (x) * SUM (x)) - 1.0- (1.0 / COUNT (x)) เป็น gini จาก tt
Chris
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.