Pythonを使用してKSを計算する詳細な例

金融分野では、y値と予測されるデフォルト確率は、分布が不明な2つの分布にすぎません。優れた信用リスク管理モデルは、一般に、精度、安定性、および解釈可能性の観点からモデルを評価します。

一般的に言えば。善人のサンプルの分布は、悪人のサンプルの分布とは大きく異なるはずです。KSは、有効性指標の識別能力指標です。** KSは、モデルのリスク識別能力を評価するために使用され、KS指標は、良いサンプルと悪いサンプルの蓄積を測定します。分布の違い。 ****

良いサンプルと悪いサンプルの累積差が大きく、KSインデックスが大きいほど、モデルがリスクを区別する能力が高くなります。

1、 ksの計算の中核となるクロス集計の実装は、善人と悪人の累積確率分布です。pandas.crosstab関数を使用して、累積確率分布を計算します。

2、 roc_curveの実装では、sklearnライブラリのroc_curve関数がrocとaucを計算するときに、計算プロセス中に善人と悪人の累積確率分布が取得され、sklearn.metrics.roc_curveを使用してks値を計算します。

3、 ks_2sampの実装では、stats.ks_2samp()関数を呼び出して計算します。 scipy.stats.ks_2samp¶をリンクしてks_2samp()のソースコードを実装します。詳細なプロセスはここに実装されています

4、 stats.ks_2samp()を直接呼び出して、ksを計算します

import pandas as pd 
import numpy as np
from sklearn.metrics import roc_curve
from scipy.stats import ks_2samp
def ks_calc_cross(data,pred,y_label):'''
特徴:KS値を計算し、対応する分割点と累積分布関数曲線グラフを出力します
入力値:
data:モデルスコアと実際のラベルを含む2次元配列またはデータフレーム
pred:モデルスコア(通常はポジティブクラスを予測する確率)を表す1次元の配列またはシリーズ
y_label:実際のラベルを表す1次元の配列またはシリーズ({0,1}または{-1,1})
出力値:'ks':KS値、'crossdens':良い顧客と悪い顧客の累積確率分布とそれらの差のギャップ
'''
crossfreq = pd.crosstab(data[pred[0]],data[y_label[0]])
crossdens = crossfreq.cumsum(axis=0)/ crossfreq.sum()
crossdens['gap']=abs(crossdens[0]- crossdens[1])
ks = crossdens[crossdens['gap']== crossdens['gap'].max()]return ks,crossdens
def ks_calc_auc(data,pred,y_label):'''
特徴:KS値を計算し、対応する分割点と累積分布関数曲線グラフを出力します
入力値:
data:モデルスコアと実際のラベルを含む2次元配列またはデータフレーム
pred:モデルスコア(通常はポジティブクラスを予測する確率)を表す1次元の配列またはシリーズ
y_label:実際のラベルを表す1次元の配列またはシリーズ({0,1}または{-1,1})
出力値:'ks':KS値
'''
fpr,tpr,thresholds=roc_curve(data[y_label[0]],data[pred[0]])
ks =max(tpr-fpr)return ks
def ks_calc_2samp(data,pred,y_label):'''
特徴:KS値を計算し、対応する分割点と累積分布関数曲線グラフを出力します
入力値:
data:モデルスコアと実際のラベルを含む2次元配列またはデータフレーム
pred:モデルスコア(通常はポジティブクラスを予測する確率)を表す1次元の配列またはシリーズ
y_label:実際のラベルを表す1次元の配列またはシリーズ({0,1}または{-1,1})
出力値:'ks':KS値、'cdf_df':良い顧客と悪い顧客の累積確率分布とそれらの差のギャップ
'''
Bad = data.loc[data[y_label[0]]==1,pred[0]]
Good = data.loc[data[y_label[0]]==0, pred[0]]
data1 = Bad.values
data2 = Good.values
n1 = data1.shape[0]
n2 = data2.shape[0]
data1 = np.sort(data1)
data2 = np.sort(data2)
data_all = np.concatenate([data1,data2])
cdf1 = np.searchsorted(data1,data_all,side='right')/(1.0*n1)
cdf2 =(np.searchsorted(data2,data_all,side='right'))/(1.0*n2)
ks = np.max(np.absolute(cdf1-cdf2))
cdf1_df = pd.DataFrame(cdf1)
cdf2_df = pd.DataFrame(cdf2)
cdf_df = pd.concat([cdf1_df,cdf2_df],axis =1)
cdf_df.columns =['cdf_Bad','cdf_Good']
cdf_df['gap']= cdf_df['cdf_Bad']-cdf_df['cdf_Good']return ks,cdf_df
data ={'y_label':[1,1,1,1,1,1,0,0,0,0,0,0],'pred':[0.5,0.6,0.7,0.6,0.6,0.8,0.4,0.2,0.1,0.4,0.3,0.9]}
data = pd.DataFrame(data)
ks1,crossdens=ks_calc_cross(data,['pred'],['y_label'])
ks2=ks_calc_auc(data,['pred'],['y_label'])
ks3=ks_calc_2samp(data,['pred'],['y_label'])
get_ks = lambda y_pred,y_true:ks_2samp(y_pred[y_true==1], y_pred[y_true!=1]).statistic
ks4=get_ks(data['pred'],data['y_label'])print('KS1:',ks1['gap'].values)print('KS2:',ks2)print('KS3:',ks3[0])print('KS4:',ks4)

