XGBoost是否自己处理多重共线性?


23

我目前在具有21个功能(从大约150个功能的列表中选择)的数据集上使用XGBoost,然后对其进行一次热编码以获得〜98个功能。这98个功能中的一些功能有些多余,例如:变量(功能)也显示为B一种C一种C一种

我的问题是:

  • 增强决策树如何(如果?)处理多重共线性?
  • 如果不处理,多重共线性的存在将如何影响预测?

据我了解,该模型正在学习一棵以上的树,而最终预测是基于诸如单个预测的“加权总和”之类的。因此,如果这是正确的,那么增强决策树应该能够处理变量之间的相互依赖性。

另外,在相关说明中-XGBoost中的可变重要性对象如何工作?


我知道树可以处理多重共线性。但是基于回归的XGBoost呢?它也可以处理多重共线性吗?>决策树本质上不受多重共线性的影响。例如,如果您有2个具有99%关联的要素,则>决定拆分时,树将仅选择其中之一。其他模型(如Logistic回归)将同时使用这两个功能。>>>因为增强树使用单独的决策树,所以它们也不受多重共线性的影响。但是,从所有用于tra的数据集中删除所有冗余功能是一个很好的做法
Jay Saxena

Answers:


27

决策树本质上不受多重共线性的影响。例如,如果您具有2个99%相关的要素,则在决定拆分时,树将仅选择其中之一。其他模型(例如逻辑回归)将同时使用这两个功能。

由于增强树使用单独的决策树,因此它们也不受多重共线性的影响。但是,不管模型的算法如何,从任何用于训练的数据集中删除任何冗余特征都是一种很好的做法。对于您的情况,因为您要派生新功能,则可以使用这种方法,评估每个功能的重要性,并只保留最终模型的最佳功能。

xgboost模型的重要性矩阵实际上是一个data.table对象,第一列列出了在增强树中实际使用的所有功能的名称。第二列是“增益”度量,它表示通过采用模型中每棵树的每个特征的贡献来计算相应特征对模型的相对贡献。与其他功能相比,此指标的值越高,表示生成预测就越重要。


7

我对此感到很好奇,并做了一些测试。

我已经在钻石数据集中训练了一个模型,并观察到变量“ x”对于预测钻石的价格是否高于某个阈值最为重要。然后,我添加了多个与x高度相关的列,运行相同的模型,并观察到相同的值。

看来,当两列之间的相关性为1时,xgboost会在计算模型之前删除多余的列,因此重要性不受影响。但是,当您添加与另一列部分相关的列,因此系数较低时,原始变量x的重要性会降低。

例如,如果我添加变量xy = x + y,则x和y的重要性都会降低。类似地,如果我添加r = 0.4、0.5或0.6的新变量,则x的重要性会降低,尽管只是一点点。

我认为,在计算模型的准确性时,共线性不是增强问题,因为决策树并不关心使用哪个变量。但是,这可能会影响变量的重要性,因为删除两个相关变量之一不会对模型的准确性产生重大影响,因为另一个变量包含相似的信息。

library(tidyverse)
library(xgboost)

evaluate_model = function(dataset) {
    print("Correlation matrix")
    dataset %>% select(-cut, -color, -clarity, -price) %>% cor %>% print

    print("running model")
    diamond.model = xgboost(
        data=dataset %>% select(-cut, -color, -clarity, -price) %>% as.matrix, 
        label=dataset$price > 400, 
        max.depth=15, nrounds=30, nthread=2, objective = "binary:logistic",
        verbose=F
        )

    print("Importance matrix")
    importance_matrix <- xgb.importance(model = diamond.model)
    importance_matrix %>% print
    xgb.plot.importance(importance_matrix)
    }

