基于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)
代码关键部分解释
自定义
predict.regsubsets函数:- 从
regsubsets对象中提取原始模型公式,保证测试集特征和训练集结构一致 - 用
model.matrix()生成测试集的特征矩阵,自动处理因子变量、截距项等细节 - 通过
coef(object, id=id)精准提取第i个特征子集的系数 - 最后只使用选中的特征列与系数做矩阵乘法,得到预测值
- 从
原有逻辑保留:
你原来的交叉验证循环、误差计算、绘图以及最优子集系数提取的代码都不需要改动,自定义函数会自动适配regsubsets对象的预测需求。
效果验证
运行修改后的代码,你应该能顺利得到交叉验证的误差均值,成功绘制误差曲线,最后提取出包含11个特征的最优子集的系数。
内容的提问来源于stack exchange,提问作者SHW
相关产品推荐
相关产品推荐

