cross_val_score与GridSearchCV计算得分异常问题求助
问题分析与解决方案
你的问题核心在于混淆了两种完全不同的模型评估场景,导致对cross_val_score和GridSearchCV的结果产生误解。我们一步步拆解:
1. 你手动测试的本质:数据泄露
你之前手动运行的代码:
lr=LinearRegression() lm=lr.fit(X,y) # 用**全部数据集**拟合模型 lmscore_test=lm.score(X_test,y_test) # 测试得分0.626
这里的模型在拟合时已经见过测试集(X_test属于整个X的一部分),所以这个测试得分是数据泄露后的结果,反映的不是模型的真实泛化能力,而是模型对整个数据集的拟合效果。
2. cross_val_score与GridSearchCV的正确逻辑
cross_val_score和GridSearchCV的核心是交叉验证:对于每个fold,它们会:
- 克隆一个未拟合的模型实例
- 用当前fold的训练子集(你的例子里是前15个样本)拟合这个模型
- 用当前fold的测试子集(后6个样本)评估模型
这才是评估模型泛化能力的正确方式——模型在拟合时完全没见过测试数据,得分反映的是模型对未知数据的预测能力。
3. 为什么结果差异巨大?
你看到的r2 = -1.23e+01,其实是用前15个样本训练的LinearRegression模型,在后6个样本上的真实泛化得分。你可以手动验证这一点:
lr_train_only = LinearRegression().fit(X_train, y_train) print(lr_train_only.score(X_test, y_test))
这个结果应该和cross_val_score、GridSearchCV输出的测试得分完全一致。
4. 修正你的代码小问题
- 不需要传入已拟合的模型给
cross_val_score,直接传未拟合的estimator即可(cross_val_score会自动克隆并重新训练):cv_scores = cross_val_score(LinearRegression(), X, y, cv=kf) GridSearchCV中的return_train_score='true'应该改为布尔值True(字符串虽然能运行,但不符合参数规范):gridsearch=GridSearchCV(p, grid_parameters, verbose=3,cv=kf,scoring=scoring,return_train_score=True,refit='r_squared')
总结
你之前的手动测试属于数据泄露场景,得分不能代表模型的真实泛化能力;而cross_val_score和GridSearchCV给出的是正确的泛化得分,虽然看起来很差,但这是模型在未见过的测试数据上的真实表现。如果这个得分不符合预期,你需要从特征工程、模型选择或数据分布等方面入手优化,而不是怀疑交叉验证的逻辑。
内容的提问来源于stack exchange,提问作者Luca Fichera
相关产品推荐
相关产品推荐