> diamonds %>% head
carat   cut color   clarity depth   table   price   x   y   z
0.23    Ideal   E   SI2 61.5    55  326 3.95    3.98    2.43
0.21    Premium E   SI1 59.8    61  326 3.89    3.84    2.31
0.23    Good    E   VS1 56.9    65  327 4.05    4.07    2.31
0.29    Premium I   VS2 62.4    58  334 4.20    4.23    2.63
0.31    Good    J   SI2 63.3    58  335 4.34    4.35    2.75
0.24    Very Good   J   VVS2    62.8    57  336 3.94    3.96    2.48

根据钻石数据评估模型

考虑到所有可用的数值变量(克拉,深度,表,x,y,x),我们预测价格是否高于400

请注意,x是最重要的变量,重要度得分为0.375954。

evaluate_model(diamonds)
    [1] "Correlation matrix"
               carat       depth      table           x           y          z
    carat 1.00000000  0.02822431  0.1816175  0.97509423  0.95172220 0.95338738
    depth 0.02822431  1.00000000 -0.2957785 -0.02528925 -0.02934067 0.09492388
    table 0.18161755 -0.29577852  1.0000000  0.19534428  0.18376015 0.15092869
    x     0.97509423 -0.02528925  0.1953443  1.00000000  0.97470148 0.97077180
    y     0.95172220 -0.02934067  0.1837601  0.97470148  1.00000000 0.95200572
    z     0.95338738  0.09492388  0.1509287  0.97077180  0.95200572 1.00000000
    [1] "running model"
    [1] "Importance matrix"
       Feature       Gain      Cover  Frequency
    1:       x 0.37595419 0.54788335 0.19607102
    2:   carat 0.19699839 0.18015576 0.04873442
    3:   depth 0.15358261 0.08780079 0.27767284
    4:       y 0.11645929 0.06527969 0.18813751
    5:   table 0.09447853 0.05037063 0.17151492
    6:       z 0.06252699 0.06850978 0.11786929

在Diamonds上训练模型,在x上添加一个r = 1的变量

在这里,我们添加了一个新列,但是它没有添加任何新信息,因为它与x完全相关。

请注意,此新变量在输出中不存在。似乎xgboost会在开始计算之前自动删除完全相关的变量。x的重要性增益相同,为0.3759。

diamonds_xx = diamonds %>%
    mutate(xx = x + runif(1, -1, 1))
evaluate_model(diamonds_xx)
[1] "Correlation matrix"
           carat       depth      table           x           y          z
carat 1.00000000  0.02822431  0.1816175  0.97509423  0.95172220 0.95338738
depth 0.02822431  1.00000000 -0.2957785 -0.02528925 -0.02934067 0.09492388
table 0.18161755 -0.29577852  1.0000000  0.19534428  0.18376015 0.15092869
x     0.97509423 -0.02528925  0.1953443  1.00000000  0.97470148 0.97077180
y     0.95172220 -0.02934067  0.1837601  0.97470148  1.00000000 0.95200572
z     0.95338738  0.09492388  0.1509287  0.97077180  0.95200572 1.00000000
xx    0.97509423 -0.02528925  0.1953443  1.00000000  0.97470148 0.97077180
               xx
carat  0.97509423
depth -0.02528925
table  0.19534428
x      1.00000000
y      0.97470148
z      0.97077180
xx     1.00000000
[1] "running model"
[1] "Importance matrix"
   Feature       Gain      Cover  Frequency
1:       x 0.37595419 0.54788335 0.19607102
2:   carat 0.19699839 0.18015576 0.04873442
3:   depth 0.15358261 0.08780079 0.27767284
4:       y 0.11645929 0.06527969 0.18813751
5:   table 0.09447853 0.05037063 0.17151492
6:       z 0.06252699 0.06850978 0.11786929

在Diamonds上训练模型,为x + y添加一列

我们添加一个新列xy = x + y。这部分与x和y相关。

请注意,x和y的重要性略有降低,x的重要性从0.3759降低到0.3592,y的重要性从0.116降低到0.079。

diamonds_xy = diamonds %>%
    mutate(xy=x+y)
