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

Sklearn中F-beta=0.5评分器调参结果与预期相悖问题排查

问题排查:F0.5评分器调参后结果与预期相反的原因

首先,我们先明确核心矛盾:你设置β=0.5的F分数(更侧重precision),但调参后的模型反而precision下降、recall上升,且测试集上默认模型的F0.5分数更高——这说明你的交叉验证(CV)过程的评分结果不可靠,导致RandomizedSearchCV选错了参数组合。下面是具体的排查步骤和解决方案:

1. 先验证两个模型的F0.5分数(手动计算)

根据你给出的混淆矩阵,我们可以手动计算F0.5:

  • 调参后模型:
    $$F_{0.5} = (1+0.5^2) \cdot \frac{0.67 \times 0.90}{(0.5^2 \times 0.67) + 0.90} = 1.25 \cdot \frac{0.603}{0.1675+0.9} \approx 0.706$$
  • 默认参数模型:
    $$F_{0.5} = 1.25 \cdot \frac{0.84 \times 0.68}{(0.25 \times 0.84) + 0.68} =1.25 \cdot \frac{0.5712}{0.21+0.68} \approx 0.802$$

显然默认模型的F0.5分数更高,但RandomizedSearchCV却选择了调参后的模型,这说明CV过程的评分和测试集完全脱节,问题出在CV的设置上。

2. 核心问题:普通KFold不适合不平衡分类

你使用的是旧版sklearn的cross_validation.KFold,并且默认不打乱数据+不分层:

cv = cross_validation.KFold(len(X_train), n_folds=10)

对于高度不平衡的数据集(你的真实0类样本远多于1类),普通KFold会导致:

  • 如果训练集样本是按类别排序的,部分fold里可能几乎没有1类样本,此时fbeta_score的计算会失真(比如出现NaN或异常值)
  • 每个fold的类别比例和整体数据集差异极大,CV评分无法反映模型在真实场景下的性能

RandomizedSearchCV基于这些不可靠的CV评分选择参数,自然会选出不符合预期的模型。

3. 解决方案:改用分层KFold并打乱数据

替换普通KFold为StratifiedKFold,它会保证每个fold的类别比例和整体数据集一致,同时开启shuffle避免有序数据的影响:

# 注意使用新版model_selection模块(旧版cross_validation已废弃)
from sklearn.model_selection import StratifiedKFold

cv = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)

4. 优化评分器定义(避免歧义)

虽然你的scorer定义在逻辑上是对的,但明确指定pos_label和average参数可以避免潜在的歧义(比如当标签不是0/1时的问题):

fO5_scorer = make_scorer(fbeta_score, beta=0.5, pos_label=1, average='binary')

5. 验证CV结果的可靠性

运行调参后,查看所有参数组合的CV评分,确认默认参数的CV评分是否和测试集一致:

import pandas as pd

# 把CV结果转换成DataFrame,方便查看
cv_results = pd.DataFrame(random_search_f05.cv_results_)
# 按排名排序,查看最优参数的评分
print(cv_results[['params', 'mean_test_score', 'rank_test_score']].sort_values('rank_test_score'))

如果默认参数的CV评分确实高于调参后的模型,说明之前的KFold设置是问题根源;如果CV评分和测试集仍有差异,需要检查训练集和测试集的拆分是否合理(比如是否用了分层抽样拆分)。

额外提醒:检查数据拆分过程

如果你的训练集和测试集拆分没有用分层抽样,也可能导致两者的类别分布差异过大,进而出现CV评分和测试集性能不一致的情况。建议用train_test_split时设置stratify=y:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:58:12