如何处理高度不平衡的分类?

数据挖掘 机器学习 Python 分类 机器学习模型 助推
2022-03-10 13:10:28

我一直在处理分类问题。真正的问题是这里的不平衡

我有约 500,000 个 -ve 样本和约 300 个 +ve 样本。最终结果是预测概率而不是硬 0-1 分类 就我个人而言,我不是过采样/欠采样的忠实粉丝,因为它们会使分布混乱。我还尝试了分层抽样,以便在训练时保持相同的比例,但它不起作用。对于我目前的方法,我抽取一个 -ve 点样本(比如 100,000 个),然后用 300 个 +ve 样本进行训练,并获得 ~85 的 ROC-AUC,但几乎没有任何情况预测达到概率 > 51%(使用 model.predict_proba 后) . 关于处理这种极端不平衡的任何提示?另外,我只想继续使用基于树的模型或增强模型,因为它们提供了可解释性(因此暂时避免使用神经网络、异常检测、自动编码器)。任何提示,资源赞赏!下面是我正在使用的代码。

df = read_data(path)
Pkl_Filename = path + "/catboost.pkl"
# if not os.path.exists(Pkl_Filename):
X = df.drop(ep_config['target_field'], axis=1)
y = df[ep_config['target_field']]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, stratify=y)
clf = CatBoostClassifier(eval_metric='Recall', use_best_model=True, scale_pos_weight=...)
sm = SMOTE(random_state=27, ratio=1.0)
X_train, y_train = sm.fit_sample(X_train, y_train)
smote = clf.fit(X_train, y_train, eval_set=(X_test, y_test))

# smote_pred = smote.predict(X_test)

# Checking accuracy
# accuracy_score(y_test, smote_pred)
# clf.fit(X_train, y_train, eval_set=(X_test, y_test))
with open(Pkl_Filename, 'wb') as file:
    pickle.dump(smote, file)
# else:
#     clf = pickle.loads(Pkl_Filename)
logging.info('the test roc is :{:.6f}'.format(roc_auc_score(y_test, smote.predict_proba(X_test)[:,1])))
1个回答

您是否已经尝试过只使用很少的 -ve 案例?例如,要在总共 900 个点上训练您的模型,600/300?那么分层抽样应该仍然可以正常工作。然后我会根据你的模型预测 -ve 案例的能力来评估你的模型,并只监控它在模型以前从未见过的(在你的案例中)巨大的测试数据集上的性能。

此外,您可以通过从真实数据中引导来生成“合成”+ve 案例,以查看它如何影响模型。与此处描述的类似:https ://sci2s.ugr.es/keel/pdf/specific/articulo/dupret_science.pdf