You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sklearn随机森林针对不平衡数据集优化AUC/F1分数的方法咨询

不平衡数据集下优化模型AUC/F1指标的技巧及模型支持

Sklearn随机森林能否针对AUC/F1优化?

Sklearn的随机森林默认以基尼系数或熵作为分裂准则,训练时直接优化的是分类准确率,无法将AUC、F1这类考虑样本不平衡的指标作为训练目标。但可以通过间接手段引导模型向优化这类指标的方向靠拢。

除类别权重外的优化技巧

1. 数据集重采样

  • 过采样:对占比少的正类样本进行扩充,推荐用SMOTE生成合成样本(避免简单重复导致过拟合),可通过imblearn.over_sampling.SMOTE实现。
  • 欠采样:对占比多的负类样本进行筛选,比如用NearMiss保留与正类样本关联性更强的负类样本,减少冗余数据。
  • 混合采样:结合欠采样和过采样,比如先对负类欠采样,再对正类做SMOTE过采样,平衡数据集的同时降低过拟合风险。

2. 用目标指标指导调参

在使用GridSearchCV或RandomizedSearchCV调参时,将scoring参数指定为'roc_auc'或'f1',调参过程会自动选择在目标指标上表现最优的模型参数,间接让模型适配不平衡场景。示例代码:

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier

param_grid = {'n_estimators': [100, 200], 'max_depth': [5, 10]}
rf = RandomForestClassifier(class_weight='balanced')
grid_search = GridSearchCV(rf, param_grid, scoring='roc_auc', cv=5)
grid_search.fit(X_train, y_train)

3. 自定义样本权重

除了class_weight参数按类别设置权重,还可以手动给每个样本分配权重(比如正类样本权重设为4,负类设为1,对应类别占比的反比),通过fit方法的sample_weight参数传入,更灵活地控制样本对模型训练的影响。

4. 调整分类阈值

随机森林输出的是样本属于正类的概率,默认0.5的分类阈值在不平衡数据集上往往不是最优的。可以通过PR曲线或ROC曲线找到能最大化F1或AUC的阈值,再用该阈值生成预测结果。示例:

import numpy as np
from sklearn.metrics import precision_recall_curve

# 得到正类概率
y_proba = rf.predict_proba(X_test)[:, 1]
# 计算不同阈值下的精确率、召回率
precision, recall, thresholds = precision_recall_curve(y_test, y_proba)
# 找到F1最高的阈值
f1_scores = 2 * (precision * recall) / (precision + recall)
best_threshold = thresholds[np.argmax(f1_scores)]
# 用最优阈值生成预测结果
y_pred = (y_proba >= best_threshold).astype(int)

其他模型的自定义指标支持(以XGBoost为例)

XGBoost、LightGBM、CatBoost这类梯度提升树模型,相比随机森林更灵活,支持自定义评估指标甚至目标函数:

  • XGBoost处理不平衡+优化AUC:可以设置scale_pos_weight为负类与正类的比例(这里是4)来平衡类别,同时将eval_metric设为'auc',训练过程中监控AUC指标。
  • XGBoost自定义F1评估:可以编写自定义评估函数,在训练时监控F1分数,调参时选择F1最优的模型。示例代码:
import xgboost as xgb

# 转换为XGBoost专用数据格式
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

params = {
    'objective': 'binary:logistic',
    'scale_pos_weight': 4,  # 平衡类别权重
    'eval_metric': 'auc'
}

# 自定义F1评估函数
def f1_score_eval(preds, dtrain):
    labels = dtrain.get_label()
    preds = (preds >= 0.5).astype(int)
    tp = (labels * preds).sum()
    fp = ((1 - labels) * preds).sum()
    fn = (labels * (1 - preds)).sum()
    precision = tp / (tp + fp) if (tp + fp) != 0 else 0
    recall = tp / (tp + fn) if (tp + fn) != 0 else 0
    f1 = 2 * precision * recall / (precision + recall) if (precision + recall) != 0 else 0
    return 'f1', f1

# 训练并监控自定义指标
watchlist = [(dtrain, 'train'), (dtest, 'test')]
model = xgb.train(params, dtrain, num_boost_round=100, evals=watchlist, feval=f1_score_eval, maximize=True)

LightGBM可通过is_unbalance参数自动处理不平衡,CatBoost支持auto_class_weights='Balanced',两者也都支持自定义评估指标。

内容的提问来源于stack exchange,提问作者Baron Yugovich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:52:20