随机森林不平衡类(正为少数类),低精度和怪异的得分分布

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

我有一个非常不平衡的数据集(5000正面300000负)。我使用sklearn RandomForestClassifier尝试和预测正类的概率。我有多年的数据和我的设计特点之一是前一年的课,所以我隐瞒数据集的最后一年,除了我的测试从我训练年内设置上测试上。

这里是我试过什么(结果):

上采样与SMOTE和SMOTEENN(怪异得分分布,见第一PIC,预测为正和负类概率都是相同的,即,该模型预测的大部分正类的非常低的概率)

下采样到一个平衡的数据集(召回〜0.80的测试集,但为0.07外的年度测试从总底片的数量之多,在不平衡列明年测试集,见第二张图)

离开它不平衡(怪异的进球再次分配,精度上升到0.60〜和回忆下​​降到0.05和0.10的测试和外的年测试集)

XGBoost(对超出年的试验组稍好召回,0.11)

我应该尝试下?我想,以优化F1,因为这两个假阳性和假阴性是在我的情况同样糟糕。我想结合k重交叉验证,并已阅读过采样之前,我应该这样做,一)我应该这样做/是有可能帮助和b)我怎么能纳入一个类似的管道如下:

from imblearn.pipeline import make_pipeline, Pipeline

clf_rf = RandomForestClassifier(n_estimators=25, random_state=1)
smote_enn = SMOTEENN(smote = sm)
kf = StratifiedKFold(n_splits=5)

pipeline = make_pipeline(??)

pipeline.fit(X_train, ytrain)
ypred = pipeline.predict(Xtest)
ypredooy = pipeline.predict(Xtestooy)

python scikit-learn random-forest
1个回答
3
投票
  • 采样与SMOTE和SMOTEENN:我远不是那些专家,但通过上采样数据集可能会放大存在的噪声从而诱发过度拟合。这可以解释的事实,你的算法不能正确分类,从而使在第一张图的结果。

我发现多一点点的信息在这里,也许如何提高你的结果:https://sci2s.ugr.es/sites/default/files/ficherosPublicaciones/1773_ver14_ASOC_SMOTE_FRPS.pdf

  • 当你下采样你似乎遇到同样的问题,过拟合我的理解是(至少前一年的目标结果)。这是很难推断其背后的原因,没有对数据的视图,虽然。
  • 你的过度拟合问题可能来自你使用可能增加不必要的噪声特征的数量。您可以尝试减少您使用的功能数量,逐渐增加它(使用RFE模型)。这里更多的信息:

https://machinelearningmastery.com/feature-selection-in-python-with-scikit-learn/

对于您所使用的模型,你提到的随机森林和XGBoost,但你没有提到有使用简单的模型。你可以尝试简单的模型,并专注于你的数据工程。如果你还没有尝试它,或许你还可以:

  • 下采样数据
  • 规范化与StandardScaler所有数据
  • 简单的模型,如朴素贝叶斯和Logistic回归测试的“强力”调整 # Define steps of the pipeline steps = [('scaler', StandardScaler()), ('log_reg', LogisticRegression())] pipeline = Pipeline(steps) # Specify the hyperparameters parameters = {'C':[1, 10, 100], 'penalty':['l1', 'l2']} # Create train and test sets X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42) # Instantiate a GridSearchCV object: cv cv = GridSearchCV(pipeline, param_grid=parameters) # Fit to the training set cv.fit(X_train, y_train)

无论如何,你比如管道可能是(我用Logistic回归造的,但是你可以用另一ML算法改变,因此改变参数网格):

from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV, StratifiedKFold, cross_val_score

from imblearn.combine import SMOTEENN
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import Pipeline

param_grid = {'C': [1, 10, 100]}

clf = LogisticRegression(solver='lbfgs', multi_class = 'auto')
sme = SMOTEENN(smote = SMOTE(k_neighbors = 2), random_state=42)
grid = GridSearchCV(estimator=clf, param_grid = param_grid, score = "f1")

pipeline = Pipeline([('scale', StandardScaler()),
                     ('SMOTEENN', sme),
                     ('grid', grid)])

cv = StratifiedKFold(n_splits = 4, random_state=42)
score = cross_val_score(pipeline, X, y, cv=cv)

我希望这可以帮助你。

(编辑:我在GridSearchCV加入得分=“F1”)

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