機械学習におけるクラス不均衡に対処するための 10 のヒント

機械学習におけるクラス不均衡に対処するための 10 のヒント

導入

あるクラスの観測値が他のクラスの観測値よりも高い場合、クラスの不均衡が生じます。

例: 不正なクレジットカード取引の検出。下図の通り、不正取引件数は約400件、不正でない取引件数は約9万件となっております。

クラスの不均衡は機械学習、特に分類問題においてよく見られる問題です。不均衡なデータは、長期間にわたってモデルの精度を妨げる可能性があります。

階級の不均衡は、以下を含む多くの分野で発生します。

  • 不正行為検出
  • スパムフィルタリング
  • 病気のスクリーニング
  • SaaS サブスクリプション解約
  • 広告クリック

階級不均衡問題

ほとんどの機械学習アルゴリズムは、各クラスにほぼ同じ数の例がある場合に最も効果的に機能します。これは、ほとんどのアルゴリズムが精度を最大化し、エラーを最小化するように設計されているためです。

ただし、データセットのバランスが崩れると、多数派クラスを予測するだけでかなり高い精度が得られますが、モデルを最初に作成した目的である少数派クラスを捕捉できないことがあります。

クレジットカード詐欺検出の例

クレジットカード会社からデータセットを入手し、クレジットカード取引が不正かどうかを調べる必要があるとします。

しかし、ここに落とし穴があります…不正な取引は比較的まれで、取引のわずか 6% が不正です。

さて、始める前に、問題をどのように解決すべきか想像できますか? モデルのトレーニングにまったく時間を費やさなかったとしたらどうなるか想像してみてください。代わりに、常に「不正な取引はない」と予測するコードを 1 行だけ書いたらどうなるでしょうか?

  1. 定義トランザクション(transaction_data):
  2. 戻る  「不正取引はなし」  

さて、どうなると思いますか?あなたの「解決策」の精度は 94% になります!

残念ながら、この正確さは誤解を招くものです。

これらすべての不正のない取引では 100% の精度が得られます。

それらの不正取引の精度は 0% です。

ほとんどの取引が不正ではないため(モデルが優れているからではなく)、全体的な精度が高くなります。

多くの機械学習アルゴリズムは全体的な精度を最大化するように設計されているため、これは明らかに問題です。この記事では、不均衡なデータを処理するためのさまざまな手法について説明します。

データ

この記事では、こちらから入手できるクレジットカード詐欺検出データセットを使用します。

https://www.kaggle.com/mlg-ulb/クレジットカード詐欺

データが読み込まれると、データセットの最初の 5 行が表示されます。

  1. #不正なターゲット変数をチェックし  不正ではないtransactiondata[ 'Class' ].value_counts()#0 -> 不正ではない
  2. # 1 -> 詐欺

  1. # ターゲット変数を視覚化する
  2. g = sns.countplot(データ[ 'クラス' ])
  3. g.set_xticklabels([ '不正ではない' , '不正' ])
  4. plt.show()

データセット間に大きな違いがあることがはっきりとわかります。不正でない取引が 9,000 件、不正な取引が 492 件。

インジケータートラップ

不均衡なデータセットを扱う際に新しい開発者ユーザーが遭遇する主な問題の 1 つは、モデルを評価するために使用されるメトリックに関連しています。精度スコアなどのより単純な指標を使用すると、誤解を招く可能性があります。クラスのバランスが非常に悪いデータセットでは、分類器は常に特徴分析を行わずに最も一般的なクラスを「予測」し、明らかに正しくない高い精度を実現します。

シンプルな XGBClassifier を使用し、特徴エンジニアリングなしでこの実験をしてみましょう。

  1. # ライブラリをインポートする
  2. xgboostからXGBClassifier をインポートします
  3. xgb_model = XGBClassifier().fit(x_train, y_train)# 予測xgb_y_predict = xgb_model.predict(x_test)# 精度スコアxgb_score = acceleration_score(xgb_y_predict, y_test)print( '精度スコアは:' , xbg_score)出力 
  4. 精度スコアは0.992です

99% の精度で、ほとんどのクラスが 0 (不正ではない) と予測されるため、非常に高い精度が得られていることがわかります。

再サンプリング技術

非常に不均衡なデータセットを処理するために広く採用されている手法は、リサンプリングと呼ばれます。これには、多数派クラスからサンプルを削除すること (アンダーサンプリング) と、少数派クラスからさらにサンプルを追加すること (オーバーサンプリング) が含まれます。

クラスのバランスをとることには利点があるものの、これらの手法には欠点もあります。

オーバーサンプリングの最も単純な実装は、少数派クラスのランダムなレコードを複製することであり、これは乱獲につながる可能性があります。

