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值。 - 可视化对比:用箱线图把两个模型的交叉验证得分分布画出来,直观展示差异:
得分越高(越接近0),说明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() - 统计检验:如果想确认两个模型的差异是否显著,可以用配对t检验,判断你的模型是否真的比基准模型表现更好:
如果p值小于0.05,说明你的模型和均值基准的差异在统计上是显著的。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}")
内容的提问来源于stack exchange,提问作者jxqbbb
相关产品推荐
相关产品推荐

