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

基于k折交叉验证的线性模型子集选择拟合优度报错求助

问题分析与解决方案

为什么会出现这个错误?

leaps包的regsubsets()函数返回的是**regsubsets类对象**,但R的基础包和该包本身并没有为这个类实现predict()方法。当你直接调用predict(best.fit, ...)时,R找不到对应的处理逻辑,就会抛出no applicable method for 'predict' applied to an object of class "regsubsets"这个报错。

解决办法:自定义适配regsubsets的predict函数

我们可以自己写一个专门处理regsubsets对象的预测函数,核心是提取对应特征子集的系数,再结合测试集的特征计算预测值。

修改后的完整代码

library(leaps)
library(ISLR)

# 自定义适用于regsubsets类的predict函数
predict.regsubsets <- function(object, newdata, id, ...) {
  # 提取模型的原始公式
  form <- as.formula(object$call[[2]])
  # 根据公式生成测试集的特征矩阵
  mat <- model.matrix(form, newdata)
  # 获取对应特征子集的系数
  coefi <- coef(object, id = id)
  # 计算预测值:仅使用选中的特征与对应系数做矩阵乘法
  mat[, names(coefi)] %*% coefi
}

k=10
set.seed(1)
folds=sample(1:k,nrow(Hitters),replace=TRUE)
cv.errors=matrix(NA,k,19, dimnames=list(NULL, paste(1:19)))

for(j in 1:k){
  best.fit=regsubsets(Salary~.,data=Hitters[folds!=j,],nvmax=19)
  for(i in 1:19){
    pred=predict(best.fit,Hitters[folds==j,],id=i)
    cv.errors[j,i]=mean( (Hitters$Salary[folds==j]-pred)^2)
  }
}

mean.cv.errors=apply(cv.errors,2,mean)
mean.cv.errors

par(mfrow=c(1,1))
plot(mean.cv.errors,type='b')

reg.best=regsubsets(Salary~.,data=Hitters, nvmax=19)
coef(reg.best,11)

代码关键部分解释

  1. 自定义predict.regsubsets函数:

    • 从regsubsets对象中提取原始模型公式,保证测试集特征和训练集结构一致
    • 用model.matrix()生成测试集的特征矩阵,自动处理因子变量、截距项等细节
    • 通过coef(object, id=id)精准提取第i个特征子集的系数
    • 最后只使用选中的特征列与系数做矩阵乘法,得到预测值
  2. 原有逻辑保留:
    你原来的交叉验证循环、误差计算、绘图以及最优子集系数提取的代码都不需要改动,自定义函数会自动适配regsubsets对象的预测需求。

效果验证

运行修改后的代码,你应该能顺利得到交叉验证的误差均值,成功绘制误差曲线,最后提取出包含11个特征的最优子集的系数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:12:53