如何在CV-ing数据集中实现基于比率的SMOTE过采样

问题描述 投票:1回答:1

我正在处理关于二元分类问题的非常不平衡的数据集(~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(见表4第7页)建议测试不同的重采样率,以确定哪一个提供更好的性能。现在,我的sm = SMOTE()我正在生成一个50-50%的数据集,但我想循环一个潜在比率列表(例如5-95,10-90等)。然而,SMOTE中的比率参数不接受所需的百分比,而是一个具有样本数量的特定整数,由于我的kfold CV,我认为我无法做到这一点(每个折叠可能会有一个略微不同的样本尺寸)。怎么能实现呢?

python scikit-learn cross-validation
1个回答
1
投票

虽然在文档中没有提到,但我认为你可以把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(正如你所提到的)。

© www.soinside.com 2019 - 2024. All rights reserved.