evaluate_model(diamonds_xy)

[1] "Correlation matrix"
           carat       depth      table           x           y          z
carat 1.00000000  0.02822431  0.1816175  0.97509423  0.95172220 0.95338738
depth 0.02822431  1.00000000 -0.2957785 -0.02528925 -0.02934067 0.09492388
table 0.18161755 -0.29577852  1.0000000  0.19534428  0.18376015 0.15092869
x     0.97509423 -0.02528925  0.1953443  1.00000000  0.97470148 0.97077180
y     0.95172220 -0.02934067  0.1837601  0.97470148  1.00000000 0.95200572
z     0.95338738  0.09492388  0.1509287  0.97077180  0.95200572 1.00000000
xy    0.96945349 -0.02750770  0.1907100  0.99354016  0.99376929 0.96744200
              xy
carat  0.9694535
depth -0.0275077
table  0.1907100
x      0.9935402
y      0.9937693
z      0.9674420
xy     1.0000000
[1] "running model"
[1] "Importance matrix"
   Feature       Gain      Cover  Frequency
1:       x 0.35927767 0.52924339 0.15952849
2:   carat 0.17881931 0.18472506 0.04793713
3:   depth 0.14353540 0.07482622 0.24990177
4:   table 0.09202059 0.04714548 0.16267191
5:      xy 0.08203819 0.04706267 0.13555992
6:       y 0.07956856 0.05284980 0.13595285
7:       z 0.06474029 0.06414738 0.10844794

对Diamonds数据进行模型训练,修改后添加冗余列

我们添加了三个与x相关的新列(r = 0.4、0.5和0.6),然后看看会发生什么。

请注意,x的重要性降低了,从0.3759降至0.279。

#' given a vector of values (e.g. diamonds$x), calculate three new vectors correlated to it
#' 
#' Source: https://stat.ethz.ch/pipermail/r-help/2007-April/128938.html
calculate_correlated_vars = function(x1) {

    # create the initial x variable
    #x1 <- diamonds$x

    # x2, x3, and x4 in a matrix, these will be modified to meet the criteria
    x234 <- scale(matrix( rnorm(nrow(diamonds) * 3), ncol=3 ))

    # put all into 1 matrix for simplicity
    x1234 <- cbind(scale(x1),x234)

    # find the current correlation matrix
    c1 <- var(x1234)

    # cholesky decomposition to get independence
    chol1 <- solve(chol(c1))

    newx <-  x1234 %*% chol1 

    # check that we have independence and x1 unchanged
    zapsmall(cor(newx))
    all.equal( x1234[,1], newx[,1] )

    # create new correlation structure (zeros can be replaced with other r vals)
    newc <- matrix( 
    c(1  , 0.4, 0.5, 0.6, 
      0.4, 1  , 0  , 0  ,
      0.5, 0  , 1  , 0  ,
      0.6, 0  , 0  , 1  ), ncol=4 )

    # check that it is positive definite
    eigen(newc)

    chol2 <- chol(newc)

    finalx <- newx %*% chol2 * sd(x1) + mean(x1)

    # verify success
    mean(x1)
    colMeans(finalx)

    sd(x1)
    apply(finalx, 2, sd)

    zapsmall(cor(finalx))
    #pairs(finalx)

    all.equal(x1, finalx[,1])
    finalx
}
finalx = calculate_correlated_vars(diamonds$x)
diamonds_cor = diamonds
diamonds_cor$x5 = finalx[,2]
diamonds_cor$x6 = finalx[,3]
diamonds_cor$x7 = finalx[,4]
evaluate_model(diamonds_cor)
[1] "Correlation matrix"
           carat        depth       table           x           y          z
