随机森林可以用于多元线性回归中的特征选择吗?

机器算法验证 回归 机器学习 特征选择 随机森林 回归策略
2022-02-06 06:30:43

由于RF可以处理非线性但不能提供系数,使用随机森林收集最重要的特征然后将这些特征插入多元线性回归模型以获得它们的系数是否明智?

4个回答

由于 RF 可以处理非线性但不能提供系数,使用随机森林收集最重要的特征,然后将这些特征插入多元线性回归模型以解释它们的符号是否明智?

我将 OP 的单句问题解释为 OP 希望了解以下分析管道的可取性:

  1. 将随机森林拟合到某些数据
  2. 通过(1)中的一些可变重要性度量,选择一个高质量特征的子集。
  3. 使用 (2) 中的变量,估计线性回归模型。这将使 OP 可以访问 OP 注释 RF 无法提供的系数。
  4. 从 (3) 中的线性模型,定性地解释系数估计的符号。

我不认为这个管道会完成你想要的。在随机森林中重要的变量不一定与结果具有任何线性加法关系。这句话应该不足为奇:这就是随机森林在发现非线性关系方面如此有效的原因。

这是一个例子。我创建了一个包含 10 个噪声特征、两个“信号”特征和一个圆形决策边界的分类问题。

set.seed(1)
N  <- 500
x1 <- rnorm(N, sd=1.5)
x2 <- rnorm(N, sd=1.5)

y  <- apply(cbind(x1, x2), 1, function(x) (x%*%x)<1)

plot(x1, x2, col=ifelse(y, "red", "blue"))
lines(cos(seq(0, 2*pi, len=1000)), sin(seq(0, 2*pi, len=1000))) 

在此处输入图像描述

而当我们应用 RF 模型时,我们并不惊讶地发现这些特征很容易被模型挑选为重要的。(注意:这个模型根本没有调整

x_junk   <- matrix(rnorm(N*10, sd=1.5), ncol=10)
x        <- cbind(x1, x2, x_junk)
names(x) <- paste("V", 1:ncol(x), sep="")

rf <- randomForest(as.factor(y)~., data=x, mtry=4)
importance(rf)

    MeanDecreaseGini
x1         49.762104
x2         54.980725
V3          5.715863
V4          5.010281
V5          4.193836
V6          7.147988
V7          5.897283
V8          5.338241
V9          5.338689
V10         5.198862
V11         4.731412
V12         5.221611

但是当我们只选择这两个有用的特征时,得到的线性模型很糟糕。

summary(badmodel <- glm(y~., data=data.frame(x1,x2), family="binomial"))

总结的重要部分是残余偏差和零偏差的比较。我们可以看到,该模型基本上没有“移动”偏差。此外,系数估计值基本上为零。

Call:
glm(formula = as.factor(y) ~ ., family = "binomial", data = data.frame(x1, 
    x2))

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-0.6914  -0.6710  -0.6600  -0.6481   1.8079  

Coefficients:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept) -1.398378   0.112271 -12.455   <2e-16 ***
x1          -0.020090   0.076518  -0.263    0.793    
x2          -0.004902   0.071711  -0.068    0.946    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 497.62  on 499  degrees of freedom
Residual deviance: 497.54  on 497  degrees of freedom
AIC: 503.54

Number of Fisher Scoring iterations: 4

