numpy實現PSI指標計算

計算方法
population stability index, 羣體穩定性指標,比較特徵的分佈在兩個樣本空間內的差異度,計算公式:

\(PSI = \sum\limits_{i=1}^{n} (A_i-E_i) * ln ( \frac{A_i} {E_i} )\)

參數 說明
\(A_i\) 分箱內真實(Actual)樣本個數佔比
\(E_i\) 分箱內期望(Except)樣本個數佔比, 在機器學習裏就是預測結果
\(n\) 分箱的個數

實現代碼

import numpy as np
def calc_psi(train_proba, test_proba, n_bins=10, eps=1e-6):
    def calc_ratio(y_proba):
        y_proba_1d = y_proba.reshape(1, -1)
        ratios = []
        for i, interval in enumerate(intervals):
            if i == len(interval) - 1:
                # include the probability==1
                n_samples = (y_proba_1d[np.where((y_proba_1d >= interval[0]) & (y_proba_1d <= interval[1]))]).shape[0]
            else:
                n_samples = (y_proba_1d[np.where((y_proba_1d >= interval[0]) & (y_proba_1d < interval[1]))]).shape[0]
            ratio = n_samples / y_proba.shape[0]
            if ratio == 0:
                ratios.append(eps)
            else:
                ratios.append(ratio)
        return np.array(ratios)

    distance = 1 / n_bins
    intervals = [(i * distance, (i+1) * distance) for i in range(n_bins)]
    train_ratio = calc_ratio(train_proba)
    test_ratio = calc_ratio(test_proba)
    return np.sum((train_ratio - test_ratio) * np.log(train_ratio / test_ratio))

測試

import numpy as np
np.random.seed(324)

probas = np.random.random(10000).reshape(-1, 1)
train_proba = probas[: 8000]
test_proba = probas[8000: ]
calc_psi(train_proba, test_proba)
# output
# 0.007639628811739914
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章