基尼係數計算:sql (hive)實現
阿新 • • 發佈:2018-12-12
通過近似的方法,如何在sql中計算基尼係數。
-------------------------------------------------------------------------------------------------
如何在python中實現基尼係數計算的兩種方法,可以檢視我的另一篇文章。
-------------------------------------------------------------------------------------------------
本文中採用的近似方法,如何建立近似計算公式、如何簡化推導公式可檢視文章:
-------------------------------------------------------------------------------------------------
近似的精確度取決於分組數量。如果樣本數量為100個,如果分組數量為100,近似的方法取得的結果跟實際值相等。
但隨著分組數量的減少,精確度也減少。
本文是在hive中實現,需要使用到hive中的over函式。
包括如何使用over函式進行分組、計算每組的總和以及取得累計加和等等。
select * from gini; -- gini為table名稱。 -- gini中的100個數據如下,欄位名為wealth。 /* 346, 559, 198, 420, 39, 709, 225 , 731, 708, 369, 519, 46, 48, 446 , 117, 127, 905, 652, 528, 832, 217 , 536, 942, 608, 37, 802, 422, 884 , 746, 959, 759, 397, 245, 83, 542 , 907, 128, 933, 740, 506, 458, 830 , 874, 570, 914, 592, 585, 574, 636 , 462, 86, 321, 174, 238, 670, 690 , 456, 918, 70, 801, 695, 908, 57, 497 , 605, 334, 265, 255, 235, 199, 739, 81 , 131, 68, 229, 602, 390, 571, 733, 440 , 528, 409, 222, 55, 876, 606, 906, 549 , 487, 552, 796, 454, 301, 914, 635, 304, 503, 688, 631, 705 */ -- 計算基尼係數時候先進行cumsum或者是先進行分組都可以。 -- 這裡由於over函式計算cumsum的特殊性,先進行分組。 -- 這裡顯示的是分成9組 -- 9出現在兩個地方:第二行,最後的計算公式中,還有就是出現在ntile之後,分成9組的時候。 -- 第二行中:計算最後的結果時候,跟推匯出來的公式有所補桶。外面的sum之前多做了一個處理,減掉了1。 -- 這是因為最後一個樣本資料的cumsum是佔全部的樣本的總和的100%,這個資料需要去掉。 -- cum_sum_1和cum_sum_2的結果是相同的,目前簡單的資料上如此,複雜之後可能不是,需要確認。 -- 在樣本數量不能被分組數量整除的時候,ntile的處理,可以搜尋一下hive是怎麼做的。 select (1 - (1/9) * (2*(sum(cum_sum_1)/sum(bar_sum) - 1) + 1)) from ( select bar , sum(wealth) as bar_sum -- 即使bar_sum最後不需要用,也不能省略,下面的cum_sum的生成需要它,不然會報錯。 -- , sum(sum(wealth)) over (order by bar rows between unbounded preceding and current row) as cum_sum_2 , sum(sum(wealth)) over(order by bar) as cum_sum_1 from ( select wealth , ntile(9) over (order by wealth) as bar -- 分成9組 from gini ) a group by bar order by bar limit 1000 ) b ; -- 一些結果 100組 0.310964174 -- 這個跟使用相同資料,在python上精確的求曲線下方面積的結果是相等的。 -- 可見我的另一片使用pyhton計算基尼係數的文章。 20組 0.31025484587225693 9組 0.300356286353766