Apakah XGBoost menangani multikolinieritas dengan sendirinya?

23

Saat ini saya menggunakan XGBoost pada kumpulan data dengan 21 fitur (dipilih dari daftar sekitar 150 fitur), kemudian dikodekan satu kali untuk mendapatkan ~ 98 fitur. Beberapa dari 98 fitur ini agak redundan, misalnya: variabel (fitur) juga muncul sebagai BA danCBA .CA

Pertanyaan saya adalah:

  • Bagaimana ( Jika? ) Boosted Decision Trees menangani multicollinearity?
  • Bagaimana keberadaan multikolinearitas memengaruhi prediksi jika tidak ditangani?

Dari apa yang saya pahami, model tersebut belajar lebih dari satu pohon dan prediksi akhir didasarkan pada sesuatu seperti "jumlah tertimbang" dari prediksi individu. Jadi jika ini benar, maka Boosted Decision Trees harus dapat menangani saling ketergantungan antar variabel.

Juga, pada catatan terkait - bagaimana objek kepentingan variabel dalam XGBoost berfungsi?

pengguna140323
sumber
Saya mengerti bahwa pohon dapat menangani multikolinieritas. Tetapi bagaimana dengan XGBoost berbasis regresi? Apakah bisa menangani multi-collinearity juga? > Pohon keputusan pada dasarnya kebal terhadap multi-collinearity. Sebagai contoh, jika Anda memiliki 2 fitur yang berkorelasi 99%, ketika> memutuskan split, pohon hanya akan memilih salah satu dari mereka. > Model lain seperti Regresi logistik akan menggunakan kedua fitur tersebut. >> Karena pohon yang dikuatkan menggunakan pohon keputusan individu, mereka>> juga tidak terpengaruh oleh multi-collinearity. Namun, ini merupakan praktik yang baik untuk> menghapus semua fitur yang berlebihan dari dataset apa pun yang digunakan untuk tra
Jay Saxena

Jawaban:

27

Pohon keputusan pada dasarnya kebal terhadap multi-collinearity. Misalnya, jika Anda memiliki 2 fitur yang berkorelasi 99%, ketika memutuskan split, pohon hanya akan memilih salah satu dari mereka. Model lain seperti regresi logistik akan menggunakan kedua fitur tersebut.

Karena pohon yang dikuatkan menggunakan pohon keputusan individu, mereka juga tidak terpengaruh oleh multi-collinearity. Namun, ini merupakan praktik yang baik untuk menghapus semua fitur yang berlebihan dari setiap dataset yang digunakan untuk pelatihan, terlepas dari algoritma model. Dalam kasus Anda karena Anda memperoleh fitur baru, Anda dapat menggunakan pendekatan ini, mengevaluasi pentingnya setiap fitur dan hanya mempertahankan fitur terbaik untuk model akhir Anda.

Matriks penting dari model xgboost sebenarnya adalah objek data.table dengan kolom pertama berisi daftar semua fitur yang sebenarnya digunakan pada pohon yang dikuatkan. Kolom kedua adalah metrik Penguatan yang menyiratkan kontribusi relatif dari fitur yang sesuai dengan model yang dihitung dengan mengambil kontribusi setiap fitur untuk setiap pohon dalam model. Nilai yang lebih tinggi dari metrik ini bila dibandingkan dengan fitur lain menyiratkan bahwa lebih penting untuk menghasilkan prediksi.

Sandeep S. Sandhu
sumber
7

Saya ingin tahu tentang hal ini dan melakukan beberapa tes.

Saya telah melatih model pada dataset berlian, dan mengamati bahwa variabel "x" adalah yang paling penting untuk memprediksi apakah harga berlian lebih tinggi dari ambang tertentu. Kemudian, saya telah menambahkan beberapa kolom yang sangat berkorelasi dengan x, menjalankan model yang sama, dan mengamati nilai yang sama.

Tampaknya ketika korelasi antara dua kolom adalah 1, xgboost menghapus kolom tambahan sebelum menghitung model, sehingga kepentingannya tidak terpengaruh. Namun, ketika Anda menambahkan kolom yang sebagian berkorelasi dengan yang lain, dengan demikian dengan koefisien yang lebih rendah, pentingnya variabel asli x diturunkan.

Sebagai contoh jika saya menambahkan variabel xy = x + y, pentingnya x dan y berkurang. Demikian pula, pentingnya x berkurang jika saya menambahkan variabel baru dengan r = 0,4, 0,5 atau 0,6, meskipun hanya sedikit.

Saya pikir bahwa collinearity bukan masalah untuk meningkatkan ketika Anda menghitung keakuratan model, karena pohon keputusan tidak peduli yang mana salah satu variabel yang digunakan. Namun itu mungkin mempengaruhi pentingnya variabel, karena menghapus salah satu dari dua variabel yang berkorelasi tidak memiliki dampak besar pada keakuratan model, mengingat yang lain berisi informasi yang sama.

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

