機械学習操作を実行するために、Pythonプログラムでscikit-learnを使用しています。問題は、私のデータセットに深刻な不均衡の問題があることです。
Scikit-learnまたはpython全般の不均衡の解決策を知っている人はいますか? Javaには、SMOTEメカニズムがあります。 Pythonには何か平行したものがありますか?
SMOTEはscikit-learnの組み込みではありませんが、それでもオンラインで利用可能な実装があります。
ここ など。
ここに新しいものがあります
https://github.com/scikit-learn-contrib/imbalanced-learn
SMOTEを含む、次のカテゴリの多くのアルゴリズムが含まれています
ここで、アンダーサンプリングと複数のSMOTE
実装を含む複数のオーバーサンプリング技術を実装するライブラリと、SVM
を使用するライブラリを見つけました。
他の人が非常に人気のある不均衡学習ライブラリへのリンクをリストしているので、いくつかのリンクとともにそれを適切に使用する方法の概要を説明します。
https://imbalanced-learn.org/en/stable/generated/imblearn.under_sampling.RandomUnderSampler.html
https://imbalanced-learn.org/en/stable/generated/imblearn.over_sampling.RandomOverSampler.html
https://imbalanced-learn.readthedocs.io/en/stable/generated/imblearn.over_sampling.SMOTE.html
https://imbalanced-learn.org/en/stable/combine.html
不均衡学習での一般的なオーバーサンプリングとアンダーサンプリングのテクニックには、imblearn.over_sampling.RandomOverSampler、imblearn.under_sampling.RandomUnderSampler、imblearn.SMOTEがあります。これらのライブラリには、ユーザーがサンプリング比を変更できるようにするNiceパラメーターがあります。
たとえば、SMOTEでは、比率を変更するには辞書を入力し、すべての値は最大クラス以上でなければなりません(SMOTEはオーバーサンプリング手法であるため)。私の経験上、SMOTEがモデルのパフォーマンスにより適しているとわかったのは、おそらくRandomOverSamplerを使用すると行を複製しているためです。つまり、モデルは新しいデータに一般化するのではなく、データの記憶を開始できます。 SMOTEはK-Nearest-Neighborsアルゴリズムを使用して、サンプリングされたデータポイントに「類似した」データポイントを作成します。
SMOTEが「類似の」観測を行うために最近傍を使用している場合でも、モデルが1つまたは複数のマイノリティクラスをオーバーフィットする可能性があるため、SMOTEを盲目的に使用して比率をデフォルト(クラスバランスでも)に設定するのは良い習慣ではない場合があります。 MLモデルのハイパーパラメーターを調整するのと同様の方法で、比率やknnなどのSMOTEアルゴリズムのハイパーパラメーターを調整します。以下は、SMOTEを適切に使用する方法の実例です。
注:完全なデータセットではSMOTEを使用しないことが重要です。トレーニングセットでのみ(つまり、分割後)SMOTEを使用し、検証セットとテストセットで検証して、SMOTEモデルが他のモデルを実行したかどうかを確認する必要があります。これを行わないと、データ漏洩が発生し、まったく無関係なモデルが得られます。
from collections import Counter
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
import numpy as np
from xgboost import XGBClassifier
import warnings
warnings.filterwarnings(action='ignore', category=DeprecationWarning)
sm = SMOTE(random_state=0, n_jobs=8, ratio={'class1':100, 'class2':100, 'class3':80, 'class4':60, 'class5':90})
X_resampled, y_resampled = sm.fit_sample(X_normalized, y)
print('Original dataset shape:', Counter(y))
print('Resampled dataset shape:', Counter(y_resampled))
X_train_smote, X_test_smote, y_train_smote, y_test_smote = train_test_split(X_resampled, y_resampled)
X_train_smote.shape, X_test_smote.shape, y_train_smote.shape, y_test_smote.shape, X_resampled.shape, y_resampled.shape
smote_xgbc = XGBClassifier(n_jobs=8).fit(X_train_smote, y_train_smote)
print('TRAIN')
print(accuracy_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))
print(f1_score(smote_xgbc.predict(np.array(X_train_normalized)), y_train))
print('TEST')
print(accuracy_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))
print(f1_score(smote_xgbc.predict(np.array(X_test_normalized)), y_test))