天天看點

Gini coefficient直覺的解釋與實作

引言

大家在機器學習中經常會看到基尼系數的詞彙,有時候在做比賽的時候,有些賽題的Scoring Metric就是基尼系數。我們去Google或者Baidu,得到的都是些不甚滿意的經濟學相關的解釋。那麼在機器學習、資料挖掘領域,基尼系數在實際的應用場景中又該如何解釋以及如何實作呢?

基尼系數的經濟學解釋

首先,我們先看一張從Wiki上找來的經典圖檔:

Gini coefficient直覺的解釋與實作

基尼系數是一個分布不平衡程度的度量。它被定義成大小在0到1之間的比值:分子是均勻分布直線與洛倫茲曲線之間的面積,分母是均勻分布直線下方的面積。它是由意大利統計學家Corrado Gini提出并于1912年發表論文:”Variability and Mutability”。

基尼系數的計算

首先我們直接構造賽題結果:真實資料與預測資料

predictions = [, , , , , , , , , , , , , , ]
actual = [, , , , , , , , , , , , , , ]
           

參考Wiki上關于财富基尼系數計算公式的定義:

In some cases, this equation can be applied to calculate the Gini coefficient without direct reference to the Lorenz curve. For example, (taking y to mean the income or wealth of a person or household): For a population uniform on the values yi, i = 1 to n, indexed in non-decreasing order (yi ≤ yi+1):

G=1n(n+1−2∑ni=1(n+1−i)yi∑ni=1yi)(1)

上面的話我通俗翻譯下:在某些情況下,我們能夠不直接參考洛倫茲曲線來計算出基尼系數。比如,(假設y代表某人或某個家庭的财富值):序列 yi 是非遞減序列。那麼序列 yi 就代表着從窮人到富人的排列順序。是以基尼系數的公式就是:

G=1n(n+1−2∑ni=1(n+1−i)yi∑ni=1yi)(1)

那麼這個公式我在這裡将它拆分解釋下:

  • n代表y的個數
  • ∑ni=1yi 代表總财富值
  • ∑ni=1(n+1−i)yi 代表财富值的累計求和

1.資料轉換

在這裡我們并沒有窮人到富人的資料序列,我們可以将預測值從小到大排列。

# Sort the actual values by the predictions
data = zip(actual, predictions)
sorted_data = sorted(data, key=lambda d: d[])
sorted_actual = [d[] for d in sorted_data]
print('Sorted Actual Values', sorted_actual)
           

2.累計求和

在這裡我們對排序後的真實值累計求和:

# Sum up the actual values
cumulative_actual = np.cumsum(sorted_actual)
cumulative_index = np.arange(, len(cumulative_actual)+)

plt.plot(cumulative_index, cumulative_actual)
plt.xlabel('Cumulative Number of Predictions')
plt.ylabel('Cumulative Actual Values')
plt.show()
           
Gini coefficient直覺的解釋與實作

上圖顯示的折線就與我們從wiki上找來的圖檔中的洛倫茲曲線相對應。

3.Normalization

接下來我們将資料Normalization到0,1之間。并畫出45度線。

cumulative_actual_shares = cumulative_actual / sum(actual)
cumulative_index_shares = cumulative_index / len(predictions)

# Add (0, 0) to the plot
x_values = [] + list(cumulative_index_shares)
y_values = [] + list(cumulative_actual_shares)

# Display the 45° line stacked on top of the y values
diagonal = [x - y for (x, y) in zip(x_values, y_values)]

plt.stackplot(x_values, y_values, diagonal)
plt.xlabel('Cumulative Share of Predictions')
plt.ylabel('Cumulative Share of Actual Values')
plt.show()
           
Gini coefficient直覺的解釋與實作

4.計算橙色區域面積

我們使用線性代數庫scipy,求得橙色區域面積:

fy = scipy.interpolate.interp1d(x_values, y_values)
blue_area, _ = scipy.integrate.quad(fy, , , points=x_values)
orange_area =  - blue_area
print('Orange Area: %.3f' % orange_area)
           
[out] Orange Area: 
           

5.最大可能的基尼系數

前面我們是按照預測值對真實值排序,得到一個基尼系數;現在我們按照真實值給真實值排序,得到最大可能的基尼系數:

cumulative_actual_shares_perfect = np.cumsum(sorted(actual)) / sum(actual)
y_values_perfect = [] + list(cumulative_actual_shares_perfect)

# Display the 45° line stacked on top of the y values
diagonal = [x - y for (x, y) in zip(x_values, y_values_perfect)]

plt.stackplot(x_values, y_values_perfect, diagonal)
plt.xlabel('Cumulative Share of Predictions')
plt.ylabel('Cumulative Share of Actual Values')
plt.show()

# Integrate the the curve function
fy = scipy.interpolate.interp1d(x_values, y_values_perfect)
blue_area, _ = scipy.integrate.quad(fy, , , points=x_values)
orange_area =  - blue_area
print('Orange Area: %.3f' % orange_area)
           
Gini coefficient直覺的解釋與實作
[out] Orange Area: 
           

資料挖掘中的Scoring Metric的實作

在這裡我們封裝好基尼系數的函數,可用來作為比賽中的打分函數。

def gini(actual, pred):
    assert (len(actual) == len(pred))
    all = np.asarray(np.c_[actual, pred, np.arange(len(actual))], dtype=np.float)
    all = all[np.lexsort((all[:, ], - * all[:, ]))]
    totalLosses = all[:, ].sum()
    giniSum = all[:, ].cumsum().sum() / totalLosses

    giniSum -= (len(actual) + ) / 
    return giniSum / len(actual)


def gini_normalized(actual, pred):
    return gini(actual, pred) / gini(actual, actual)


gini_predictions = gini(actual, predictions)
gini_max = gini(actual, actual)
ngini= gini_normalized(actual, predictions)
print('Gini: %.3f, Max. Gini: %.3f, Normalized Gini: %.3f' % (gini_predictions, gini_max, ngini))
           
[out] Gini: , Max. Gini: , Normalized Gini: 
           

總結

關于Gini系數的pdf文章,請戳:傳送門

繼續閱讀