Mengevaluasi model pada data berlian

Kami memperkirakan apakah harga lebih tinggi dari 400, mengingat semua variabel numerik tersedia (karat, kedalaman, tabel, x, y, x)

Perhatikan bahwa x adalah variabel yang paling penting, dengan skor gain penting 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

Model dilatih tentang Diamonds, menambahkan variabel dengan r = 1 hingga x

Di sini kita menambahkan kolom baru, yang bagaimanapun tidak menambahkan informasi baru, karena berkorelasi sempurna dengan x.

Perhatikan bahwa variabel baru ini tidak ada dalam output. Tampaknya xgboost secara otomatis menghapus variabel berkorelasi sempurna sebelum memulai perhitungan. Keuntungan penting x adalah sama, 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

Model dilatih tentang Diamonds, menambahkan kolom untuk x + y

Kami menambahkan kolom baru xy = x + y. Ini sebagian berkorelasi dengan x dan y.

Perhatikan bahwa pentingnya x dan y sedikit berkurang, dari 0,3759 menjadi 0,3592 untuk x, dan dari 0,116 menjadi 0,079 untuk y.

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

Model dilatih tentang data Diamonds, dimodifikasi menambahkan kolom yang berlebihan

Kami menambahkan tiga kolom baru yang berkorelasi dengan x (r = 0,4, 0,5 dan 0,6) dan melihat apa yang terjadi.

Perhatikan bahwa pentingnya x akan berkurang, turun dari 0,3759 ke 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
dalloliogm
sumber
6

Ada jawaban dari Tianqi Chen (2018).

Perbedaan ini berdampak pada kasus sudut dalam analisis fitur penting: fitur yang berkorelasi. Bayangkan dua fitur berkorelasi sempurna, fitur A dan fitur B. Untuk satu pohon tertentu, jika algoritma membutuhkan salah satu dari mereka, ia akan memilih secara acak (benar di kedua meningkatkan dan Hutan Acak ™).

Namun, dalam Random Forests ™ pilihan acak ini akan dilakukan untuk setiap pohon, karena setiap pohon independen dari yang lain. Oleh karena itu, kira-kira, tergantung pada parameter Anda, 50% dari pohon akan memilih fitur A dan 50% lainnya akan memilih fitur B. Jadi pentingnya informasi yang terkandung dalam A dan B (yang sama, karena mereka berkorelasi sempurna ) dilarutkan dalam A dan B. Jadi Anda tidak akan mudah mengetahui informasi ini penting untuk memprediksi apa yang ingin Anda prediksi! Bahkan lebih buruk ketika Anda memiliki 10 fitur yang berhubungan ...

Dalam meningkatkan, ketika tautan spesifik antara fitur dan hasil telah dipelajari oleh algoritme, ia akan berusaha untuk tidak memfokuskannya kembali (dalam teori itulah yang terjadi, kenyataannya tidak selalu sesederhana itu). Karena itu, yang terpenting adalah pada fitur A atau pada fitur B (tetapi tidak keduanya). Anda akan tahu bahwa satu fitur memiliki peran penting dalam hubungan antara pengamatan dan label. Terserah Anda untuk mencari fitur yang berkorelasi dengan fitur yang terdeteksi sebagai penting jika Anda perlu mengetahui semuanya.

Untuk meringkas, Xgboost tidak secara acak menggunakan fitur yang berkorelasi di setiap pohon, yang model hutan acak menderita dari situasi seperti itu.

Referensi :

Tianqi Chen, Michaël Benesty, Tong He. 2018. "Memahami Kumpulan Data Anda dengan Xgboost." Https://cran.r-project.org/web/packages/xgboost/vignettes/discoverYourData.html#numeric-vs-categorical-variables .

Jiaxiang
sumber
2

Sebuah komentar pada jawaban Sandeep: Dengan asumsi 2 fitur Anda sangat kolinear (katakanlah sama dengan 99% waktu) Memang hanya 1 fitur yang dipilih pada setiap pemisahan, tetapi untuk pemisahan berikutnya, xgb dapat memilih fitur lainnya. Oleh karena itu, peringkat fitur xgb mungkin akan memberi peringkat fitur 2 colinear secara merata. Tanpa pengetahuan sebelumnya atau pemrosesan fitur lainnya, Anda hampir tidak memiliki sarana dari peringkat yang disediakan ini untuk mendeteksi bahwa 2 fitur tersebut adalah colinear.

Sekarang, untuk kepentingan relatif yang menghasilkan xgboost, itu harus sangat mirip (atau mungkin persis sama) dengan gradien sklearn yang ditingkatkan peringkat pohon. Lihat di sini untuk penjelasan.

PSAfrance
sumber