carat 1.00000000  0.028224314  0.18161755  0.97509423  0.95172220 0.95338738
depth 0.02822431  1.000000000 -0.29577852 -0.02528925 -0.02934067 0.09492388
table 0.18161755 -0.295778522  1.00000000  0.19534428  0.18376015 0.15092869
x     0.97509423 -0.025289247  0.19534428  1.00000000  0.97470148 0.97077180
y     0.95172220 -0.029340671  0.18376015  0.97470148  1.00000000 0.95200572
z     0.95338738  0.094923882  0.15092869  0.97077180  0.95200572 1.00000000
x5    0.39031255 -0.007507604  0.07338484  0.40000000  0.38959178 0.38734145
x6    0.48879000 -0.016481580  0.09931705  0.50000000  0.48835896 0.48487442
x7    0.58412252 -0.013772440  0.11822089  0.60000000  0.58408881 0.58297414
                 x5            x6            x7
carat  3.903125e-01  4.887900e-01  5.841225e-01
depth -7.507604e-03 -1.648158e-02 -1.377244e-02
table  7.338484e-02  9.931705e-02  1.182209e-01
x      4.000000e-01  5.000000e-01  6.000000e-01
y      3.895918e-01  4.883590e-01  5.840888e-01
z      3.873415e-01  4.848744e-01  5.829741e-01
x5     1.000000e+00  5.925447e-17  8.529781e-17
x6     5.925447e-17  1.000000e+00  6.683397e-17
x7     8.529781e-17  6.683397e-17  1.000000e+00
[1] "running model"
[1] "Importance matrix"
   Feature       Gain      Cover  Frequency
1:       x 0.27947762 0.51343709 0.09748172
2:   carat 0.13556427 0.17401365 0.02680747
3:      x5 0.13369515 0.05267688 0.18155971
4:      x6 0.12968400 0.04804315 0.19821284
5:      x7 0.10600238 0.05148826 0.16450041
6:   depth 0.07087679 0.04485760 0.11251015
7:       y 0.06050565 0.03896716 0.08245329
8:   table 0.04577057 0.03135677 0.07554833
9:       z 0.03842355 0.04515944 0.06092608

6

陈天琪(2018)有一个答案。

这种差异会影响特征重要性分析的一个极端情况:相关特征。想象一下两个特征完全相关的特征A和特征B。对于一棵特定的树,如果算法需要其中之一,它将随机选择(boosting和Random Forests™中都是true)。

但是,在Random Forests™中,将对每棵树进行此随机选择,因为每棵树都彼此独立。因此,大约根据您的参数,有50%的树将选择特征A,其余50%的树将选择特征B。因此,A和B中包含的信息的重要性(这是相同的,因为它们是完全相关的)稀释在A和B中。因此,您将不容易知道此信息对于预测要预测的内容很重要!当您拥有10个相关功能时,情况更糟……

在增强算法中,当算法已经了解了特征与结果之间的特定联系时,它将尝试不重新关注它(理论上就是这样,现实并不总是那么简单)。因此,所有重要性都将在特征A或特征B上(但不能同时在两者上)。您将知道,一项功能在观测值和标签之间的链接中起着重要作用。如果您需要了解所有相关功能,则仍然需要搜索与检测到的重要功能相关的功能。

总而言之,Xgboost不会随机使用每棵树中的相关特征,而随机森林模型会遭受这种情况的困扰。

参考

陈天琪,米歇尔·贝内斯蒂,Tong河。2018。“使用Xgboost理解数据集。” https://cran.r-project.org/web/packages/xgboost/vignettes/discoverYourData.html#numeric-vs-categorical-variables


2

关于Sandeep答案的评论:假设您的2个要素是高度共线性的(例如等于99%的时间),实际上每个拆分只选择了1个要素,但是对于下一个拆分,xgb可以选择其他要素。因此,xgb特征排名可能将2个共线特征均等地排名。没有一些先验知识或其他特征处理,从提供的排名中您几乎无法检测到这两个特征是共线的。

现在,关于输出xgboost的相对重要性,它应该与sklearn梯度增强树排名非常相似(或可能完全相似)。请参阅此处以获取解释。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.