我有一个非常不平衡的数据集(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)
我发现多一点点的信息在这里,也许如何提高你的结果:https://sci2s.ugr.es/sites/default/files/ficherosPublicaciones/1773_ver14_ASOC_SMOTE_FRPS.pdf
https://machinelearningmastery.com/feature-selection-in-python-with-scikit-learn/
对于您所使用的模型,你提到的随机森林和XGBoost,但你没有提到有使用简单的模型。你可以尝试简单的模型,并专注于你的数据工程。如果你还没有尝试它,或许你还可以:
# 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”)