假设我的数据集是一个填充了分类变量的100 x 3
矩阵。我希望对响应变量进行二元分类。我们用以下代码创建一个数据集:
set.seed(2013)y <- as.factor(round(runif(n=100,min=0,max=1),0))var1 <- rep(c("red","blue","yellow","green"),each=25)var2 <- rep(c("shortest","short","tall","tallest"),25)df <- data.frame(y,var1,var2)
数据看起来像这样:
> head(df) y var1 var21 0 red shortest2 1 red short3 1 red tall4 1 red tallest5 0 red shortest6 1 red short
我尝试在这组数据上使用两种不同的方法进行随机森林和Adaboost分析。第一种方法是直接使用原始数据:
> library(randomForest)> randomForest(y~var1+var2,data=df,ntrees=500)Call: randomForest(formula = y ~ var1 + var2, data = df, ntrees = 500) Type of random forest: classification Number of trees: 500No. of variables tried at each split: 1 OOB estimate of error rate: 44%Confusion matrix: 0 1 class.error0 29 22 0.43137251 22 27 0.4489796----------------------------------------------------> library(ada)> ada(y~var1+var2,data=df)Call:ada(y ~ var1 + var2, data = df)Loss: exponential Method: discrete Iteration: 50 Final Confusion Matrix for Data: Final PredictionTrue value 0 1 0 34 17 1 16 33Train Error: 0.33 Out-Of-Bag Error: 0.33 iteration= 11 Additional Estimates of number of iterations:train.err1 train.kap1 10 16
第二种方法是将数据集转换为宽格式,并将每个类别视为一个变量。我这样做的原因是我的实际数据集中var1和var2有500多个因子,结果树分区总是将500个类别分为两个分支。这样会丢失很多信息。转换数据的方法如下:
id <- 1:100library(reshape2)tmp1 <- dcast(melt(cbind(id,df),id.vars=c("id","y")),id+y~var1,fun.aggregate=length)tmp2 <- dcast(melt(cbind(id,df),id.vars=c("id","y")),id+y~var2,fun.aggregate=length)df2 <- merge(tmp1,tmp2,by=c("id","y"))
新的数据看起来像这样:
> head(df2) id y blue green red yellow short shortest tall tallest1 1 0 0 0 2 0 0 2 0 02 10 1 0 0 2 0 2 0 0 03 100 0 0 2 0 0 0 0 0 24 11 0 0 0 2 0 0 0 2 05 12 0 0 0 2 0 0 0 0 26 13 1 0 0 2 0 0 2 0 0
我对这个新数据集应用随机森林和Adaboost:
> library(randomForest)> randomForest(y~blue+green+red+yellow+short+shortest+tall+tallest,data=df2,ntrees=500)Call: randomForest(formula = y ~ blue + green + red + yellow + short + shortest + tall + tallest, data = df2, ntrees = 500) Type of random forest: classification Number of trees: 500No. of variables tried at each split: 2 OOB estimate of error rate: 39%Confusion matrix: 0 1 class.error0 32 19 0.37254901 20 29 0.4081633----------------------------------------------------> library(ada)> ada(y~blue+green+red+yellow+short+shortest+tall+tallest,data=df2)Call:ada(y ~ blue + green + red + yellow + short + shortest + tall + tallest, data = df2)Loss: exponential Method: discrete Iteration: 50 Final Confusion Matrix for Data: Final PredictionTrue value 0 1 0 36 15 1 20 29Train Error: 0.35 Out-Of-Bag Error: 0.33 iteration= 26 Additional Estimates of number of iterations:train.err1 train.kap1 5 10
两种方法的结果不同。随着每个变量(即var1
和var2
)引入更多级别,这种差异更加明显。我的问题是,既然我们使用的是完全相同的数据,为什么结果会不同?我们应该如何解释这两种方法的结果?哪一种更可靠?
回答:
虽然这两个模型看起来相同,但它们在本质上是不同的——在第二个模型中,你隐式地包含了给定观察可能具有多种颜色和多种高度的可能性。两种模型公式之间的正确选择将取决于你现实世界观察的特征。如果这些特征是互斥的(即,每个观察只有一个颜色和一个高度),那么第一个模型公式将是正确的选择。然而,如果一个观察可以是蓝色和绿色,或者任何其他颜色组合,你可以使用第二个公式。从你原始数据的直觉来看,似乎第一个更合适(即,一个观察怎么会有多个高度?)。
另外,为什么你在df2中将逻辑变量列编码为0和2,而不是0/1?我想知道这是否会根据数据是如何被编码为因子或数值而影响拟合结果。