是什么导致了这两种模型之间的巨大差异?嗯,很明显,我们试图学习的决策边界不是两个“信号”特征的线性函数。显然,如果您在估计回归之前知道决策边界的函数形式,您可以应用一些转换以回归可以发现的方式对数据进行编码......(但我从来不知道前方边界的形式由于在这种情况下我们只处理两个信号特征,即在类标签中没有噪声的合成数据集,因此类之间的边界在我们的图中非常明显。但在处理真实数量的真实数据时,它就不那么明显了。

此外,一般来说,随机森林可以将不同的模型拟合到不同的数据子集。在一个更复杂的例子中,从一个情节中根本看不出发生了什么,建立一个具有相似预测能力的线性模型将更加困难。

因为我们只关心二维,所以我们可以制作一个预测表面。正如预期的那样,随机模型了解到原点周围的邻域很重要。

M                 <- 100
x_new             <- seq(-4,4, len=M)
x_new_grid        <- expand.grid(x_new, x_new)
names(x_new_grid) <- c("x1", "x2")
x_pred            <- data.frame(x_new_grid, matrix(nrow(x_new_grid)*10, ncol=10))
names(x_pred)     <- names(x)

y_hat             <- predict(object=rf, newdata=x_pred, "vote")[,2]

library(fields)
y_hat_mat         <- as.matrix(unstack(data.frame(y_hat, x_new_grid), y_hat~x1))

image.plot(z=y_hat_mat, x=x_new, y=x_new, zlim=c(0,1), col=tim.colors(255), 
           main="RF Prediction surface", xlab="x1", ylab="x2")

在此处输入图像描述

正如我们糟糕的模型输出所暗示的那样,减少变量逻辑回归模型的预测表面基本上是平坦的。

在此处输入图像描述

bad_y_hat     <- predict(object=badmodel, newdata=x_new_grid, type="response")
bad_y_hat_mat <- as.matrix(unstack(data.frame(bad_y_hat, x_new_grid), bad_y_hat~x1))
image.plot(z=bad_y_hat_mat, x=x_new, y=x_new, zlim=c(0,1), col=tim.colors(255), 
           main="Logistic regression prediction surface", xlab="x1", ylab="x2")

HongOoi 指出,类成员资格不是特征的线性函数,而是线性函数处于变换之下。因为决策边界是 1=X12+X22,如果我们对这些特征进行平方,我们将能够建立一个更有用的线性模型。这是故意的。虽然 RF 模型可以在这两个特征中找到信号而无需转换,但分析师必须更加具体才能在 GLM 中获得类似有用的结果。也许这对 OP 来说就足够了:为 2 个特征找到一组有用的转换比 12 个更容易。但我的观点是,即使转换会产生有用的线性模型,RF 特征重要性也不会单独建议转换。

@Sycorax 的回答太棒了。除了与模型拟合相关的问题的那些充分描述的方面之外,还有另一个原因不追求多步骤过程,例如运行随机森林、套索或弹性网络来“学习”哪些特征可以提供给传统回归。普通回归不会知道在随机森林或其他方法的开发过程中正确进行的惩罚,并且会拟合在预测中出现严重偏差的未惩罚效应. 这与运行逐步变量选择并报告最终模型而不考虑它是如何到达的没有什么不同。

正确执行的随机森林应用于更“适合随机森林”的问题,可以作为过滤器来去除噪声,并使结果更适合作为其他分析工具的输入。

免责声明:

  • 是“银弹”吗?没门。里程会有所不同。它在它工作的地方工作,而不是在其他地方。
  • 有没有办法让你错误地粗暴地使用它并获得垃圾到巫毒域中的答案?完全正确。像每个分析工具一样,它也有局限性。
  • 如果你舔青蛙,你的口气会不会像青蛙一样?可能。我在那里没有经验。

我必须向制作“蜘蛛”的“偷窥”发出“大喊”。链接)他们的示例问题告知了我的方法。链接)我也喜欢 Theil-Sen 估计器,希望我能给 Theil 和 Sen 提供道具。

我的回答不是关于如何弄错,而是关于如果你大部分都正确的话它会如何工作。虽然我使用“微不足道”的噪音,但我希望您考虑“非微不足道”或“结构化”噪音。

随机森林的优势之一是它适用于高维问题的能力。我无法以清晰的视觉方式显示 20k 列(又名 20k 维空间)。这不是一件容易的事。但是,如果您有一个 20k 维的问题,那么当大多数其他人的“面孔”一塌糊涂时,随机森林可能是一个很好的工具。

这是使用随机森林从信号中去除噪声的示例。

#housekeeping
rm(list=ls())

#library
library(randomForest)

#for reproducibility
set.seed(08012015)

#basic
n <- 1:2000
r <- 0.05*n +1 
th <- n*(4*pi)/max(n)

#polar to cartesian
x1=r*cos(th) 
y1=r*sin(th)

#add noise
x2 <- x1+0.1*r*runif(min = -1,max = 1,n=length(n))
y2 <- y1+0.1*r*runif(min = -1,max = 1,n=length(n))

#append salt and pepper
x3 <- runif(min = min(x2),max = max(x2),n=length(n)/2)
y3 <- runif(min = min(y2),max = max(y2),n=length(n)/2)

x4 <- c(x2,x3)
y4 <- c(y2,y3)
z4 <- as.vector(matrix(1,nrow=length(x4)))

#plot class "A" derivation
plot(x1,y1,pch=18,type="l",col="Red", lwd=2)
points(x2,y2)
points(x3,y3,pch=18,col="Blue")
legend(x = 65,y=65,legend = c("true","sampled","false"),
col = c("Red","Black","Blue"),lty = c(1,-1,-1),pch=c(-1,1,18))

让我描述一下这里发生了什么。下图显示了“1”类的训练数据。类“2”在相同的域和范围内是均匀随机的。你可以看到“1”的“信息”主要是一个螺旋,但已经被“2”的材料破坏了。对于许多拟合工具来说,33% 的数据损坏可能是个问题。Theil-Sen 开始降解约 29%。链接

在此处输入图像描述

现在我们将信息分离出来,只知道噪声是什么。

#Create "B" class of uniform noise
x5 <- runif(min = min(x4),max = max(x4),n=length(x4))
y5 <- runif(min = min(y4),max = max(y4),n=length(x4))
z5 <- 2*z4 

#assemble data into frame 
data <- data.frame(c(x4,x5),c(y4,y5),as.factor(c(z4,z5)))
names(data) <- c("x","y","z")

#train random forest - I like h2o, but this is textbook Breimann
fit.rf <- randomForest(z~.,data=data,
                       ntree = 1000, replace=TRUE, nodesize = 20)
