3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SPSS Modelerのバランス・ノードをPythonで書き換える。アンバランスデータの修正

Last updated at Posted at 2021-07-16

SPSS Modelerで目的変数のレコード数に不均衡がある場合にそのバランスをそろえるのがバランス・ノードです。
このバランス・ノードを解説するとともに、Pythonのpandasで書き換えてみます。

#0.元データ

ここではローン審査での、顧客の属性と判定したリスクの入ったデータを使います。Riskが1の場合はリスクの高い顧客、0はリスクの低い顧客を示しています。

CustID:顧客番号
Age:年齢
Car_loans:車のローンランク
Credit_cards:クレジットカード利用ランク
Education:教育ランク
Income:収入ランク
Risk:リスクありなし

500件あります。
image.png

Riskの1と0のレコード件数を比較するとRisk=1のレコードは全体の25%、Risk=0のレコードは75%で、アンバランスになっていることがわかります。

image.png

通常こういうデータでRisk予測モデルを作る場合は、Riskがある人を予測したいのですが、仮にすべてをRiskなしと予測しても75%の精度で予測ができ、Riskなしと予想しがちなモデルができてしまいます。

これを避けるために、Riskありとなしのレコードのバランスをとるのがバランス・ノードです。

#1m.①アンダーサンプリング Modeler版
バランス・ノードは単体で使うこともできますが、棒グラフノードから作るのが一般的です。

まずRiskで棒グラフを作成します。
image.png

グラフができたら、生成メニューから「バランスノード(減少)」を選びます。
image.png

そうするとバランスノードがキャンバスに追加されます。
image.png

中身を見るとRisk=1の時には1倍なのでそのまま、Risk=0の時には約0.3倍のレコード数にするというバランス比率が定義されます。
image.png

このサンプリングノードを接続したうえで、改めて棒グラフノードで結果を確認すると、Risk=0のデータが約1/3になって、ほぼ同数のレコード数になりました。
image.png

注意点はランダムシードが設定できないので、毎回結果が変わってしまうことです。ですので、キャッシュしてキャッシュデータを保存しておくか、エクスポートノードでファイルやDBのテーブルに出力しておくことをお勧めします。

image.png

#1p.①アンダーサンプリング pandas版

pandasでアンバランスデータの修正を行う場合はimblearnを使います。pipやcondaを使って導入しておきます。

#pip
pip install imbalanced-learn
#conda
conda install -c conda-forge imbalanced-learn

imblearnを使うためには、以下のように説明変数のデータフレームと目的変数のデータフレームに分割しておく必要があります。

df_x=df.drop(['Risk'],axis=1)
df_y=df[['Risk']]

件数とその棒グラフを表示してみます。

df_risk=df_y.groupby('Risk').size()
print(df_risk)
df_risk.plot.bar()

image.png

では、このデータをアンダーサンプリングしてみます。

RandomUnderSamplerをImportし、random_stateでランダムシードを指定してインスタンス化します。
その上で説明変数のデータフレームと目的変数のデータフレームを引数にfit_resampleを実行するとアンダーサンプリングされた説明変数のデータフレームと目的変数のデータフレームが戻ります。

from imblearn.under_sampling import RandomUnderSampler
sampler = RandomUnderSampler(random_state=1)
x_resampled, y_resampled = sampler.fit_resample(df_x,df_y)

件数とその棒グラフを表示してみます。どちらも600件と同数になっているのがわかります。

df_risk=df_y.groupby('Risk').size()
print(df_risk)
df_risk.plot.bar()

image.png

#2m.②オーバーサンプリング Modeler版
先ほどはRiskありの600件に合わせてRiskなしのレコードを減らすアンダーサンプリングをしましたが、Riskありのレコード件数を増やすオーバーサンプリングも可能です。

棒グラフの生成メニューから「バランスノード(増加)」を選びます。
image.png

中身を見るとRisk=0の時には1倍なのでそのまま、Risk=1の時には約3倍のレコード数にするというバランス比率が定義されます。
image.png

棒グラフで結果を見ると以下のようにRisk=1のレコードが3倍に増えて、同数程度になっていることがわかります。
image.png

データをみるとRisk=1のレコードが約3倍に重複していることがわかります。
image.png

#2p.②オーバーサンプリング pandas版
pandasでオーバーサンプリングする場合はRandomOverSamplerを使います。使い方はRandomUnderSamplerと同じです。

from imblearn.over_sampling  import RandomOverSampler
sampler = RandomOverSampler(random_state=1)
x_resampled, y_resampled = sampler.fit_resample(df_x,df_y)

Risk=1が増えて同数になったことがわかります。
image.png

#3. 補足

オーバーサンプリングにはSMOTEという方法もあります。SMOTEは単にデータをコピーするのではなく、似たデータを生成します。

【リレー連載】わたしの推しノード –機械学習時代の申し子「SMOTEノード」が不均衡データの壁を突破する | IBM ソリューション ブログ

ModelerにはSMOTEノードがあります。imbalanced-learnでもSMOTEが可能です。

SMOTE — Version 0.8.0

#4. サンプル
サンプルは以下に置きました。

ストリーム
https://github.com/hkwd/200611Modeler2Python/raw/master/balance/balance3.str
notebook
https://github.com/hkwd/200611Modeler2Python/blob/master/balance/balance.ipynb
データ
https://raw.githubusercontent.com/hkwd/200611Modeler2Python/master/data/credit_risk.csv

■テスト環境
Modeler 18.3
Windows 10 64bit
Python 3.8.5
pandas 1.0.5
imblearn 0.7.0

#5. 参考情報

Python: 機械学習における不均衡データの問題点と対処法について - CUBE SUGAR CONTAINER

バランス・ノード - IBM Documentation

imbalanced-learn API reference — Version 0.8.0

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?