アンダーサンプリングの最も単純な実装では、多数派クラスからランダムなレコードを削除しますが、これにより情報が失われる可能性があります。

クレジットカード詐欺検出の例を使用してこれを実装してみましょう。

まずクラス 0 とクラス 1 を分離します。

  1. クラス 
  2. class_count_0, class_count_1 = データ[ 'クラス' ].value_counts()
  3. # 別々のクラス class_0 = data[data[ 'Class' ] == 0]
  4. class_1 = data[data[ 'Class' ] == 1]#クラス形状を出力します
  5. print( 'クラス0:' , class_0.shape)
  6. print( 'クラス1:' , class_1.shape

1. ランダムアンダーサンプリング

アンダーサンプリングは、多数派クラスから観測値を削除することとして定義できます。これは、多数派と少数派のクラスのバランスが取れる前に行われます。

数百万行など、大量のデータがある場合、アンダーサンプリングは適切な選択肢となります。しかし、アンダーサンプリングの欠点の 1 つは、貴重な情報が削除される可能性があることです。

  1. class_0_under = class_0.sample(class_count_1)
  2. test_under = pd.concat([class_0_under, class_1], 軸=0)
  3. print( "total class of 1 and0:" ,test_under[ 'Class' ].value_counts()) #カウントをプロットする アンダーサンプリング
  4. test_under[ 'クラス' ].value_counts().plot(kind= 'バー' 、title= 'カウント(ターゲット)' )

2. ランダムオーバーサンプリング

オーバーサンプリングは、少数クラスのコピーをさらに追加することとして定義できます。処理するデータがそれほど多くない場合は、オーバーサンプリングが適切なオプションになります。

アンダーサンプリングを行う際に考慮すべき欠点の 1 つは、テスト セットでの過剰適合と一般化の低下につながる可能性があることです。

  1. class_1_over = class_1.sample(class_count_0、 replace = True )
  2. test_over = pd.concat([class_1_over, class_0], 軸=0)
  3. print( "1と0の合計クラス: " ,test_under[ 'Class' ].value_counts()) #カウントをプロットする アンダーサンプリング
  4. test_over[ 'クラス' ].value_counts().plot(kind= 'バー' , title= 'カウント(ターゲット)' )

imbalanced-learn python モジュールを使用してデータのバランスをとる

科学文献では、より洗練された再サンプリング手法が数多く提案されています。

たとえば、多数派クラスのレコードをクラスター化し、各クラスターからレコードを削除してアンダーサンプリングすることで、情報を保持することができます。オーバーサンプリングでは、少数派クラスのレコードの正確なコピーを作成する代わりに、これらのコピーに小さなバリエーションを導入して、より多様な合成サンプルを作成できます。

Python ライブラリ imbalanced-learn を使用して、これらの再サンプリング手法のいくつかを適用してみましょう。これは scikit-learn と互換性があり、scikit-learn-contrib プロジェクトの一部です。

  1. インポートimblearn

3. imblearnを使用したランダムアンダーサンプリング

RandomUnderSampler は、ターゲット クラスのデータのサブセットをランダムに選択することで、データのバランスをとる高速かつ簡単な方法です。置換ありまたは置換なしでサンプルをランダムに選択することにより、多数派クラスをアンダーサンプリングします。

  1. # ライブラリをインポートする
  2. imblearn.under_samplingからRandomUnderSampler をインポートします
  3. rus = RandomUnderSampler(random_state=42, replacement= True )# 予測変数ターゲット変数を適合させる
  4. x_rus, y_rus = rus.fit_resample(x, y)print( '元のデータセットの形状:' , Counter(y))
  5. print( 'データセットの形状を再サンプル' , Counter(y_rus))

4. imblearnを使用したランダムオーバーサンプリング

不均衡なデータに対処する 1 つの方法は、少数クラスで新しいサンプルを生成することです。最も単純な戦略は、現在利用可能なサンプルをランダムにサンプリングして置き換えることで、新しいサンプルを生成することです。ランダムオーバーサンプリングはそのような解決策を提供します。

  1. # ライブラリをインポートする
  2. imblearn.over_samplingからRandomOverSampler をインポートします
  3. ros = ランダムオーバーサンプラー(ランダム状態=42)
  4. # 予測変数ターゲット変数を適合させる x_ros, y_ros = ros.fit_resample(x, y) print( '元のデータセットの形状' , Counter(y))
  5. print( 'データセットの形状を再サンプル' , Counter(y_ros))

5. アンダーサンプリング: Tomek Link

Tomek リンクは、非常に近いインスタンスのペアですが、カテゴリは反対です。多数派クラスの各ペアのインスタンスを削除すると、2 つのクラス間のスペースが広がり、分類プロセスが容易になります。

2つのサンプルが互いに最も近い隣接サンプルである場合、トメックリンクが存在する。

次のコードでは、ratio='majority' を使用して多数派クラスを再サンプリングします。

  1. # ライブラリをインポートする
  2. imblearn.under_samplingからTomekLinks をインポート
  3. tl = RandomOverSampler(サンプリング戦略 = 'majority' )
  4. # 予測変数ターゲット変数を適合させる x_tl, y_tl = ros.fit_resample(x, y) print( '元のデータセットの形状' , Counter(y))
  5. print( 'データセットの形状を再サンプル' , Counter(y_ros))

6. 合成少数オーバーサンプリング技術 (SMOTE)

この手法は、合成少数オーバーサンプリング手法です。

SMOTE (Synthetic Minority Oversampling Technique) は、少数クラスからランダムにポイントを選択し、そのポイントの k 近傍を計算することによって機能します。選択したポイントとその隣接するポイントの間に合成ポイントが追加されます。

SMOTE アルゴリズムは、次の 4 つの簡単な手順で機能します。

  • 入力ベクトルとして少数派クラスを選択する
  • k 個の最も近い近傍を検索します (SMOTE() 関数のパラメータとして k_neighbors を指定します)
  • これらの近傍点の1つを選択し、検討中の点と選択された近傍点を結ぶ線上の任意の場所に合成点を配置します。
  • データのバランスが取れるまでこれらの手順を繰り返します
  1. # ライブラリをインポートする
  2. imblearn.over_samplingからSMOTE をインポートします
  3. smote = SMOTE() # 予測変数ターゲット変数を適合させる x_smote, y_smote = smote.fit_resample(x, y) print( '元のデータセットの形状' , Counter(y))
  4. print( 'データセットの形状を再サンプル' , Counter(y_ros))

7. ニアミス

NearMiss はアンダーサンプリング技術です。距離を使用して少数クラスを再サンプリングする代わりに、多数クラスが少数クラスと等しくなります。

  1. imblearn.under_samplingからNearMiss をインポート
  2. nm = NearMiss()x_nm, y_nm = nm.fit_resample(x, y)print( '元のデータセットの形状:' , Counter(y))
  3. print( 'データセットの形状を再サンプリング:' , Counter(y_nm))

8. パフォーマンス指標の変更

不均衡なデータセットを評価する場合、誤解を招く可能性があるため、精度は最適な指標ではありません。

より良い洞察を提供できる指標は次のとおりです。

  • 混同マトリックス: 正しい予測と誤った予測の種類を示す表。
  • 精度: 真陽性の数をすべての陽性予測数で割った値。精度は陽性予測値とも呼ばれます。これは分類器の精度を測る指標です。精度が低いということは、誤検知の数が多いことを意味します。
  • 再現率: 真陽性の数をテストデータ内の陽性値の数で割ったもの。リコールは、感度または真陽性率とも呼ばれます。これは分類器の完全性を測る尺度です。リコールが低いということは、偽陰性の数が多いことを示します。
  • F1: スコア: 精度と再現率の加重平均。
  • ROC 曲線の下の領域 (AUROC): AUROC は、モデルが 2 つのクラスからの観測値を区別する可能性を表します。

言い換えれば、各クラスからランダムに観測値を選択した場合、モデルがそれらを正しく「ランク付け」できる確率はどれくらいでしょうか。

9. ペナルティアルゴリズム(コスト重視のトレーニング)

次の戦略は、少数派クラスを誤分類するコストを増やすペナルティ付き学習アルゴリズムを使用することです。

この手法でよく使われるアルゴリズムは、Penalized-SVM です。

トレーニング中に、パラメータ class_weight='balanced' を使用して、少数クラスのエラーに、過少表現の度合いに比例した量でペナルティを課すことができます。

SVM アルゴリズムの確率推定を有効にする場合は、パラメータ probability=True も含める必要があります。

元の不均衡なデータセットでペナルティ付き SVM を使用してモデルをトレーニングしてみましょう。

  1. #ライブラリをロード
  2. sklearn.svmからSVC をインポートします
  3. # class_weight= 'balanced'を追加できます  間違いをパナライズする
  4. svc_model = SVC(class_weight= 'balanced' 、確率= True )
  5. svc_model.fit(x_train, y_train)svc_predict = svc_model.predict(x_test) # パフォーマンスをチェックprint( 'ROCAUC スコア:' ,roc_auc_score(y_test, svc_predict))
  6. print( '精度スコア:' ,accuracy_score(y_test, svc_predict))
  7. print( 'F1 スコア:' ,f1_score(y_test, svc_predict))

10. アルゴリズムを変更する

あらゆる機械学習の問題においてさまざまなアルゴリズムを試してみるのは良い経験則ですが、不均衡なデータセットの場合に特に有益です。

決定木は、不均衡なデータに対しても優れたパフォーマンスを発揮することがよくあります。現代の機械学習では、ツリー アンサンブル (ランダム フォレスト、勾配ブースティング ツリーなど) は、単一の決定木よりもほぼ常に優れているため、その点について簡単に説明します。

ツリーベースのアルゴリズムは、if/else 問題の階層を学習することによって機能します。これにより、両方のクラスの解決が強制されます。

  1. #ライブラリをロード
  2. sklearn.ensembleからRandomForestClassifier をインポートします
  3. rfc = RandomForestClassifier() # 予測子ターゲットを適合しますrfc.fit(x_train, y_train)# 予測しますrfc_predict = rfc.predict(x_test)#パフォーマンスを確認しますprint( 'ROCAUC スコア:' , roc_auc_score(y_test, rfc_predict))
  4. print( '精度スコア:' ,accuracy_score(y_test, rfc_predict))
  5. print( 'F1スコア:' ,f1_score(y_test, rfc_predict))

アンダーサンプリングの利点と欠点

アドバンテージ

  • トレーニング データセットが大きい場合、トレーニング データ サンプルの数を減らすことで、実行時間とストレージの問題を改善できます。

欠点

  • ルール分類子の構築に重要となる可能性のある、潜在的に有用な情報を破棄する可能性があります。
  • ランダム アンダーサンプリングによって選択されたサンプルは、偏ったサンプルになる可能性があります。これにより、実際のテスト データセットで不正確な結果が生じる可能性があります。

オーバーサンプリングの利点と欠点

アドバンテージ

  • アンダーサンプリングとは異なり、この方法では情報が失われることはありません。
  • サンプリング条件下でのパフォーマンスの向上

欠点

  • 少数クラスのイベントを複製するため、過剰適合の可能性が高まります。

私の GitHub リポジトリでコードの実装を確認できます。

https://github.com/benai9916/Handle-imbalanced-data/tree/master

結論は

要約すると、この記事では、データセット内のクラスの不均衡に対処するためのさまざまな手法について説明しました。実際には、不均衡なデータを処理するときに試すことができるアプローチは多数あります。この記事がお役に立てば幸いです。

<<:  9つの主要テーマ!機械学習アルゴリズム理論に関する面接の質問の要約

>>:  ビジネスにおけるAIベースの音声認識アプリケーション

ブログ    
ブログ    

推薦する

シナリオイノベーションがスマート発電所を強化 | Ruijie Networks が 2021 年スマート発電所フォーラムに登場

2021年4月27日〜28日、華北電力大学技術移転・変革センターと中関村華電エネルギー・電力産業連盟...

ディープラーニング、ノイズ除去オートエンコーダを使用して生データを予測する方法は?

[[214638]]ノイズ除去オートエンコーダー (DAE) は、破損したデータを入力として受け入...

CTO は、企業開発のさまざまな段階で知的財産権の対応する全体像をどのように確立できるでしょうか?

最近、新しい「特許法」の全文が公布され、新たに改正された「著作権法」が公布されたことにより、国は知的...

「ロボット排除の3原則」を破る方法

2013年に私は2つの文章を書きました。1つは「デジタル化できるものはすべてデジタル化される」という...

...

...

データによると、ChatGPTのトラフィックは8月末から増加し始めており、これは主に新学期の始まりによるものである。

9月21日、第三者機関の最新の推計によると、人工知能チャットボット「ChatGPT」のトラフィック...

速報です!画像AI企業「Huiyi Huiying」がハッキングされ、COVID-19研究成果が公開された

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

遠隔医療と増加する高齢者人口:高齢者ヘルスケアの強化

高齢者人口の継続的な増加は、高齢者の差し迫った健康ニーズを満たすために医療および保健システムを改善す...

エッセンス共有サイトのランキングアルゴリズムのまとめ

ウェブサイトのランキングは、ウェブサイトの最適化を行うすべての人が最も気にしていることです。しかし、...

劉玉樹:人工知能における中国と米国の格差は縮まっているが、まだやるべきことはある

著者の劉玉樹氏は中国人民大学重陽金融研究所学務委員会委員、マクロ研究部部長、研究者である。本稿は11...

2021年に人工知能はどのように発展するのでしょうか? 6つの予測

海外メディアの報道によると、人工知能はここ数年、着実な成長曲線を保っている。しかし、COVID-19...

...

いくつかの小さな図でディープラーニングを徹底的に説明します

Andrew Ng 氏は、Tess Ferrandez 氏が修了したディープラーニング特別コースのイ...

...