R语言用e1071库做SVM回归时出现test data does not match model错误
e1071 SVM回归预测报错"test data does not match model!"的原因及解决
问题场景
使用R的e1071库构建SVM回归模型:
model = svm(deflated_price~year+month+beds+room_in_apt+nhood, data = train_sample)
模型拟合正常,summary(model)输出符合预期,但执行预测时:
y_hat = predict(model, newdata = test_sample)
触发错误:test data does not match model!
训练集与测试集的结构信息如下:
train_sample结构
str(train_sample) 'data.frame': 48752 obs. of 6 variables: $ year : Factor w/ 19 levels "2000","2001",..: 5 17 5 17 14 13 16 6 7 17 ... $ nhood : chr "sea cliff" "hayes valley" "pacific heights" "noe valley" ... $ beds : chr "2" "1" "3" "1" ... $ room_in_apt : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ... $ month : Factor w/ 12 levels "1","2","3","4",..: 9 2 10 10 12 3 11 1 2 3 ... $ deflated_price: num 565 920 3055 616 1399 ...
test_sample结构
str(test_sample) 'data.frame': 5000 obs. of 5 variables: $ year : Factor w/ 19 levels "2000","2001",..: 5 5 5 5 5 6 5 6 8 5 ... $ nhood : chr "alamo square" "alamo square" "alamo square" "alamo square" ... $ beds : chr "0" "2" "1" "1" ... $ room_in_apt: Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ... $ month : Factor w/ 12 levels "1","2","3","4",..: 6 6 11 8 7 1 8 3 9 9 ...
错误原因
核心问题是分类变量的类型/水平不匹配,具体涉及两个变量:
beds变量:训练集里的beds是字符型,取值为"2","1","3"等,但测试集出现了训练集没有的"0"。模型拟合时,字符型变量会被自动转为因子,测试集的新因子水平("0")不在训练集的水平范围内,导致预测失败。nhood变量:同样为字符型,测试集里的"alamo square"在训练集的样本中从未出现过,属于模型未见过的新水平,无法被模型处理。- 额外注意:即使手动添加
deflated_price字段,也无法解决分类变量水平不匹配的核心问题。
解决方法
方法1:统一转换为因子并对齐水平
先将训练集的字符型变量转为因子,再用训练集的水平约束测试集的转换,确保测试集的因子水平是训练集的子集:
# 处理训练集的分类变量 train_sample$beds <- factor(train_sample$beds) train_sample$nhood <- factor(train_sample$nhood) # 用训练集的水平转换测试集,未出现的水平转为NA test_sample$beds <- factor(test_sample$beds, levels = levels(train_sample$beds)) test_sample$nhood <- factor(test_sample$nhood, levels = levels(train_sample$nhood)) # 重新拟合模型并预测 model <- svm(deflated_price~year+month+beds+room_in_apt+nhood, data = train_sample) y_hat <- predict(model, newdata = test_sample)
对于转为NA的样本,可选择删除或合并到训练集的某个通用水平(如"other")。
方法2:将beds转为数值型
beds代表床的数量,本质是数值变量,转为数值型可彻底避免因子水平问题:
# 转换为数值型 train_sample$beds <- as.numeric(train_sample$beds) test_sample$beds <- as.numeric(test_sample$beds) # 重新拟合模型并预测 model <- svm(deflated_price~year+month+beds+room_in_apt+nhood, data = train_sample) y_hat <- predict(model, newdata = test_sample)
此方法更贴合变量的业务含义,推荐优先使用。
内容的提问来源于stack exchange,提问作者Phil
相关产品推荐
相关产品推荐

