使用rpart对新因子(分类)变量进行预测

时间:2015-03-23 15:18:59

标签: r machine-learning prediction categorical-data rpart

我正在使用R练习机器学习。我正在使用rpart方法进行训练。数据是来自UCI的成人数据集。链接如下

http://archive.ics.uci.edu/ml/datasets/Adult

#Get the data    
adultData <- read.table("adult.data", header = FALSE, sep = ",")
adultName <- read.csv("adult.name", header = TRUE, sep = ",", stringsAsFactors = FALSE)
names(adultData) <- names(adultName)

为了简化练习,我只选择了几个属性,并将数据集减少到仅20%

selected <- c("age", "education", "marital.status", "relationship", "sex", "hours.per.week", "salary")
adultData <- subset(adultData, select = selected)
trainIndex = createDataPartition(adultData$salary, p=0.20, list=FALSE)
training = adultData[ trainIndex, ]

使用&#34; rpart&#34;大约需要一分钟才能适应模型。 (&#34; gbm&#34;或&#34; rf&#34;)慢一些。

set.seed(33833)
modFit <- train(salary ~ ., method = "rpart", data=training)

问题来自我对新数据值的预测。我创建了一个新的数据框

a <- data.frame(age = 40, education = "Bachelors", marital.status = "Divorced", relationship = "Wife", sex = "Female", hours.per.week = 40)
predict(modFit, newdata = a)

它返回错误&#34;教育有了新的水平&#34;。

我知道问题来自那些分类(因素)变量。不知何故,他们不承认&#34; Bachelors&#34;作为他们已经拥有的因素,但新的字符串(新因素)。

1 个答案:

答案 0 :(得分:3)

问题源于数据清理不畅

当我下载数据时,我发现了一个与R中的因素相同的问题: 标签有额外的空间,因此,当你调用标签时(例如,你的例子中为“单身汉”),系统无法识别它,因为在这个级别中,这个级别有一个额外的空间:

“单身汉”

你可以通过调用因子:水平(教育)

来看到这一点

您可以通过将strip.white参数设置为TRUE

来删除读取调用中的空格

如果您以标准方式上传数据集,则可以看到因素'标签有额外空间

# Not Run 
#  adultData <- read.csv2("AdultDataRenamed.csv", header = TRUE)

# levels(adultData$education)

 # [1] " 10th"         " 11th"         " 12th"         " 1st-4th"     
 # [5] " 5th-6th"      " 7th-8th"      " 9th"          " Assoc-acdm"  
 # [9] " Assoc-voc"    " Bachelors"    " Doctorate"    " HS-grad"     
# [13] " Masters"      " Preschool"    " Prof-school"  " Some-college"

如果您使用strip.white = TRUE上传数据集,则可以看到因素'标签没有额外空间

# Not Run 
# adultData <- read.csv2("AdultDataRenamed.csv", header = TRUE, strip.white = TRUE)

# levels(adultData$education)

 # [1] "10th"         "11th"         "12th"         "1st-4th"      "5th-6th"     
 # [6] "7th-8th"      "9th"          "Assoc-acdm"   "Assoc-voc"    "Bachelors"   
# [11] "Doctorate"    "HS-grad"      "Masters"      "Preschool"    "Prof-school" 
# [16] "Some-college"

我通过上传干净的数据集来重现这个例子,我已经重命名了

# Not Run 
# adultData <- read.csv2("AdultDataRenamed.csv", header = TRUE, strip.white = TRUE)

数据集太宽,无法在此发布;它可以从上面链接中的说明轻松复制。我的干净数据集可以从这里下载http://www.insular.it/?wpdmact=process&did=OC5ob3RsaW5r

始终查看数据

dim(adultData)
head(adultData)
str(adultData)

调用您需要的库

library(rpart)
library(caret)

我选择了您选择的相同属性,并且我已将数据集减少到仅40%(可以接受培训)

selected <- c("age", "education", "marital.status", "relationship", "sex", "hours.per.week", "salary")
adultData <- subset(adultData, select = selected)
trainIndex = createDataPartition(adultData$salary, p=0.40, list=FALSE)
training = adultData[ trainIndex, ]

我还添加了一个测试集

test = adultData[ -trainIndex, ]

模型拟合

set.seed(33833)
modFit <- train(salary ~ ., method = "rpart", data=training)

总体准确度

prediction <- predict(modFit, newdata=test)

tab <- table(prediction, test$salary)

sum(diag(tab))/sum(tab)

使用插入符号包进行更好的测试

rpartPred<-predict(modFit,test)

confusionMatrix(rpartPred,test$salary) 

绘制模型(不太清楚)

library(rattle)

fancyRpartPlot(modFit$finalModel)

替代

library(partykit)

finalModel <-as.party(modFit$finalModel)
plot(finalModel)

使用您指定的新数据值进行预测

a <- data.frame(age = 40, education = "Bachelors", marital.status = "Divorced", relationship = "Wife", sex = "Female", hours.per.week = 40)

predict(modFit, newdata = a)