R语言Support Vector Machine模型predict返回预测值全为0问题求助
SVM预测结果全为0问题排查方案
核心错误点
- 数据集拆分逻辑错误:
sample.split()的第一个参数要求传入响应变量列而非整个数据集,直接传入ult会导致拆分逻辑完全失效,训练集和测试集的分布可能完全不符合随机抽样要求 - 数据预处理顺序错误:你在拆分训练集、测试集之后才修改
ult$dns为因子类型,这就导致提前拆分出来的training_set里的dns列还是修改前的类型,和测试集的dns列因子水平不匹配,模型训练时标签逻辑异常 - 列索引依赖风险:你使用
test_set[,-7]、test_set[,7]通过数字索引取特征和标签,一旦数据集列顺序发生变化就会出现特征、标签不匹配的问题,很容易导致预测时输入的特征完全错误 - 缺少SVM必要的特征预处理:SVM模型对特征尺度高度敏感,若未对数值特征做标准化/归一化处理,大尺度特征会完全主导模型计算,模型无法学到有效分类规律,最终只会输出占比最高的类别
- 语法小问题:你提供的代码中
table语句缺少右括号,若实际运行代码也存在该问题会导致结果输出异常
修复步骤
- 调整预处理顺序,先处理标签,再拆分数据集:
library(caTools) library(e1071) # 提前加载svm所在的依赖包 set.seed(123) # 先处理标签列 ult$dns<-factor(ult$dns, labels = make.names(levels(ult$dns))) # 拆分时传入响应变量列保证分层抽样 split<-sample.split(ult$dns, SplitRatio = 0.8) training_set<-subset(ult, split == TRUE) test_set<-subset(ult, split == FALSE)
- 补充特征标准化处理:
# 对除标签外的所有数值列做标准化,适配SVM对特征尺度的要求 feature_cols <- which(names(training_set)!="dns") training_set[,feature_cols] <- scale(training_set[,feature_cols]) test_set[,feature_cols] <- scale(test_set[,feature_cols])
- 修改模型训练和预测代码,用列名替代数字索引:
svm.model.ult <- svm(dns ~ ., data = training_set, type = "C-classification", cost = 1,gamma = 0.125, cross =10) # 预测时直接传入测试集,模型会自动匹配特征列 svm.pred.ult <- predict(svm.model.ult, test_set) # 生成混淆矩阵 table(pred = svm.pred.ult, true = test_set$dns)
- 若修复后还是全预测同一类别,先验证训练集标签分布:
table(training_set$dns)
如果某一类占比超过90%属于类别不平衡问题,需要调整svm()的class.weight参数给少数类更高权重,或者通过网格搜索调整cost、gamma参数优化模型分类效果。
内容的提问来源于stack exchange,提问作者Callum Pet
相关产品推荐
相关产品推荐

