SVM不同特征组合精度一致,类别不平衡及class_weight调优求助
问题分析与解决方案
你的核心问题是类别严重不平衡,而非过拟合。模型直接学会了预测占比更高的多数类,因此不管更换特征、调参,精度都会维持在「全猜多数类」的基线水平;而使用class_weight后精度下降,是因为精度这个指标在不平衡数据集里完全失效,得看少数类的召回率、F1分数等指标。
1. 先确认数据分布
先统计训练集里deal_status的类别占比,明确不平衡程度:
y_train['deal_status'].value_counts(normalize=True)
如果某类占比超过90%,模型直接猜该类就能拿到高精度,这就是为什么特征变化不影响结果——特征根本没机会发挥作用。
2. 替换评估指标
放弃用「精度」评估模型,改用召回率(recall)、F1分数这些针对少数类的指标。你用class_weight后精度下降,本质是模型开始尝试预测少数类,牺牲了部分多数类的正确预测,但这是优化的必经过程——重点看少数类的召回率是否提升,而非盯着精度。
3. 解决类别不平衡的具体方案
(1)重采样训练集
只在训练集上操作,不要碰测试集:
- 过采样:给少数类生成合成样本,比如SMOTE:
from imblearn.over_sampling import SMOTE sm = SMOTE(random_state=42) X_train_res, y_train_res = sm.fit_resample(X_train, y_train) - 欠采样:减少多数类样本数量,比如用
RandomUnderSampler,但注意不要丢失过多有效信息。
(2)调整决策阈值
SVM默认用0.5的阈值判断类别,你可以通过概率输出调低少数类的决策阈值,让模型更倾向于预测少数类:
# 假设少数类是类别1 y_proba = grid.predict_proba(X_test)[:, 1] # 把阈值从0.5降到0.3(可根据实际情况调整) y_pred = (y_proba > 0.3).astype(int)
(3)扩大参数搜索范围
你当前的GridSearchCV参数范围太窄,且没针对不平衡优化,试试扩大范围并指定合适的评分指标:
param_grid = { 'C': [0.001, 0.01, 0.1, 1, 10, 100], 'gamma': ['auto', 'scale', 0.001, 0.01, 0.1], 'kernel': ['linear', 'rbf'], 'class_weight': ['balanced'] } # 用f1_macro作为评分指标,优先优化少数类表现 grid = GridSearchCV(rfc, param_grid=param_grid, refit=True, verbose=2, n_jobs=-1, scoring='f1_macro')
(4)换用对不平衡更友好的模型
比如XGBoost、LightGBM,它们自带scale_pos_weight参数,能更稳定地调整类别权重,比SVM的class_weight效果更可控。
4. 特征有效性验证
现在特征变化不影响结果,是因为模型根本没用到这些特征(全猜多数类)。等解决不平衡问题后,再通过特征重要性分析、单独训练仅含目标特征的模型,评估cult_distance和inst_dist的实际作用。
内容的提问来源于stack exchange,提问作者Paul Engelbert
相关产品推荐
相关产品推荐