出力結果:

KS1:[0.83333333]
KS2:0.833333333333
KS3:0.833333333333
KS4:0.833333333333

データにNANデータがある場合、注意が必要な問題がいくつかあります。

たとえば、元のデータにy_label = 0、pred = np.nanを追加しました。

data = {‘y_label’:[1,1,1,1,1,1,0,0,0,0,0,0,0],
‘pred’:[0.5,0.6,0.7,0.6,0.6,0.8,0.4,0.2,0.1,0.4,0.3,0.9,np.nan]}

この時点で実行します

ks1,crossdens=ks_calc_cross(data,[‘pred’], [‘y_label’])

出力結果

KS1: [ 0.83333333]

実施した

ks2=ks_calc_auc(data,[‘pred’], [‘y_label’])

次のエラーが報告されます

ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64’).

実施した

ks3=ks_calc_2samp(data,[‘pred’], [‘y_label’])

出力結果

KS3: 0.714285714286

実施した

ks4=get_ks(data[‘pred’],data[‘y_label’])

出力結果

KS4: 0.714285714286

上記の結果からわかる

3つの方法で計算されたks値はすべて異なります。

ks_calc_crossの計算では、NANは無視され、正しいデータの確率分布が計算されます。計算されたksは、手動で計算されたksと同じです。

ks_calc_auc関数の組み込み関数はNAN値を処理できないため、エラーを直接報告します。したがって、ks値を計算するためにks_calc_aucが必要な場合は、事前にNAN値を削除する必要があります。

ks_calc_2sampによって計算されたksはsearchsorted()関数によるものです(興味のある学生は自分でデータをシミュレートしてこの関数を見ることができます)。Nan値はデフォルトで最大にソートされ、データの元の累積分布確率が変更され、計算されたksになります。実際のksにエラーがあります。

総括する

実際の状況では、通常、デフォルトの確率のks値を計算しますが、現時点ではNAN値はありません。したがって、上記の3つの方法でks値を計算できます。ただし、単一の変数のks値を計算する場合、データ品質が良くなく、NAN値がある場合は、ks_calc_aucとks_calc_2sampを引き続き使用すると問題が発生します。

2つの解決策があります

  1. 事前にデータのNAN値を削除してください

  2. ks_calc_crossを使用して直接計算します。

Pythonを使用してKSを計算する上記の詳細な例は、エディターによって共有されるすべてのコンテンツです。参照を提供したいと思います。

Recommended Posts

Pythonを使用してKSを計算する詳細な例
PythonWebページパーサーの使用例の詳細な説明
Python |再帰を使用して解決する関数
pythonバックトラッキングテンプレートの詳細な説明
Pythonイールドの使用例の分析
Pythonプラグインメカニズムの詳細な実装
pythonシーケンスタイプの詳細な説明
gpg2を使用したubuntuの詳細な説明
Pythonを使用して複数のクリップボードを実装する
Pythonでの辞書の詳細な使用法
IV値を計算するPythonの例
Centos6ネットワーク構成の詳細な例
pythonのインストールが成功したことを確認する方法
npy形式のデータ例へのPythonアクセス
PythonIOポート多重化の詳細な説明
Pythonガベージコレクションメカニズムの詳細な分析
ヘビを実現するための200行のPythonコード
属性からプロパティまでのPython詳細な説明
不可欠な例を見つけるためのPythonRombergメソッド
reprを使用してpythonプログラムをデバッグする方法
Python推測アルゴリズムの問題の詳細な説明
Python super()メソッドの原理の詳細な説明
python標準ライブラリOSモジュールの詳細な説明
詳細なチュートリアルを構築するためのPython3開発環境
Pythondecimalモジュールの使用法の詳細な説明
航空機戦争を達成するための500行のPythonコード
pythonがコンカレントメソッドをサポートする方法の詳細な説明
ファイルをダウンロードするためのPythonヘッドレスクローラーの実装
Pythonに基づくデータタイプの詳細な説明
FMEに基づくPythonプロセスの使用図
Python3.9の7つの機能
01.Pythonの概要
100の小さなPythonの例
Pythonの紹介
Python関数パラメータ分類の原理の詳細な説明
Pythonタイマースレッドプールの原理の詳細な説明
Pythonインターフェース開発の実装手順の詳細な説明
Pythonプロセス制御の一般的なツールの詳細な説明
Pythonでのパッケージの導入を理解する方法
pythonで番号のリストを理解する方法
Pythonオブジェクトの属性アクセスプロセスの詳細な説明
pythonに基づく残りの問題の詳細な説明(%)
pythonで写真を自動的にダウンロードする方法の例
Pythonを使用して広州の不動産市場を分析する
プレイカードの配布を実現するためのPythonシミュレーション