data2 <- predict(fit.rf,newdata=data[data$z==1,c(1,2)],type="response")

#separate class "1" from training data
idx1a <- which(data[,3]==1)

#separate class "1" from the predicted data
idx1b <- which(data2==1)

#show the difference in classes before and after RF based filter
plot(data[idx1a,1],data[idx1a,2])
points(data[idx1b,1],data[idx1b,2],col="Red")

这是拟合结果:

在此处输入图像描述

我真的很喜欢这个,因为它可以同时显示一个体面的方法对一个难题的优点和缺点。如果您靠近中心看,您会发现过滤较少。信息的几何规模很小,随机森林缺少这一点。它说明了第 2 类的节点数、树数和样本密度。在 (-50,-50) 附近还有一个“间隙”,并且在几个位置存在“喷射”。但是,总的来说,过滤是不错的。

比较与 SVM

这是允许与 SVM 进行比较的代码:

#now to fit to svm
fit.svm <-  svm(z~., data=data, kernel="radial",gamma=10,type = "C")

x5 <- seq(from=min(x2),to=max(x2),by=1)
y5 <- seq(from=min(y2),to=max(y2),by=1)

count <- 1
x6 <- numeric()
y6 <- numeric()
for (i in 1:length(x5)){

     for (j in 1:length(y5)){
          x6[count]<-x5[i]
          y6[count]<-y5[j]
          count <- count+1
     }
}

data4 <- data.frame(x6,y6)
names(data4) <- c("x","y")

data4$z <- predict(fit.svm,newdata=data4)

idx4 <- which(data4$z==1,arr.ind=TRUE)


plot(data4[idx4,1],data4[idx4,2],col="Gray",pch=20)
points(data[idx1b,1],data[idx1b,2],col="Blue",pch=20)
lines(x1,y1,pch=18,col="Green", lwd=2)
grid()
legend(x = 65,y=65,
       legend = c("true","from RF","From SVM"),
       col = c("Green","Blue","Gray"),lty = c(1,-1,-1),pch=c(-1,20,15),pt.cex=c(1,1,2.25))

结果如下图。

在此处输入图像描述

这是一个不错的 SVM。灰色是 SVM 与类“1”相关联的域。蓝点是 RF 与“1”类相关的样本。 基于 RF 的滤波器在没有明确施加的基础的情况下与 SVM 的性能相当。 可以看出,靠近螺旋中心的“紧密数据”被 RF 解析得更加“紧密”。在 RF 发现 SVM 没有的关联的“尾部”也存在“孤岛”。

我很开心。在没有背景的情况下,我做了一件早期的事情,也是由该领域的一位非常优秀的贡献者完成的。原作者使用“参考分布”(链接链接)。

编辑:

将随机森林应用于此模型:
虽然 user777 认为 CART 是随机森林的元素,但随机森林的前提是“弱学习器的集成聚合”。CART 是一个已知的弱学习器,但它与“集成”相去甚远。尽管在随机森林中的“集合”旨在“在大量样本的限制下”。user777 的答案,在散点图中,至少使用了 500 个样本,这说明了在这种情况下人类可读性和样本大小。人类视觉系统(本身就是一个学习者的集合)是一个了不起的传感器和数据处理器,它发现该值足以轻松处理。

如果我们甚至采用随机森林工具的默认设置,我们可以观察到前几棵树的分类误差增加的行为,并且直到大约 10 棵树才达到一棵树的水平。最初错误增长,错误减少在 60 棵树左右变得稳定。我的意思是稳定

x        <- cbind(x1, x2)
plot(rf,type="b",ylim=c(0,0.06))
grid()

产生:
在此处输入图像描述

如果不是查看“最小弱学习器”,而是查看工具默认设置的非常简短的启发式建议的“最小弱集成”,结果会有所不同。

请注意,我使用“线条”来绘制表示近似值边缘的圆圈。你可以看到它是不完美的,但比单个学习器的质量要好得多。

在此处输入图像描述

原始采样有 88 个“内部”样本。如果样本量增加(允许集成应用),那么近似的质量也会提高。具有 20,000 个样本的相同数量的学习者可以更好地拟合。

在此处输入图像描述

更高质量的输入信息还允许评估适当数量的树。收敛性检查表明,在这种特殊情况下,20 棵树是足够的最小数量,可以很好地表示数据。

在此处输入图像描述

尽管有合理的警告表明这种方法在某些情况下可能会失败,但这不应该阻止您尝试它!Breimann 报告了一个示例 ( Breimann 2001 ),即从随机森林中通过变量重要性选择特征并将它们插入逻辑回归中优于专门为逻辑回归量身定制的变量选择,并且其他人报告了类似的观察结果,例如,使用 Boruta 作为预处理变量选择步骤用于逻辑回归。

由于随机森林变量重要性计算和 Boruta 特征选择都可以在 R 或其他软件中轻松获得,因此可以毫不费力地进行测试,因此应该尝试一下。如果您有足够的数据,您甚至可以通过对不同部分的数据执行这两个步骤来验证该方法。