OverSmpling-Error(expects n_neighbors <= n_samples)

2024/01/25に公開

背景

研究でオーバーサンプリングの研究をしており,既存手法との比較を行うためにimbalanced-learnライブラリのSMOTEやADASYNを実行したときに

expects n_neighbors <= n_samples, but n_samples < n_neighbors

のエラーが出て,長い時間悩んだので,備忘録も兼ねて記事を書く

エラーの内容

ChatGPTに聞くと

このエラーは、K-Nearest Neighbors(KNN)アルゴリズムの n_neighbors パラメータが、データセットのサンプル数よりも大きい値に設定されていることを示しています。エラーメッセージにあるように、n_neighbors は 7 で、n_samples(サンプル数)は 2 です。

KNNでは、最寄りの近傍点を見つけるために n_neighbors パラメータが使用されますが、その値がサンプル数よりも大きいと、計算が不可能となります。各データポイントに対して計算される最近傍点の数が、データセット全体のサンプル数を上回ることは許容されません。

と出る.なるほど
そこで提案されたのが,SMOTEを呼び出すときにk_neighborsの値をデフォルトの5から3とかに減らせって言われた.例えば

sm = SMOTE(k_neighbors = 3)

とか.
これを試してみたが,やっぱりエラーは消えない.

解決策

いろいろ調べてみたら,そもそもデータ数が十分にないことが分かった.(正確には,データが十分に無いラベルが含まれている)
私が用いていたIot-23のデータセットの中身は

PartOfAHorizontalPortScan     230690
Okiru                          73681
Benign                         55419
DDoS                           38718
C&C                             4230
Attack                          1128
C&C-HeartBeat                    104
C&C-FileDownload                  15
C&C-Torii                          9
C&C-HeartBeat-FileDownload         4
FileDownload                       2
Name: label, dtype: int64

C&C-Toriiの攻撃や,C&C-HeartBeat-FileDownload,FileDownloadの攻撃のデータ数はもともと9とか4とか2とか少ないため,そもそも隣接点(k_neighbors)を計算できなかったという訳だ.
なので,解決策としては

  1. データの少ないラベルのデータをRandom Over Samplerなので増やす
  2. 極端にデータの少ないラベルはそもそも消す(df = df[df['Label'] != label_to_remove]などで)

さいごに

オーバーサンプリングは不均衡データを解決するために結構使える手法であり,今回のエラーは少数派データがある故のエラーなので,誰の役に立てれば.

Discussion