我正在处理二进制分类问题中非常不平衡的数据集(约5%)。我正在管道SMOTE和随机森林分类器,以使我的过度采样发生在GridSearch CV循环内(如建议的here)。您可以在下面看到我的实现:

from imblearn.over_sampling import SMOTE
from sklearn.ensemble import RandomForestClassifier
from imblearn.pipeline import Pipeline
from sklearn.model_selection import RandomizedSearchCV, StratifiedKFold

sm = SMOTE()
rf = RandomForestClassifier()

pipeline = Pipeline([('sm', sm), ('rf', rf)])

kf = StratifiedKFold(n_splits = 5)

params = {'rf__max_depth' : list(range(2,5)),
    'rf__max_features' : ['auto','sqrt'],
    'rf__bootstrap' : [True, False]
}

grid = RandomizedSearchCV(pipeline, param_distributions = params, scoring = 'f1', cv = kf)

grid.fit(X, y)


但是,this paper(请参阅第7页的表4)建议测试不同的重采样率,以找出哪个可以提供更好的性能。现在,使用我的sm = SMOTE(),我正在生成50-50%的数据集,但我想遍历一系列潜在比率(例如5-95、10-90等)。但是,SMOTE中的ratio参数不能接受所需的百分比率,而是带有样本数量的特定整数,由于kfold CV,我认为我无法做到这一点(每折可能会略有增加不同的样本量)。如何实现呢?

最佳答案

虽然在文档中未提及,但我认为您可以将float指定为ratio。但是您应该知道它已被弃用,并将在将来的版本中删除(因为我认为这仅适用于二进制情况,不适用于多类)。

params = {'sm__ratio' : [0.05, 0.10, 0.15],
          'rf__max_depth' : list(range(2,5)),
          'rf__max_features' : ['auto','sqrt'],
          'rf__bootstrap' : [True, False]
         }

grid = RandomizedSearchCV(pipeline, param_distributions = params, scoring = 'f1', cv = kf)


还要注意,您在此处提到的比率将是对少数群体进行上采样后的类别比率。

因此,假设您有如下原始类:

  1:  75
  0:  25


然后将比率指定为0.5。在这里,多数类将不会被触及,但是将生成12个更多的0类合成样本,因此最终数字为:

  1:  75
  0:  37  (25 + 12)


最终比率是37/75 = 0.5(如上所述)。

关于python - CV-ing数据集时如何实现基于比率的SMOTE过采样,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51480776/

10-12 16:55