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

Scikit-learn中如何便捷用交叉验证对比模型与均值基准模型?

问题背景与疑问

我在做泰坦尼克号乘客年龄预测时,想把自己的模型和简单均值填充法做对比。一开始我用mean_absolute_error(actual_age, mean_age_list)计算误差,但因为我的模型是用GridSearchCV构建的,觉得用交叉验证来评估均值方法更严谨。但cross_val_score要求标准的Scikit-learn Estimator,所以我自定义了一个只返回训练集目标均值的Estimator:

class MeanModel(BaseEstimator):
    def fit(self,X,y):
        self.y = y
        
    def predict(self,X):
        return np.full(X.shape[0], self.y.mean()) 

cross_val_score(MeanModel(), age_prediction_data, age_target_data, cv=10, scoring="neg_mean_absolute_error")

我的疑问是:

  • 是否有更便捷的方法实现这个流程?
  • 每次用交叉验证对比模型和简单均值方法时,都需要自定义Estimator吗?
  • 该如何将模型与“简单均值模型”对比?

解决方案与建议

1. 更便捷的替代方法:用DummyRegressor

Scikit-learn已经内置了专门的基准模型类DummyRegressor,完全不需要自己写Estimator。它支持多种基准策略,其中strategy="mean"就是返回训练集目标的均值,正好满足你的需求。

直接用它替换自定义的MeanModel就行:

from sklearn.dummy import DummyRegressor
from sklearn.model_selection import cross_val_score

# 初始化均值基准模型
dummy_mean = DummyRegressor(strategy="mean")
# 交叉验证评估
scores = cross_val_score(dummy_mean, age_prediction_data, age_target_data, cv=10, scoring="neg_mean_absolute_error")

除了mean,它还支持median(中位数)、constant(指定常数)等策略,灵活度很高。

2. 不需要每次自定义Estimator

有了DummyRegressor,你完全不用每次重复写自定义类。不管是回归任务的均值/中位数基准,还是分类任务的DummyClassifier(比如多数类基准),Scikit-learn都提供了现成的工具,直接调用就行。

3. 模型与均值基准的对比方法

对比时,核心是把两个模型的交叉验证结果放在一起统计分析:

  • 数值对比:分别计算两个模型交叉验证得分的均值和标准差,比如:
    # 你的模型的交叉验证得分(假设已经定义了your_model)
    your_scores = cross_val_score(your_model, age_prediction_data, age_target_data, cv=10, scoring="neg_mean_absolute_error")
    
    # 基准模型的得分
    dummy_scores = cross_val_score(dummy_mean, age_prediction_data, age_target_data, cv=10, scoring="neg_mean_absolute_error")
    
    # 打印统计结果
    print(f"你的模型MAE均值: {-your_scores.mean():.2f} (±{your_scores.std():.2f})")
    print(f"均值基准MAE均值: {-dummy_scores.mean():.2f} (±{dummy_scores.std():.2f})")
    
    注意:因为scoring="neg_mean_absolute_error"返回的是负数,所以取反得到真实MAE值。
  • 可视化对比:用箱线图把两个模型的交叉验证得分分布画出来,直观展示差异:
    import matplotlib.pyplot as plt
    import seaborn as sns
    import pandas as pd
    
    scores_df = pd.DataFrame({
        "模型": ["你的模型"]*10 + ["均值基准"]*10,
        "负MAE得分": list(your_scores) + list(dummy_scores)
    })
    
    sns.boxplot(x="模型", y="负MAE得分", data=scores_df)
    plt.title("模型与均值基准的交叉验证得分对比")
    plt.show()
    
    得分越高(越接近0),说明MAE越小,模型效果越好。
  • 统计检验:如果想确认两个模型的差异是否显著,可以用配对t检验,判断你的模型是否真的比基准模型表现更好:
    from scipy.stats import ttest_rel
    
    t_stat, p_value = ttest_rel(your_scores, dummy_scores)
    print(f"配对t检验结果:t={t_stat:.2f}, p值={p_value:.4f}")
    
    如果p值小于0.05,说明你的模型和均值基准的差异在统计上是显著的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:07:28