我正在尝试使用来自 Kaggle 的数据集进行房价预测。
这是我的代码
library(ggplot2)dataset=read.csv('train(1).csv')dataset_test=read.csv('test(1).csv')dataset_test$SalePrice<-0#testsummary(comb$MSZoning)#testendcomb=rbind(dataset,dataset_test)#str(dataset)#test#colSums(is.na(comb))#testend#colnames(comb)[colSums(is.na(comb)) > 0]sub_int_cols=Filter(is.integer, comb)sub_factor_cols=Filter(is.factor, comb)names_na_fac_col=colnames(sub_factor_cols)[colSums(is.na(sub_factor_cols)) > 0]names_na_int_col=colnames(sub_int_cols)[colSums(is.na(sub_int_cols)) > 0]#dataset[]=lapply(dataset, function(x){if(is.factor(x)) as.character(x) else x})for(i in 1:length(names_na_fac_col)){ comb[[names_na_fac_col[i]]]=as.character(comb[[names_na_fac_col[i]]])}sub_chr_cols=Filter(is.character,comb)names_chr_col=colnames(sub_chr_cols)for(i in 1:length(names_chr_col)){ comb[[names_chr_col[i]]]=ifelse(is.na(comb[[names_chr_col[i]]]), "NA", comb[[names_chr_col[i]]])}for(i in 1:length(names_chr_col)){ comb[[names_chr_col[i]]]=as.factor(comb[[names_chr_col[i]]])}#correctfor(i in 1:length(names_na_int_col)){ comb[[names_na_int_col[i]]]=ifelse(is.na(comb[[names_na_int_col[i]]]), 0, comb[[names_na_int_col[i]]])}# for(i in 1:length(names_na_fac_col)){# print(summary(comb[[names_na_fac_col[i]]]))# }library('binst')#dataset$YearBuilt=create_bins(dataset$YearBuilt,# seq(min(dataset$YearBuilt),max(dataset$YearBuilt),10))comb$YearRemodAdd=create_bins(comb$YearRemodAdd, seq(min(comb$YearRemodAdd),max(comb$YearRemodAdd),10))#summary(comb$YearRemodAdd)comb$YrSold=create_bins(comb$GarageYrBlt, c(1910,1920,1930,1940,1950,1960,1970,1980,1990,2000,2010))data_pp=subset(comb, Id %in% seq(1,1460,1))data_test_pp=subset(comb, Id %in% seq(1461,2919,1))data_pp=data_pp[,-1]#----------------------------------regressor=lm(SalePrice~.,data = data_pp)summary(regressor)data_test_pp1=data_test_pp[,-1]res=predict(regressor,newdata = data_test_pp1)
数据集中有81列用于训练线性回归模型。问题在于Kaggle的数据集分为两部分(分别是训练集和测试集)。这两部分都有一些缺失值(NA),这些在预处理中得到了处理(如上面的代码所示)。训练集和测试集最初是合并在一起的。然后所有因子列都被转换为字符列。接着在这些列中,缺失值被填充为”NA”。最后,这些列再次被转换为因子列。之后,训练集和测试集被分开(它们保持了原始文件中的状态,没有使用分割函数)。当我尝试运行预测函数时,我得到了错误信息“因子 xyz 出现了新的层次 NA”。问题在于,例如,’MSZoning’列在训练数据集中没有NA因子,但在测试集中某些行’MSZoning’是NA因子。因此,模型没有被训练来预测’MSZoning’为NA的结果值(模型没有被训练识别’MSZoning’为NA)。我不能简单地从测试集中删除这些行,因为比赛需要测试集中的所有行。有什么方法可以解决这个问题,并在不删除任何行或列的情况下对测试集中的所有行进行预测吗?
提前感谢。
回答:
你没有NA值,你有一些单元格里包含了文本“NA”。
是这一段代码引入了”NA”(不是NA值):
for(i in 1:length(names_chr_col)){ comb[[names_chr_col[i]]]=ifelse(is.na(comb[[names_chr_col[i]]]), "NA", comb[[names_chr_col[i]]])}
问题在于,你为每个有缺失值的因子添加了一个新的层次”NA”。然而,由于你的训练数据中没有名为”NA”的因子,当它出现在测试数据中时,你的模型不知道该如何处理它。(为了帮助你理解为什么未见过的类别会成为问题:想象你是一名兽医,只知道猫和狗。如果有人带给你一只动物,说“这是一头猪!”你就不知道该怎么处理它了。)
作为第一步,我建议用该因子的最常见值替换NA值,而不是创建因子的新层次。
我写了一个笔记本,它详细解释了问题所在,并展示了如何替换值。