データの不均衡問題とその対処法
クラス分類の問題において、一部のクラスのデータが他のクラスに比べて大幅に少ない場合、データの不均衡という状況が生じます。不均衡なデータセットをそのまま使ってモデルを訓練すると、モデルは大多数のクラスを予測することで高い正確性を達成できますが、少数クラスの予測能力は低いままとなります。これに対処する一つの方法が、アップサンプリングという手法です。本記事では、Pythonを用いてアップサンプリングとその一つの手法であるSMOTEの例を紹介します。
アップサンプリングとは
アップサンプリングは、少数クラスのデータを人工的に増やす(サンプリングアップする)ことで、クラス間のデータのバランスをとる方法です。アップサンプリングには、ランダムサンプリング、**SMOTE(Synthetic Minority Over-sampling Technique)**などの手法があります。
ランダムサンプリング
ランダムサンプリングでは、少数クラスのデータからランダムにデータを選び、それをコピーしてデータセットに追加します。これにより、少数クラスのデータの数が増え、大多数クラスとのバランスが改善されます。しかし、単にデータをコピーするだけなので、モデルが新たなパターンを学ぶわけではありません。
Pythonを用いたランダムサンプリングの例を以下に示します。ここでは、imbalanced-learnパッケージを使用します。
from imblearn.over_sampling import RandomOverSampler
from sklearn.datasets import make_classification
import numpy as np
# 不均衡なデータセットの生成
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2,
n_redundant=0, n_repeated=0, n_classes=2,
n_clusters_per_class=1,
weights=[0.99, 0.01],
class_sep=0.8, random_state=0)
# オリジナルデータのクラス分布
print('Original dataset shape %s' % np.bincount(y))
ros = RandomOverSampler(random_state=0)
X_resampled, y_resampled = ros.fit_resample(X, y)
# サンプリング後のクラス分布
print('Resampled dataset shape %s' % np.bincount(y_resampled))
SMOTE
SMOTEはより高度なアップサンプリングの手法で、新たな少数クラスのデータを合成します。SMOTEは以下のステップで動作します:
少数クラスの各サンプルについて、k最近傍法(k-NN)を使って最も近い「隣人」を見つけます。
これらの「隣人」の間でランダムに一つを選びます。
選ばれた「隣人」と元のサンプルとの間に新しいサンプルを生成します。これは、選ばれた「隣人」から元のサンプルに向かう線分上の点をランダムに選ぶことで実現されます。
これにより、新しいサンプルが生成され、元のデータに追加されます。これらの新しいサンプルは元のデータに基づいていますが、元のデータとは異なるため、モデルが新たなパターンを学ぶことが可能となります。
Pythonを用いたSMOTEの例を以下に示します。ここでも、imbalanced-learnパッケージを使用します。
from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state=42)
X_resampled, y_resampled = sm.fit_resample(X, y)
# サンプリング後のクラス分布
print('Resampled dataset shape %s' % np.bincount(y_resampled))
ただし、SMOTEは単にデータを増やすだけでなく、新しいデータが元のデータの特徴空間内である程度均一に分布するように合成するため、適用する際には注意が必要です。特に、少数クラスのデータが大多数クラスのデータと重なる領域でSMOTEを適用すると、新しく合成されたデータが大多数クラスの領域に侵入する可能性があり、ノイズの多いモデルを生み出す可能性があります。そのため、SMOTEを適用する際には、その効果を確認しながら適切なパラメータを設定することが重要です。