Sklearn自定义F2评分函数在参数搜索中结果异常?
1. 交叉验证阶段的SMOTE数据泄露
你很可能在错误的时机做了SMOTE处理:如果先对整个数据集完成SMOTE再拆分交叉验证折,合成的样本会同时出现在训练折和验证折中,导致模型在验证阶段能“看到”部分训练相关的合成数据,交叉验证分数被严重高估。正确流程应该是:先拆分训练集与测试集,再针对每个交叉验证的训练折单独执行SMOTE,验证折完全不参与SMOTE生成。
另外,原数据中好样本仅100个,SMOTE生成的合成样本本身就依赖有限的真实样本特征,交叉验证折如果划分不均(比如某折真实好样本极少,合成样本占比过高),会让模型在验证集上过度拟合合成数据,表现虚高,但面对真实测试样本时泛化能力骤降。
2. 自定义F2评分函数的计算偏差
你的自定义F2评分函数大概率存在类别指向错误:RandomizedSearchCV默认可能没有指定正类别(你关注的“好样本”),导致交叉验证时计算的F2是针对多数类(坏样本)的得分。由于坏样本占90%,哪怕模型全预测坏样本,针对多数类的F2分数也会极高(接近1),这完全能解释0.958的虚高结果。
检查你的自定义函数:必须明确指定pos_label为“好样本”的标签值,并且严格遵循sklearn评分函数的接口(接受y_true和y_pred作为输入,输出针对少数类的F2分数)。
3. SVC参数搜索的过拟合风险
如果RandomizedSearchCV中C参数的搜索范围设置得过大,会让SVC模型过度拟合训练数据(包括SMOTE生成的合成样本噪声)。C值越大,SVC对误分类的惩罚越重,会试图拟合所有样本点,在交叉验证的小折上表现极好,但面对未见过的真实测试数据时,泛化能力急剧下降,导致测试集F2分数反而比默认参数更低。
另外,SVC默认未设置class_weight,即使做了SMOTE,若交叉验证折内的样本分布仍有偏差,模型可能还是倾向于多数类,但错误的交叉验证分数会掩盖这个问题。
4. 预处理步骤的数据泄露
检查异常值截断、数据缩放的执行时机:如果先对整个数据集做缩放(用全量数据的均值、标准差)再拆分训练/测试集,测试集的信息会泄露到训练过程中,导致交叉验证结果乐观,但测试集实际表现差。正确做法是仅用训练集的统计量完成缩放和异常值截断,再将相同规则应用到测试集。
内容的提问来源于stack exchange,提问作者Alex96

