Compare commits
774 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36ad160501 | ||
|
|
c22f6db4bf | ||
|
|
f15a6d2b19 | ||
|
|
08a547f5c2 | ||
|
|
60303db2ee | ||
|
|
df984f9c43 | ||
|
|
2f22f8d49b | ||
|
|
68d86336d7 | ||
|
|
76bdca072a | ||
|
|
021e6a842a | ||
|
|
e5bef4ffce | ||
|
|
10bb0a74ef | ||
|
|
e803d06d8c | ||
|
|
ccf43d4ba0 | ||
|
|
dd58c2ac47 | ||
|
|
899e4c8988 | ||
|
|
a2085bf223 | ||
|
|
067b704e58 | ||
|
|
1a834b2b85 | ||
|
|
162b48a1a4 | ||
|
|
83a078b7e5 | ||
|
|
575fba651b | ||
|
|
62ed8b5fef | ||
|
|
a980e10744 | ||
|
|
59c54e361b | ||
|
|
60a8c8ebba | ||
|
|
58bc225657 | ||
|
|
850b53100f | ||
|
|
67b657dad0 | ||
|
|
db14e3feb7 | ||
|
|
9372370dda | ||
|
|
1136a7e0c3 | ||
|
|
a347cd512b | ||
|
|
9ff0c0832a | ||
|
|
534c940a7e | ||
|
|
5b76acccff | ||
|
|
4bc59ef7c3 | ||
|
|
e43cd60c0e | ||
|
|
3f92970a39 | ||
|
|
e17f7010bf | ||
|
|
aa30ce10da | ||
|
|
153d995b58 | ||
|
|
463313d9be | ||
|
|
7cf58a2c65 | ||
|
|
28a466ab51 | ||
|
|
5bd849f1b5 | ||
|
|
c69af90319 | ||
|
|
c884b9e888 | ||
|
|
52977f0cdf | ||
|
|
c47c71e34f | ||
|
|
76f95a6667 | ||
|
|
3901f5d9db | ||
|
|
521086d56b | ||
|
|
5647fc6542 | ||
|
|
8f3dee58be | ||
|
|
031d66ec27 | ||
|
|
2176e511fc | ||
|
|
fcddbc9264 | ||
|
|
80e10e02ab | ||
|
|
b3208aac4e | ||
|
|
748d516c50 | ||
|
|
4633b476e9 | ||
|
|
3ef1703553 | ||
|
|
29595102b9 | ||
|
|
2faa744aba | ||
|
|
97a5b088a5 | ||
|
|
ce0382dcb0 | ||
|
|
39afdac3be | ||
|
|
210915c985 | ||
|
|
c68684ff4c | ||
|
|
5545c49cfc | ||
|
|
e1f9f80df2 | ||
|
|
a71421e825 | ||
|
|
d70e59fefc | ||
|
|
50ff8a2623 | ||
|
|
bc7a6ec603 | ||
|
|
c24e9d712c | ||
|
|
8d4038da57 | ||
|
|
66fd9f5207 | ||
|
|
909e49e214 | ||
|
|
668b8a0ea4 | ||
|
|
e47b3a3da3 | ||
|
|
97c3a80a34 | ||
|
|
b2bbf49015 | ||
|
|
d686bf52a6 | ||
|
|
ca0547bb65 | ||
|
|
37886a5dff | ||
|
|
9af99760d4 | ||
|
|
299e5000a4 | ||
|
|
55cf24cc32 | ||
|
|
b14c44ee5e | ||
|
|
cbf3a5f918 | ||
|
|
c91fed083d | ||
|
|
6925b222e0 | ||
|
|
f835368bcf | ||
|
|
6d1452074a | ||
|
|
fcab51aa82 | ||
|
|
1082ccd3cc | ||
|
|
8f77677193 | ||
|
|
4056974e37 | ||
|
|
ff71c69adf | ||
|
|
0cd11b893a | ||
|
|
be5b95e743 | ||
|
|
8d247f0d64 | ||
|
|
ab342af242 | ||
|
|
3fd331f8f2 | ||
|
|
eb7bbee2c9 | ||
|
|
b791446623 | ||
|
|
7d43e74e71 | ||
|
|
fffb1fca52 | ||
|
|
4f42aa5f12 | ||
|
|
520586ffa7 | ||
|
|
70df36c99c | ||
|
|
2e63af6117 | ||
|
|
bdf265076d | ||
|
|
a2686543a9 | ||
|
|
bc818316f2 | ||
|
|
dd44ac91b8 | ||
|
|
23faf656ad | ||
|
|
e888eb2fa9 | ||
|
|
b397d64c96 | ||
|
|
dc07137a2c | ||
|
|
b5eb36f1af | ||
|
|
441ffc017a | ||
|
|
7ee10e3dbd | ||
|
|
ada4a86d1c | ||
|
|
deae99e662 | ||
|
|
b78bc734d9 | ||
|
|
56395d120b | ||
|
|
a868498c18 | ||
|
|
8dac90a593 | ||
|
|
d6e2013c5f | ||
|
|
651f0a8889 | ||
|
|
d03794ce7a | ||
|
|
9b32e6e2dc | ||
|
|
f4628c22a4 | ||
|
|
35ef8abc27 | ||
|
|
ad3bc0edee | ||
|
|
53d2a733b0 | ||
|
|
1703dc330f | ||
|
|
40a10c217d | ||
|
|
93966b0d19 | ||
|
|
a9458fd844 | ||
|
|
fa869eebd9 | ||
|
|
f421c26d35 | ||
|
|
16bca5d4a1 | ||
|
|
36e7c5364d | ||
|
|
20d1bba1bb | ||
|
|
d868126c39 | ||
|
|
570f8ae4ba | ||
|
|
bdb291f1c2 | ||
|
|
446d536c23 | ||
|
|
8fc60b31bc | ||
|
|
9ae547f994 | ||
|
|
03cc3b359c | ||
|
|
bcc8679a05 | ||
|
|
ff471b3fab | ||
|
|
d87f69215e | ||
|
|
2cba1d9fcc | ||
|
|
24c2373080 | ||
|
|
2c70751d1e | ||
|
|
546de5efd2 | ||
|
|
3970e4e6bb | ||
|
|
7785d65c8a | ||
|
|
4a4e5c7c18 | ||
|
|
1be09848a7 | ||
|
|
cb40bbdadd | ||
|
|
703261e78f | ||
|
|
ef11b024e8 | ||
|
|
5156be0f49 | ||
|
|
8bdea72688 | ||
|
|
f23cc92130 | ||
|
|
f801d3cf15 | ||
|
|
2365f82750 | ||
|
|
7a6b711eb8 | ||
|
|
4325178822 | ||
|
|
4083440690 | ||
|
|
e28f6f6657 | ||
|
|
579ab23b10 | ||
|
|
a33f35eecf | ||
|
|
91bb9e2cb3 | ||
|
|
0ce80b7bcf | ||
|
|
7a5586f3db | ||
|
|
8fccc3c4ad | ||
|
|
647d3844dd | ||
|
|
dae7a41baa | ||
|
|
8dd96013f1 | ||
|
|
36cf979b82 | ||
|
|
abaa593aa0 | ||
|
|
937352c78f | ||
|
|
176fec8789 | ||
|
|
8959622836 | ||
|
|
0bdaca25ca | ||
|
|
a5bc8e2c6a | ||
|
|
210eb471e9 | ||
|
|
701f32b227 | ||
|
|
794cbaa60a | ||
|
|
ff1c559084 | ||
|
|
8746f9cddf | ||
|
|
f24bfc7684 | ||
|
|
3af02584c1 | ||
|
|
bc4f802b17 | ||
|
|
2407381c3d | ||
|
|
e88d6e071d | ||
|
|
dcaf580476 | ||
|
|
6eb23353d7 | ||
|
|
f470ad3af9 | ||
|
|
45dc1f818a | ||
|
|
0725fd6081 | ||
|
|
a68580e2a7 | ||
|
|
f0c1b842bf | ||
|
|
142a208a90 | ||
|
|
e44a082620 | ||
|
|
e5ec546da5 | ||
|
|
4a87ea49b8 | ||
|
|
d285d6ba2a | ||
|
|
e58e417603 | ||
|
|
9b0eb66b78 | ||
|
|
637e42a0c0 | ||
|
|
bb47fd8c49 | ||
|
|
8f8bd8147a | ||
|
|
1a33b50a0d | ||
|
|
d48123d23b | ||
|
|
1ced638165 | ||
|
|
b90c6d25e8 | ||
|
|
78694405a6 | ||
|
|
6426449c8b | ||
|
|
31e6902e43 | ||
|
|
6b55150e80 | ||
|
|
13b15e07e8 | ||
|
|
d3429f2ff6 | ||
|
|
545fd4548e | ||
|
|
27c66f12d1 | ||
|
|
5a7dc41351 | ||
|
|
80339c3427 | ||
|
|
6275cdc486 | ||
|
|
cc6d57aa0d | ||
|
|
7a039e03fe | ||
|
|
fbc3d861bb | ||
|
|
47224dd6d3 | ||
|
|
bde4f25794 | ||
|
|
2070afea02 | ||
|
|
18cbebaeb9 | ||
|
|
755d9d4609 | ||
|
|
606be9e663 | ||
|
|
18a38f7ca0 | ||
|
|
d314680a15 | ||
|
|
474366c020 | ||
|
|
f6babc814c | ||
|
|
6f424d8d6c | ||
|
|
f93a727869 | ||
|
|
edf9a9608e | ||
|
|
765097d514 | ||
|
|
19775ffe15 | ||
|
|
5ef33adf68 | ||
|
|
806c92c80b | ||
|
|
71d3b2e036 | ||
|
|
b41cf92dc2 | ||
|
|
77d4a53c32 | ||
|
|
4fcfd9c96e | ||
|
|
1496789561 | ||
|
|
a06d53688c | ||
|
|
4cd14aee5a | ||
|
|
1baad8650c | ||
|
|
ee382c4153 | ||
|
|
af907e2d0d | ||
|
|
11e46e4bc0 | ||
|
|
1b6538b4e5 | ||
|
|
c8f9d4b6e6 | ||
|
|
9fa7ed1743 | ||
|
|
11d65fcb21 | ||
|
|
db80671d6b | ||
|
|
94ca52b7b7 | ||
|
|
8ba4722d04 | ||
|
|
65e6d73b95 | ||
|
|
16ba74d008 | ||
|
|
d2bc0f0f08 | ||
|
|
1823db53f2 | ||
|
|
7ef54e39ec | ||
|
|
14ef38b834 | ||
|
|
46e0bce212 | ||
|
|
8ab5e13b5d | ||
|
|
317d7be6ee | ||
|
|
90cce38236 | ||
|
|
50d854e02e | ||
|
|
1b103e1f5f | ||
|
|
288c52596c | ||
|
|
f7db16add1 | ||
|
|
a94e1b172e | ||
|
|
686caad40c | ||
|
|
fdf533f2b9 | ||
|
|
ad06172c6b | ||
|
|
bef1f939ce | ||
|
|
dc2e699656 | ||
|
|
6ece549a90 | ||
|
|
332380479b | ||
|
|
c45665a55a | ||
|
|
f0f76259c9 | ||
|
|
c13a2a3114 | ||
|
|
c70fa502a5 | ||
|
|
401d451569 | ||
|
|
52d4eda786 | ||
|
|
5815df4c46 | ||
|
|
d0de954af2 | ||
|
|
5dea21273a | ||
|
|
2d83b2ad8f | ||
|
|
6f032b7152 | ||
|
|
1bb1913811 | ||
|
|
56e4baff7c | ||
|
|
3f536b5308 | ||
|
|
4b00c64d96 | ||
|
|
118192f116 | ||
|
|
729d227b89 | ||
|
|
89d6419fd5 | ||
|
|
2454407f3a | ||
|
|
e5ab8f3ebe | ||
|
|
bcce17e688 | ||
|
|
c467e90ac1 | ||
|
|
fd78af404b | ||
|
|
02dd7b6913 | ||
|
|
e8eff3581b | ||
|
|
6fa1afdffc | ||
|
|
522636cb52 | ||
|
|
9150fdbd4d | ||
|
|
d4796482b5 | ||
|
|
a50b84244e | ||
|
|
3c9b04460a | ||
|
|
8b3ecfca25 | ||
|
|
39c5616af2 | ||
|
|
b37ff3d492 | ||
|
|
b3ba0e8708 | ||
|
|
af0cf88921 | ||
|
|
64575591d8 | ||
|
|
f5b20286e2 | ||
|
|
c92ab2ce49 | ||
|
|
66cb4afc6c | ||
|
|
f20ffa8db3 | ||
|
|
4d81c741e9 | ||
|
|
cd55823112 | ||
|
|
996cc705af | ||
|
|
718472dbe2 | ||
|
|
9a400731d9 | ||
|
|
da351621a1 | ||
|
|
e78a38b837 | ||
|
|
613ec36c5a | ||
|
|
6b6849b001 | ||
|
|
98d6faefd6 | ||
|
|
4dafb5fac8 | ||
|
|
04fc575c0e | ||
|
|
55463b76c1 | ||
|
|
a62a3d991d | ||
|
|
68b6d6bbe2 | ||
|
|
a92e0f6240 | ||
|
|
1d468e20a4 | ||
|
|
18a4af63aa | ||
|
|
5eed2990ad | ||
|
|
1b25dd59f9 | ||
|
|
83a66b4994 | ||
|
|
f60d95b0ba | ||
|
|
89aa8ddf52 | ||
|
|
6762c45494 | ||
|
|
49c74a5369 | ||
|
|
e3e6de5ed9 | ||
|
|
c859764d29 | ||
|
|
584bae1fc6 | ||
|
|
e56d1779e1 | ||
|
|
549f3bd781 | ||
|
|
671b3c8d8e | ||
|
|
b2341eab0c | ||
|
|
131858e7cb | ||
|
|
f08c5dcb06 | ||
|
|
b76c5d54bf | ||
|
|
7366d3b20c | ||
|
|
14d61b0141 | ||
|
|
d625dc2047 | ||
|
|
3877043d41 | ||
|
|
711f7f3851 | ||
|
|
12949c6b31 | ||
|
|
0149f81a5a | ||
|
|
93eebe8664 | ||
|
|
0da7d872ef | ||
|
|
0d0abe1845 | ||
|
|
2369d55e9a | ||
|
|
5cd1f71b51 | ||
|
|
b52c4e13b0 | ||
|
|
1f020a6097 | ||
|
|
1441a6cd27 | ||
|
|
2775c2a1ab | ||
|
|
87c01f49d8 | ||
|
|
fe4ce920b2 | ||
|
|
926af9951e | ||
|
|
3e693e4f97 | ||
|
|
d152c59a9c | ||
|
|
34a238ca98 | ||
|
|
f6e6d0b2c0 | ||
|
|
271a7c5d43 | ||
|
|
c621775f34 | ||
|
|
b4340abf56 | ||
|
|
7f738e7f6f | ||
|
|
549bd419bb | ||
|
|
f21301c749 | ||
|
|
81210420c6 | ||
|
|
028bdc1740 | ||
|
|
e060519d4f | ||
|
|
5d7818e75d | ||
|
|
24789429fd | ||
|
|
511805c981 | ||
|
|
6967ef7267 | ||
|
|
5817840858 | ||
|
|
f84291c1e1 | ||
|
|
d262503781 | ||
|
|
ef4dae4c0e | ||
|
|
5ddd4a9d06 | ||
|
|
9fd510faa5 | ||
|
|
529cf8a54a | ||
|
|
ac7a36367c | ||
|
|
b4ec1682c6 | ||
|
|
dac9eb13bd | ||
|
|
9f20a3315e | ||
|
|
bb56bb9a13 | ||
|
|
cc06fab9a7 | ||
|
|
deab0e32ba | ||
|
|
d6ea5cc1ed | ||
|
|
465dc63833 | ||
|
|
a1bcd33a3b | ||
|
|
13b0fa4b97 | ||
|
|
52277cc3da | ||
|
|
e94b766310 | ||
|
|
e5e47c3c99 | ||
|
|
20c0d60ac7 | ||
|
|
2db808021d | ||
|
|
c635d4c46a | ||
|
|
001503186c | ||
|
|
ed95e77752 | ||
|
|
91c1a1c52f | ||
|
|
0df2ae63c7 | ||
|
|
28af6f9abb | ||
|
|
eea094e1bc | ||
|
|
ec56d5869b | ||
|
|
54582f641a | ||
|
|
eb1efb54b5 | ||
|
|
8f0a42a266 | ||
|
|
68cdbc9c16 | ||
|
|
5516281881 | ||
|
|
a4a0ebb85d | ||
|
|
3886c3dd8f | ||
|
|
29bfa94bb6 | ||
|
|
7f399eac8b | ||
|
|
eabec370e4 | ||
|
|
e8c1eb99e4 | ||
|
|
59bd1ab17e | ||
|
|
58a6723eb1 | ||
|
|
9ab73f737e | ||
|
|
b4a1236cfc | ||
|
|
24e25802a7 | ||
|
|
5b1161bb64 | ||
|
|
6f8a4633b7 | ||
|
|
70b12d898a | ||
|
|
a512b4b394 | ||
|
|
05497a9141 | ||
|
|
01152f89ee | ||
|
|
1864fab592 | ||
|
|
021f8bf28b | ||
|
|
eee527d264 | ||
|
|
85cbd32c5a | ||
|
|
6f38f5affa | ||
|
|
557ffc4bf5 | ||
|
|
bf7bb575b4 | ||
|
|
24be04e848 | ||
|
|
619c450a49 | ||
|
|
820e1c01ef | ||
|
|
488f12a996 | ||
|
|
c024c42dce | ||
|
|
96a9848c9e | ||
|
|
b124a27f57 | ||
|
|
5262e933f7 | ||
|
|
0c67685e43 | ||
|
|
0552ca8021 | ||
|
|
176110a22d | ||
|
|
d33854af1b | ||
|
|
9fb4338964 | ||
|
|
7cfb310eb4 | ||
|
|
2adf222fb2 | ||
|
|
b0015fda96 | ||
|
|
55ee272ea8 | ||
|
|
e27f543deb | ||
|
|
d4274bc556 | ||
|
|
a7057fa64c | ||
|
|
d27a11ff87 | ||
|
|
8cc75f1576 | ||
|
|
38ca96c9fc | ||
|
|
46726ec176 | ||
|
|
937fa282b5 | ||
|
|
ca6f980932 | ||
|
|
97d7582457 | ||
|
|
cb685607b2 | ||
|
|
8df0a252b7 | ||
|
|
d7d1b6e3a6 | ||
|
|
6ede12412c | ||
|
|
c968217ca8 | ||
|
|
48aff0eabd | ||
|
|
b06040b6d0 | ||
|
|
232144ca09 | ||
|
|
4100827971 | ||
|
|
ccdabe4512 | ||
|
|
57a4b4ff64 | ||
|
|
e6ab594e14 | ||
|
|
a55d43ccfd | ||
|
|
c74df31bf9 | ||
|
|
154b15060e | ||
|
|
32e673d8c4 | ||
|
|
a13321148a | ||
|
|
6295dc3b67 | ||
|
|
8211e5f341 | ||
|
|
0f7a9b42f1 | ||
|
|
239dbb3c0a | ||
|
|
b81ebbef62 | ||
|
|
c6769488b3 | ||
|
|
45aef75cca | ||
|
|
6b074add66 | ||
|
|
3c4aa9b2ea | ||
|
|
d05754f558 | ||
|
|
ac9bfaa4f2 | ||
|
|
2eee87423c | ||
|
|
b9414b6477 | ||
|
|
d4349426d8 | ||
|
|
a6bcd54b47 | ||
|
|
fd61c61071 | ||
|
|
e36b066344 | ||
|
|
864d236a82 | ||
|
|
31a307cf6b | ||
|
|
7593fa9982 | ||
|
|
d1f00fb0b7 | ||
|
|
74bab6e504 | ||
|
|
8d7c6366d7 | ||
|
|
15685996fc | ||
|
|
f999897615 | ||
|
|
b8e8f0fcd9 | ||
|
|
3b0b74fa94 | ||
|
|
376b448015 | ||
|
|
f53da412aa | ||
|
|
5ff210ed75 | ||
|
|
c42e3fbcf3 | ||
|
|
4fd149b3a2 | ||
|
|
fbb0dc4275 | ||
|
|
fb1a9e6bc5 | ||
|
|
f56e2e9a66 | ||
|
|
8e619010d0 | ||
|
|
6cdcfe8128 | ||
|
|
e6a142fe70 | ||
|
|
4ddf8d001c | ||
|
|
406c70ba0e | ||
|
|
0bd8f21e4e | ||
|
|
a7d0c66457 | ||
|
|
130df8cdda | ||
|
|
5b17bb0031 | ||
|
|
89d87e5331 | ||
|
|
298af6f409 | ||
|
|
69d3b1b8b4 | ||
|
|
578de9f762 | ||
|
|
f7caac2563 | ||
|
|
e2660ab8f3 | ||
|
|
cc459755be | ||
|
|
d8cb395380 | ||
|
|
b3b03200e2 | ||
|
|
2a0368b7ca | ||
|
|
b2d8431aea | ||
|
|
d8a549e6ac | ||
|
|
ca17f8a5fc | ||
|
|
fbd58bf190 | ||
|
|
0ee11dac77 | ||
|
|
d27a427dc5 | ||
|
|
475fd1abec | ||
|
|
9472be7d77 | ||
|
|
4f93e5586a | ||
|
|
18bd16341a | ||
|
|
61a619b5c3 | ||
|
|
e48e05e6e2 | ||
|
|
c735c17f33 | ||
|
|
c311a8c1d8 | ||
|
|
b18f5f61b0 | ||
|
|
38a23f66a8 | ||
|
|
8ad7e8eeb0 | ||
|
|
22d56cebf1 | ||
|
|
32e0858501 | ||
|
|
31c1e13f90 | ||
|
|
9f63d6fead | ||
|
|
0ed979b096 | ||
|
|
2942dc68e4 | ||
|
|
037dd0820d | ||
|
|
d997c967d5 | ||
|
|
3515931305 | ||
|
|
a0dcf6f5c1 | ||
|
|
804b2ac60f | ||
|
|
68a2c7b8d6 | ||
|
|
b12e7f7edd | ||
|
|
3a4f51f39f | ||
|
|
ba69244a94 | ||
|
|
7a1d67f9cb | ||
|
|
e7d7ab6bc3 | ||
|
|
b70e07da1f | ||
|
|
cdfaa705f3 | ||
|
|
3060f0b562 | ||
|
|
9c64618cb6 | ||
|
|
d04312b9c0 | ||
|
|
ee8d1f5ed8 | ||
|
|
3290a4f3ed | ||
|
|
bf562bd33c | ||
|
|
01b7acba30 | ||
|
|
ec849ec335 | ||
|
|
46c46829ce | ||
|
|
6bcbc77226 | ||
|
|
3f38d983a6 | ||
|
|
9600ca83f3 | ||
|
|
149f209af6 | ||
|
|
336af4f974 | ||
|
|
f7003dc819 | ||
|
|
8a84be37b8 | ||
|
|
8ee127469f | ||
|
|
ba47eda61b | ||
|
|
e2c406f5c8 | ||
|
|
7bdedacb54 | ||
|
|
d080b5a953 | ||
|
|
36346f8f56 | ||
|
|
1369133916 | ||
|
|
f1a4a1ac95 | ||
|
|
dfdf0b08fc | ||
|
|
92ae3abc97 | ||
|
|
1a75f43304 | ||
|
|
7017dd5a26 | ||
|
|
48d5de80a2 | ||
|
|
7ee7a95b84 | ||
|
|
e88ac9cc54 | ||
|
|
778135f657 | ||
|
|
41e882f80b | ||
|
|
caa9e527dd | ||
|
|
e6088366df | ||
|
|
e64ee6592f | ||
|
|
9f7f8b976d | ||
|
|
d7c14496d2 | ||
|
|
bd1f3a38f0 | ||
|
|
2f524e9f41 | ||
|
|
abec3dbf6d | ||
|
|
2801d69fb7 | ||
|
|
8e8232fb4c | ||
|
|
345796825f | ||
|
|
1d91f71119 | ||
|
|
77f6cf2d13 | ||
|
|
84d359efb8 | ||
|
|
5d7cdf2e36 | ||
|
|
c766f143ab | ||
|
|
689eb8f620 | ||
|
|
615ab2b03e | ||
|
|
d22b293f2f | ||
|
|
f937f514aa | ||
|
|
116d711815 | ||
|
|
d7e1fa7664 | ||
|
|
ffa66aace0 | ||
|
|
b56d3d5d5c | ||
|
|
93f3acdef9 | ||
|
|
a5d222fcdb | ||
|
|
1cd20efe68 | ||
|
|
1c8fdf2218 | ||
|
|
dd4db347f3 | ||
|
|
8fa32fdda2 | ||
|
|
663136aa08 | ||
|
|
b2d300e727 | ||
|
|
1d4d345634 | ||
|
|
da1ad798ca | ||
|
|
bbfffb444d | ||
|
|
29f8fd6fee | ||
|
|
7968c0d051 | ||
|
|
86715e4cd4 | ||
|
|
7dd29ffd47 | ||
|
|
dcd84b3979 | ||
|
|
d9799b09d0 | ||
|
|
5c2d7a18c9 | ||
|
|
2567404ab6 | ||
|
|
1faad825f4 | ||
|
|
b56614e9b8 | ||
|
|
25514e104a | ||
|
|
f79cc4a7a4 | ||
|
|
72f9daf9b6 | ||
|
|
bd2ca543c4 | ||
|
|
7beb2f7fae | ||
|
|
c4b9f4f622 | ||
|
|
655e6992f6 | ||
|
|
5cdaac00c1 | ||
|
|
05db6a6c29 | ||
|
|
57c732655e | ||
|
|
ee4f51a631 | ||
|
|
816b789bf0 | ||
|
|
55b823b27d | ||
|
|
89a49cf30e | ||
|
|
4cf95a6041 | ||
|
|
ab6fd304c4 | ||
|
|
29d6a5e2b8 | ||
|
|
86e60e3ba8 | ||
|
|
c6d87e5e18 | ||
|
|
a4bc7ecf27 | ||
|
|
6e52aefb37 | ||
|
|
cf06a266a8 | ||
|
|
81bdfb835d | ||
|
|
29c942f2a8 | ||
|
|
2320aa0da2 | ||
|
|
5cb51a191e | ||
|
|
7e846bb965 | ||
|
|
6e104f0570 | ||
|
|
42fc7ca6a0 | ||
|
|
a4886c404a | ||
|
|
f94f479358 | ||
|
|
d245bc891e | ||
|
|
894e9bc5d4 | ||
|
|
44cc9c04ea | ||
|
|
05ac415780 | ||
|
|
3e7e426b36 | ||
|
|
2a9979e256 | ||
|
|
90cd724be1 | ||
|
|
e41619b1fc | ||
|
|
ec6ce08cd0 | ||
|
|
4ddbaeea32 | ||
|
|
b35dd76dca | ||
|
|
37ad60fe25 | ||
|
|
a1d23f6613 | ||
|
|
45ddc39c1d | ||
|
|
34df1f588b | ||
|
|
b31d37eac5 | ||
|
|
db6285fb55 | ||
|
|
4e1a8b1fe5 | ||
|
|
5472ef626c | ||
|
|
20f34d9776 | ||
|
|
ef473b1f09 | ||
|
|
8760ec4827 | ||
|
|
54afa3ac7a | ||
|
|
a2ecbdaa31 | ||
|
|
896aede340 | ||
|
|
74b41637de | ||
|
|
c8cc3eacc9 | ||
|
|
2828da3c4c | ||
|
|
233bdf105f | ||
|
|
71b938f608 | ||
|
|
146549260a | ||
|
|
bec2b4f094 | ||
|
|
2c684ffd32 | ||
|
|
556a83022d | ||
|
|
1b26a2a561 | ||
|
|
a5d7094a45 | ||
|
|
d31a57cf5f | ||
|
|
bccb7e87d1 | ||
|
|
2e8c101b4a | ||
|
|
4224c08cac | ||
|
|
878b990fcd | ||
|
|
dee5ef2dfd | ||
|
|
3d919db0c0 | ||
|
|
b9a4f3336a | ||
|
|
ea7a6a0321 | ||
|
|
f294c4e023 | ||
|
|
b65e3c4444 | ||
|
|
7bcc8b3e5c | ||
|
|
aa0d8f20c1 | ||
|
|
7e06c81894 | ||
|
|
0cced530ea | ||
|
|
b1fdb220f4 | ||
|
|
74f3a2f4b5 | ||
|
|
47b62480af | ||
|
|
a5c852660b | ||
|
|
905fdd3e08 | ||
|
|
ca998df912 | ||
|
|
3039dd194b | ||
|
|
10ae0f9511 | ||
|
|
138fe8516a | ||
|
|
79b8b560d2 | ||
|
|
4aa12e10c0 | ||
|
|
f01af43eb0 |
214
.clang-format
Normal file
214
.clang-format
Normal file
@@ -0,0 +1,214 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
QualifierAlignment: Leave
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: true
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
PackConstructorInitializers: NextLine
|
||||
BasedOnStyle: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^<ext/.*\.h>'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: true
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequires: false
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Never
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Left
|
||||
PPIndentWidth: -1
|
||||
RawStringFormats:
|
||||
- Language: Cpp
|
||||
Delimiters:
|
||||
- cc
|
||||
- CC
|
||||
- cpp
|
||||
- Cpp
|
||||
- CPP
|
||||
- 'c++'
|
||||
- 'C++'
|
||||
CanonicalDelimiter: ''
|
||||
BasedOnStyle: google
|
||||
- Language: TextProto
|
||||
Delimiters:
|
||||
- pb
|
||||
- PB
|
||||
- proto
|
||||
- PROTO
|
||||
EnclosingFunctions:
|
||||
- EqualsProto
|
||||
- EquivToProto
|
||||
- PARSE_PARTIAL_TEXT_PROTO
|
||||
- PARSE_TEST_PROTO
|
||||
- PARSE_TEXT_PROTO
|
||||
- ParseTextOrDie
|
||||
- ParseTextProtoOrDie
|
||||
- ParseTestProto
|
||||
- ParsePartialTestProto
|
||||
CanonicalDelimiter: pb
|
||||
BasedOnStyle: google
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Auto
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
||||
77
.github/workflows/jvm_tests.yml
vendored
Normal file
77
.github/workflows/jvm_tests.yml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
name: XGBoost-JVM-Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
test-with-jvm:
|
||||
name: Test JVM on OS ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest, macos-11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.8'
|
||||
architecture: 'x64'
|
||||
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install wheel setuptools
|
||||
python -m pip install awscli
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('./jvm-packages/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
- name: Test XGBoost4J
|
||||
run: |
|
||||
cd jvm-packages
|
||||
mvn test -B -pl :xgboost4j_2.12
|
||||
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
id: extract_branch
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')) &&
|
||||
matrix.os == 'windows-latest'
|
||||
|
||||
- name: Publish artifact xgboost4j.dll to S3
|
||||
run: |
|
||||
cd lib/
|
||||
Rename-Item -Path xgboost4j.dll -NewName xgboost4j_${{ github.sha }}.dll
|
||||
dir
|
||||
python -m awscli s3 cp xgboost4j_${{ github.sha }}.dll s3://xgboost-nightly-builds/${{ steps.extract_branch.outputs.branch }}/ --acl public-read
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')) &&
|
||||
matrix.os == 'windows-latest'
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_IAM_S3_UPLOADER }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_IAM_S3_UPLOADER }}
|
||||
|
||||
|
||||
- name: Test XGBoost4J-Spark
|
||||
run: |
|
||||
rm -rfv build/
|
||||
cd jvm-packages
|
||||
mvn -B test
|
||||
if: matrix.os == 'ubuntu-latest' # Distributed training doesn't work on Windows
|
||||
env:
|
||||
RABIT_MOCK: ON
|
||||
191
.github/workflows/main.yml
vendored
191
.github/workflows/main.yml
vendored
@@ -6,6 +6,9 @@ name: XGBoost-CI
|
||||
# events but only for the master branch
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
gtest-cpu:
|
||||
@@ -14,26 +17,24 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-10.15]
|
||||
os: [macos-11]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Install system packages
|
||||
run: |
|
||||
brew install lz4 ninja libomp
|
||||
brew install ninja libomp
|
||||
- name: Build gtest binary
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DGOOGLE_TEST=ON -DUSE_OPENMP=ON -DUSE_DMLC_GTEST=ON -DPLUGIN_LZ4=ON -DPLUGIN_DENSE_PARSER=ON -GNinja
|
||||
cmake .. -DGOOGLE_TEST=ON -DUSE_OPENMP=ON -DUSE_DMLC_GTEST=ON -DPLUGIN_DENSE_PARSER=ON -GNinja
|
||||
ninja -v
|
||||
- name: Run gtest binary
|
||||
run: |
|
||||
cd build
|
||||
# libomp internal error:
|
||||
# OMP: Error #131: Thread identifier invalid.
|
||||
./testxgboost --gtest_filter="-HistIndexCreationWithExternalMemory.Test"
|
||||
./testxgboost
|
||||
ctest -R TestXGBoostCLI --extra-verbose
|
||||
|
||||
gtest-cpu-nonomp:
|
||||
@@ -62,45 +63,6 @@ jobs:
|
||||
cd build
|
||||
ctest --extra-verbose
|
||||
|
||||
python-sdist-test:
|
||||
name: Test installing XGBoost Python source package
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-10.15, windows-latest]
|
||||
python-version: ["3.8"]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Install osx system dependencies
|
||||
if: matrix.os == 'macos-10.15'
|
||||
run: |
|
||||
brew install ninja libomp
|
||||
- name: Install Ubuntu system dependencies
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
sudo apt-get install -y --no-install-recommends ninja-build
|
||||
- uses: conda-incubator/setup-miniconda@v2
|
||||
with:
|
||||
auto-update-conda: true
|
||||
python-version: ${{ matrix.python-version }}
|
||||
activate-environment: test
|
||||
- name: Display Conda env
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda info
|
||||
conda list
|
||||
- name: Build and install XGBoost
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
cd python-package
|
||||
python --version
|
||||
python setup.py sdist
|
||||
pip install -v ./dist/xgboost-*.tar.gz
|
||||
cd ..
|
||||
python -c 'import xgboost'
|
||||
|
||||
c-api-demo:
|
||||
name: Test installing XGBoost lib + building the C API demo
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -113,143 +75,78 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Install system packages
|
||||
run: |
|
||||
sudo apt-get install -y --no-install-recommends ninja-build
|
||||
- uses: conda-incubator/setup-miniconda@v2
|
||||
- uses: mamba-org/provision-with-micromamba@f347426e5745fe3dfc13ec5baf20496990d0281f # v14
|
||||
with:
|
||||
auto-update-conda: true
|
||||
python-version: ${{ matrix.python-version }}
|
||||
activate-environment: test
|
||||
cache-downloads: true
|
||||
cache-env: true
|
||||
environment-name: cpp_test
|
||||
environment-file: tests/ci_build/conda_env/cpp_test.yml
|
||||
- name: Display Conda env
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda info
|
||||
conda list
|
||||
- name: Build and install XGBoost
|
||||
|
||||
- name: Build and install XGBoost static library
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DBUILD_STATIC_LIB=ON -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -GNinja
|
||||
ninja -v install
|
||||
- name: Build and run C API demo
|
||||
cd -
|
||||
- name: Build and run C API demo with static
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
pushd .
|
||||
cd demo/c-api/
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -GNinja -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
|
||||
ninja -v
|
||||
ctest
|
||||
cd ..
|
||||
./build/api-demo
|
||||
rm -rf ./build
|
||||
popd
|
||||
|
||||
test-with-jvm:
|
||||
name: Test JVM on OS ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.8'
|
||||
architecture: 'x64'
|
||||
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Install Python packages
|
||||
- name: Build and install XGBoost shared library
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
python -m pip install wheel setuptools
|
||||
python -m pip install awscli
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('./jvm-packages/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
- name: Test XGBoost4J
|
||||
cd build
|
||||
cmake .. -DBUILD_STATIC_LIB=OFF -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -GNinja
|
||||
ninja -v install
|
||||
cd -
|
||||
- name: Build and run C API demo with shared
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
cd jvm-packages
|
||||
mvn test -B -pl :xgboost4j_2.12
|
||||
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
id: extract_branch
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')) &&
|
||||
matrix.os == 'windows-latest'
|
||||
|
||||
- name: Publish artifact xgboost4j.dll to S3
|
||||
run: |
|
||||
cd lib/
|
||||
Rename-Item -Path xgboost4j.dll -NewName xgboost4j_${{ github.sha }}.dll
|
||||
dir
|
||||
python -m awscli s3 cp xgboost4j_${{ github.sha }}.dll s3://xgboost-nightly-builds/${{ steps.extract_branch.outputs.branch }}/ --acl public-read
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')) &&
|
||||
matrix.os == 'windows-latest'
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_IAM_S3_UPLOADER }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_IAM_S3_UPLOADER }}
|
||||
|
||||
|
||||
- name: Test XGBoost4J-Spark
|
||||
run: |
|
||||
rm -rfv build/
|
||||
cd jvm-packages
|
||||
mvn -B test
|
||||
if: matrix.os == 'ubuntu-latest' # Distributed training doesn't work on Windows
|
||||
env:
|
||||
RABIT_MOCK: ON
|
||||
pushd .
|
||||
cd demo/c-api/
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -GNinja -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
|
||||
ninja -v
|
||||
ctest
|
||||
popd
|
||||
./tests/ci_build/verify_link.sh ./demo/c-api/build/basic/api-demo
|
||||
./tests/ci_build/verify_link.sh ./demo/c-api/build/external-memory/external-memory-demo
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
name: Code linting for Python and C++
|
||||
name: Code linting for C++
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
python-version: "3.8"
|
||||
architecture: 'x64'
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install wheel setuptools
|
||||
python -m pip install pylint cpplint numpy scipy scikit-learn
|
||||
python -m pip install wheel setuptools cpplint pylint
|
||||
- name: Run lint
|
||||
run: |
|
||||
make lint
|
||||
|
||||
mypy:
|
||||
runs-on: ubuntu-latest
|
||||
name: Type checking for Python
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
architecture: 'x64'
|
||||
- name: Install Python packages
|
||||
run: |
|
||||
python -m pip install wheel setuptools mypy dask[complete] distributed
|
||||
- name: Run mypy
|
||||
run: |
|
||||
make mypy
|
||||
LINT_LANG=cpp make lint
|
||||
|
||||
doxygen:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -260,7 +157,7 @@ jobs:
|
||||
submodules: 'true'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
python-version: "3.8"
|
||||
architecture: 'x64'
|
||||
- name: Install system packages
|
||||
run: |
|
||||
@@ -297,7 +194,7 @@ jobs:
|
||||
submodules: 'true'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.8'
|
||||
python-version: "3.8"
|
||||
architecture: 'x64'
|
||||
- name: Install system packages
|
||||
run: |
|
||||
|
||||
210
.github/workflows/python_tests.yml
vendored
Normal file
210
.github/workflows/python_tests.yml
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
name: XGBoost-Python-Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
python-mypy-lint:
|
||||
runs-on: ubuntu-latest
|
||||
name: Type and format checks for the Python package
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
python-version: ["3.8"]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- uses: conda-incubator/setup-miniconda@v2
|
||||
with:
|
||||
auto-update-conda: true
|
||||
python-version: ${{ matrix.python-version }}
|
||||
activate-environment: python_lint
|
||||
environment-file: tests/ci_build/conda_env/python_lint.yml
|
||||
- name: Display Conda env
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda info
|
||||
conda list
|
||||
- name: Run mypy
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
python tests/ci_build/lint_python.py --format=0 --type-check=1 --pylint=0
|
||||
- name: Run formatter
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
python tests/ci_build/lint_python.py --format=1 --type-check=0 --pylint=0
|
||||
- name: Run pylint
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
python tests/ci_build/lint_python.py --format=0 --type-check=0 --pylint=1
|
||||
|
||||
python-sdist-test-on-Linux:
|
||||
# Mismatched glibcxx version between system and conda forge.
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Test installing XGBoost Python source package on ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@e2f20e631ae6d7dd3b768f56a5d2af784dd54791 # v2.5.0
|
||||
with:
|
||||
submodules: 'true'
|
||||
- uses: mamba-org/provision-with-micromamba@f347426e5745fe3dfc13ec5baf20496990d0281f # v14
|
||||
with:
|
||||
cache-downloads: true
|
||||
cache-env: false
|
||||
environment-name: sdist_test
|
||||
environment-file: tests/ci_build/conda_env/sdist_test.yml
|
||||
- name: Display Conda env
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda info
|
||||
conda list
|
||||
- name: Build and install XGBoost
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
cd python-package
|
||||
python --version
|
||||
python setup.py sdist
|
||||
pip install -v ./dist/xgboost-*.tar.gz
|
||||
cd ..
|
||||
python -c 'import xgboost'
|
||||
|
||||
python-sdist-test:
|
||||
# Use system toolchain instead of conda toolchain for macos and windows.
|
||||
# MacOS has linker error if clang++ from conda-forge is used
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Test installing XGBoost Python source package on ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11, windows-latest]
|
||||
python-version: ["3.8"]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Install osx system dependencies
|
||||
if: matrix.os == 'macos-11'
|
||||
run: |
|
||||
brew install ninja libomp
|
||||
- uses: conda-incubator/setup-miniconda@35d1405e78aa3f784fe3ce9a2eb378d5eeb62169 # v2.1.1
|
||||
with:
|
||||
auto-update-conda: true
|
||||
python-version: ${{ matrix.python-version }}
|
||||
activate-environment: test
|
||||
- name: Display Conda env
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda info
|
||||
conda list
|
||||
- name: Build and install XGBoost
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
cd python-package
|
||||
python --version
|
||||
python setup.py sdist
|
||||
pip install -v ./dist/xgboost-*.tar.gz
|
||||
cd ..
|
||||
python -c 'import xgboost'
|
||||
|
||||
python-tests-on-macos:
|
||||
name: Test XGBoost Python package on ${{ matrix.config.os }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {os: macos-11}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@e2f20e631ae6d7dd3b768f56a5d2af784dd54791 # v2.5.0
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: mamba-org/provision-with-micromamba@f347426e5745fe3dfc13ec5baf20496990d0281f # v14
|
||||
with:
|
||||
cache-downloads: true
|
||||
cache-env: false
|
||||
environment-name: macos_test
|
||||
environment-file: tests/ci_build/conda_env/macos_cpu_test.yml
|
||||
|
||||
- name: Display Conda env
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda info
|
||||
conda list
|
||||
|
||||
- name: Build XGBoost on macos
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
brew install ninja
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
# Set prefix, to use OpenMP library from Conda env
|
||||
# See https://github.com/dmlc/xgboost/issues/7039#issuecomment-1025038228
|
||||
# to learn why we don't use libomp from Homebrew.
|
||||
cmake .. -GNinja -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
|
||||
ninja
|
||||
|
||||
- name: Install Python package
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
cd python-package
|
||||
python --version
|
||||
python setup.py install
|
||||
|
||||
- name: Test Python package
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
pytest -s -v -rxXs --durations=0 ./tests/python
|
||||
|
||||
python-tests-on-win:
|
||||
name: Test XGBoost Python package on ${{ matrix.config.os }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {os: windows-latest, python-version: '3.8'}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: conda-incubator/setup-miniconda@v2
|
||||
with:
|
||||
auto-update-conda: true
|
||||
python-version: ${{ matrix.config.python-version }}
|
||||
activate-environment: win64_env
|
||||
environment-file: tests/ci_build/conda_env/win64_cpu_test.yml
|
||||
|
||||
- name: Display Conda env
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda info
|
||||
conda list
|
||||
|
||||
- name: Build XGBoost on Windows
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
mkdir build_msvc
|
||||
cd build_msvc
|
||||
cmake .. -G"Visual Studio 17 2022" -DCMAKE_CONFIGURATION_TYPES="Release" -A x64 -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON
|
||||
cmake --build . --config Release --parallel $(nproc)
|
||||
|
||||
- name: Install Python package
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
cd python-package
|
||||
python --version
|
||||
python setup.py bdist_wheel --universal
|
||||
pip install ./dist/*.whl
|
||||
|
||||
- name: Test Python package
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
pytest -s -v -rxXs --durations=0 ./tests/python
|
||||
41
.github/workflows/python_wheels.yml
vendored
Normal file
41
.github/workflows/python_wheels.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: XGBoost-Python-Wheels
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
python-wheels:
|
||||
name: Build wheel for ${{ matrix.platform_id }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-latest
|
||||
platform_id: macosx_x86_64
|
||||
- os: macos-latest
|
||||
platform_id: macosx_arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.8"
|
||||
- name: Build wheels
|
||||
run: bash tests/ci_build/build_python_wheels.sh ${{ matrix.platform_id }} ${{ github.sha }}
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
id: extract_branch
|
||||
if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
|
||||
- name: Upload Python wheel
|
||||
if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
|
||||
run: |
|
||||
python -m pip install awscli
|
||||
python -m awscli s3 cp wheelhouse/*.whl s3://xgboost-nightly-builds/${{ steps.extract_branch.outputs.branch }}/ --acl public-read
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_IAM_S3_UPLOADER }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_IAM_S3_UPLOADER }}
|
||||
5
.github/workflows/r_nold.yml
vendored
5
.github/workflows/r_nold.yml
vendored
@@ -8,7 +8,10 @@ on:
|
||||
types: [created]
|
||||
|
||||
env:
|
||||
R_PACKAGES: c('XML', 'igraph', 'data.table', 'magrittr', 'ggplot2', 'DiagrammeR', 'Ckmeans.1d.dp', 'vcd', 'testthat', 'lintr', 'knitr', 'rmarkdown', 'e1071', 'cplm', 'devtools', 'float', 'titanic')
|
||||
R_PACKAGES: c('XML', 'igraph', 'data.table', 'ggplot2', 'DiagrammeR', 'Ckmeans.1d.dp', 'vcd', 'testthat', 'lintr', 'knitr', 'rmarkdown', 'e1071', 'cplm', 'devtools', 'float', 'titanic')
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
test-R-noLD:
|
||||
|
||||
74
.github/workflows/r_tests.yml
vendored
74
.github/workflows/r_tests.yml
vendored
@@ -3,7 +3,12 @@ name: XGBoost-R-Tests
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
R_PACKAGES: c('XML', 'igraph', 'data.table', 'magrittr', 'ggplot2', 'DiagrammeR', 'Ckmeans.1d.dp', 'vcd', 'testthat', 'lintr', 'knitr', 'rmarkdown', 'e1071', 'cplm', 'devtools', 'float', 'titanic')
|
||||
R_PACKAGES: c('XML', 'data.table', 'ggplot2', 'DiagrammeR', 'Ckmeans.1d.dp', 'vcd', 'testthat', 'lintr', 'knitr', 'rmarkdown', 'e1071', 'cplm', 'devtools', 'float', 'titanic')
|
||||
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
|
||||
_R_CHECK_EXAMPLE_TIMING_CPU_TO_ELAPSED_THRESHOLD_: 2.5
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
lintr:
|
||||
@@ -12,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- {os: windows-latest, r: 'release', compiler: 'mingw', build: 'autotools'}
|
||||
- {os: ubuntu-latest, r: 'release'}
|
||||
env:
|
||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
||||
RSPM: ${{ matrix.config.rspm }}
|
||||
@@ -22,22 +27,35 @@ jobs:
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
- uses: r-lib/actions/setup-r@v2
|
||||
with:
|
||||
r-version: ${{ matrix.config.r }}
|
||||
|
||||
- name: Cache R packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-r-${{ matrix.config.r }}-5-${{ hashFiles('R-package/DESCRIPTION') }}
|
||||
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-5-${{ hashFiles('R-package/DESCRIPTION') }}
|
||||
|
||||
- name: Install dependencies
|
||||
shell: Rscript {0}
|
||||
run: |
|
||||
install.packages(${{ env.R_PACKAGES }},
|
||||
repos = 'http://cloud.r-project.org',
|
||||
dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
||||
- name: Install igraph on Windows
|
||||
shell: Rscript {0}
|
||||
if: matrix.config.os == 'windows-latest'
|
||||
run: |
|
||||
install.packages('igraph', type='binary')
|
||||
|
||||
- name: Run lintr
|
||||
run: |
|
||||
cd R-package
|
||||
R.exe CMD INSTALL .
|
||||
Rscript.exe tests/helper_scripts/run_lint.R
|
||||
R CMD INSTALL .
|
||||
# Disable lintr errors for now: https://github.com/dmlc/xgboost/issues/8012
|
||||
Rscript tests/helper_scripts/run_lint.R || true
|
||||
|
||||
test-with-R:
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
@@ -46,11 +64,12 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {os: windows-2016, r: 'release', compiler: 'mingw', build: 'autotools'}
|
||||
- {os: windows-2016, r: 'release', compiler: 'msvc', build: 'cmake'}
|
||||
- {os: windows-2016, r: 'release', compiler: 'mingw', build: 'cmake'}
|
||||
- {os: windows-latest, r: 'release', compiler: 'mingw', build: 'autotools'}
|
||||
- {os: windows-latest, r: 'release', compiler: 'msvc', build: 'cmake'}
|
||||
- {os: windows-latest, r: 'release', compiler: 'mingw', build: 'cmake'}
|
||||
env:
|
||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
||||
_R_CHECK_EXAMPLE_TIMING_CPU_TO_ELAPSED_THRESHOLD_: 2.5
|
||||
RSPM: ${{ matrix.config.rspm }}
|
||||
|
||||
steps:
|
||||
@@ -58,20 +77,37 @@ jobs:
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
- uses: r-lib/actions/setup-r@v2
|
||||
with:
|
||||
r-version: ${{ matrix.config.r }}
|
||||
|
||||
- name: Cache R packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-r-${{ matrix.config.r }}-5-${{ hashFiles('R-package/DESCRIPTION') }}
|
||||
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-5-${{ hashFiles('R-package/DESCRIPTION') }}
|
||||
|
||||
- name: Install dependencies
|
||||
shell: Rscript {0}
|
||||
if: matrix.config.os != 'windows-latest'
|
||||
run: |
|
||||
install.packages(${{ env.R_PACKAGES }},
|
||||
repos = 'http://cloud.r-project.org',
|
||||
dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
||||
|
||||
- name: Install binary dependencies
|
||||
shell: Rscript {0}
|
||||
if: matrix.config.os == 'windows-latest'
|
||||
run: |
|
||||
install.packages(${{ env.R_PACKAGES }},
|
||||
type = 'binary',
|
||||
repos = 'http://cloud.r-project.org',
|
||||
dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
python-version: "3.8"
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Test R
|
||||
@@ -87,20 +123,31 @@ jobs:
|
||||
config:
|
||||
- {r: 'release'}
|
||||
|
||||
env:
|
||||
_R_CHECK_EXAMPLE_TIMING_CPU_TO_ELAPSED_THRESHOLD_: 2.5
|
||||
MAKE: "make -j$(nproc)"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
- uses: r-lib/actions/setup-r@v2
|
||||
with:
|
||||
r-version: ${{ matrix.config.r }}
|
||||
|
||||
- uses: r-lib/actions/setup-tinytex@master
|
||||
- uses: r-lib/actions/setup-tinytex@v2
|
||||
|
||||
- name: Install system packages
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install libcurl4-openssl-dev libssl-dev libssh2-1-dev libgit2-dev pandoc pandoc-citeproc
|
||||
sudo apt-get update && sudo apt-get install libcurl4-openssl-dev libssl-dev libssh2-1-dev libgit2-dev pandoc pandoc-citeproc libglpk-dev
|
||||
|
||||
- name: Cache R packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-r-${{ matrix.config.r }}-5-${{ hashFiles('R-package/DESCRIPTION') }}
|
||||
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-5-${{ hashFiles('R-package/DESCRIPTION') }}
|
||||
|
||||
- name: Install dependencies
|
||||
shell: Rscript {0}
|
||||
@@ -108,6 +155,7 @@ jobs:
|
||||
install.packages(${{ env.R_PACKAGES }},
|
||||
repos = 'http://cloud.r-project.org',
|
||||
dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
||||
install.packages('igraph', repos = 'http://cloud.r-project.org', dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
||||
|
||||
- name: Check R Package
|
||||
run: |
|
||||
|
||||
54
.github/workflows/scorecards.yml
vendored
Normal file
54
.github/workflows/scorecards.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: Scorecards supply-chain security
|
||||
on:
|
||||
# Only the default branch is supported.
|
||||
branch_protection_rule:
|
||||
schedule:
|
||||
- cron: '17 2 * * 6'
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecards analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Used to receive a badge.
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@865b4092859256271290c77adbd10a43f4779972 # tag=v2.0.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
|
||||
# Publish the results for public repositories to enable scorecard badges. For more details, see
|
||||
# https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories, `publish_results` will automatically be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # tag=v3.0.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # tag=v1.0.26
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -52,6 +52,8 @@ Debug
|
||||
R-package.Rproj
|
||||
*.cache*
|
||||
.mypy_cache/
|
||||
doxygen
|
||||
|
||||
# java
|
||||
java/xgboost4j/target
|
||||
java/xgboost4j/tmp
|
||||
@@ -63,6 +65,7 @@ nb-configuration*
|
||||
# Eclipse
|
||||
.project
|
||||
.cproject
|
||||
.classpath
|
||||
.pydevproject
|
||||
.settings/
|
||||
build
|
||||
@@ -96,8 +99,11 @@ metastore_db
|
||||
R-package/src/Makevars
|
||||
*.lib
|
||||
|
||||
# Visual Studio Code
|
||||
/.vscode/
|
||||
# Visual Studio
|
||||
.vs/
|
||||
CMakeSettings.json
|
||||
*.ilk
|
||||
*.pdb
|
||||
|
||||
# IntelliJ/CLion
|
||||
.idea
|
||||
@@ -125,3 +131,11 @@ credentials.csv
|
||||
*.pub
|
||||
*.rdp
|
||||
*_rsa
|
||||
|
||||
# Visual Studio code + extensions
|
||||
.vscode
|
||||
.metals
|
||||
.bloop
|
||||
|
||||
# hypothesis python tests
|
||||
.hypothesis
|
||||
35
.readthedocs.yaml
Normal file
35
.readthedocs.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
submodules:
|
||||
include: all
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.8"
|
||||
apt_packages:
|
||||
- graphviz
|
||||
- cmake
|
||||
- g++
|
||||
- doxygen
|
||||
- ninja-build
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: doc/conf.py
|
||||
|
||||
# If using Sphinx, optionally build your docs in additional formats such as PDF
|
||||
formats:
|
||||
- pdf
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
install:
|
||||
- requirements: doc/requirements.txt
|
||||
system_packages: true
|
||||
19
.travis.yml
19
.travis.yml
@@ -4,19 +4,15 @@ dist: bionic
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: "PR16i9F8QtNwn99C5NDp8nptAS+97xwDtXEJJfEiEVhxPaaRkOp0MPWhogCaK0Eclxk1TqkgWbdXFknwGycX620AzZWa/A1K3gAs+GrpzqhnPMuoBJ0Z9qxXTbSJvCyvMbYwVrjaxc/zWqdMU8waWz8A7iqKGKs/SqbQ3rO6v7c="
|
||||
- secure: "dAGAjBokqm/0nVoLMofQni/fWIBcYSmdq4XvCBX1ZAMDsWnuOfz/4XCY6h2lEI1rVHZQ+UdZkc9PioOHGPZh5BnvE49/xVVWr9c4/61lrDOlkD01ZjSAeoV0fAZq+93V/wPl4QV+MM+Sem9hNNzFSbN5VsQLAiWCSapWsLdKzqA="
|
||||
- secure: "lqkL5SCM/CBwgVb1GWoOngpojsa0zCSGcvF0O3/45rBT1EpNYtQ4LRJ1+XcHi126vdfGoim/8i7AQhn5eOgmZI8yAPBeoUZ5zSrejD3RUpXr2rXocsvRRP25Z4mIuAGHD9VAHtvTdhBZRVV818W02pYduSzAeaY61q/lU3xmWsE="
|
||||
- secure: "mzms6X8uvdhRWxkPBMwx+mDl3d+V1kUpZa7UgjT+dr4rvZMzvKtjKp/O0JZZVogdgZjUZf444B98/7AvWdSkGdkfz2QdmhWmXzNPfNuHtmfCYMdijsgFIGLuD3GviFL/rBiM2vgn32T3QqFiEJiC5StparnnXimPTc9TpXQRq5c="
|
||||
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- os: osx
|
||||
arch: amd64
|
||||
osx_image: xcode10.2
|
||||
env: TASK=python_test
|
||||
- os: osx
|
||||
arch: amd64
|
||||
osx_image: xcode10.2
|
||||
env: TASK=java_test
|
||||
- os: linux
|
||||
arch: s390x
|
||||
env: TASK=s390x_test
|
||||
|
||||
# dependent brew packages
|
||||
# the dependencies from homebrew is installed manually from setup script due to outdated image from travis.
|
||||
@@ -25,13 +21,10 @@ addons:
|
||||
update: false
|
||||
apt:
|
||||
packages:
|
||||
- snapd
|
||||
- unzip
|
||||
|
||||
before_install:
|
||||
- source tests/travis/travis_setup_env.sh
|
||||
- if [ "${TASK}" != "python_sdist_test" ]; then export PYTHONPATH=${PYTHONPATH}:${PWD}/python-package; fi
|
||||
- echo "MAVEN_OPTS='-Xmx2g -XX:MaxPermSize=1024m -XX:ReservedCodeCacheSize=512m -Dorg.slf4j.simpleLogger.defaultLogLevel=error'" > ~/.mavenrc
|
||||
|
||||
install:
|
||||
- source tests/travis/setup.sh
|
||||
|
||||
148
CMakeLists.txt
148
CMakeLists.txt
@@ -1,9 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(xgboost LANGUAGES CXX C VERSION 1.4.2)
|
||||
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
||||
project(xgboost LANGUAGES CXX C VERSION 1.7.4)
|
||||
include(cmake/Utils.cmake)
|
||||
list(APPEND CMAKE_MODULE_PATH "${xgboost_SOURCE_DIR}/cmake/modules")
|
||||
cmake_policy(SET CMP0022 NEW)
|
||||
cmake_policy(SET CMP0079 NEW)
|
||||
cmake_policy(SET CMP0076 NEW)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
||||
cmake_policy(SET CMP0063 NEW)
|
||||
|
||||
@@ -28,6 +29,7 @@ set_default_configuration_release()
|
||||
option(BUILD_C_DOC "Build documentation for C APIs using Doxygen." OFF)
|
||||
option(USE_OPENMP "Build with OpenMP support." ON)
|
||||
option(BUILD_STATIC_LIB "Build static library" OFF)
|
||||
option(FORCE_SHARED_CRT "Build with dynamic CRT on Windows (/MD)" OFF)
|
||||
option(RABIT_BUILD_MPI "Build MPI" OFF)
|
||||
## Bindings
|
||||
option(JVM_BINDINGS "Build JVM bindings" OFF)
|
||||
@@ -49,6 +51,7 @@ option(HIDE_CXX_SYMBOLS "Build shared library and hide all C++ symbols" OFF)
|
||||
option(USE_CUDA "Build with GPU acceleration" OFF)
|
||||
option(USE_NCCL "Build with NCCL to enable distributed GPU support." OFF)
|
||||
option(BUILD_WITH_SHARED_NCCL "Build with shared NCCL library." OFF)
|
||||
option(BUILD_WITH_CUDA_CUB "Build with cub in CUDA installation" OFF)
|
||||
set(GPU_COMPUTE_VER "" CACHE STRING
|
||||
"Semicolon separated list of compute versions to be built against, e.g. '35;61'")
|
||||
## Copied From dmlc
|
||||
@@ -62,9 +65,9 @@ set(ENABLED_SANITIZERS "address" "leak" CACHE STRING
|
||||
"Semicolon separated list of sanitizer names. E.g 'address;leak'. Supported sanitizers are
|
||||
address, leak, undefined and thread.")
|
||||
## Plugins
|
||||
option(PLUGIN_LZ4 "Build lz4 plugin" OFF)
|
||||
option(PLUGIN_DENSE_PARSER "Build dense parser plugin" OFF)
|
||||
option(PLUGIN_RMM "Build with RAPIDS Memory Manager (RMM)" OFF)
|
||||
option(PLUGIN_FEDERATED "Build with Federated Learning" OFF)
|
||||
## TODO: 1. Add check if DPC++ compiler is used for building
|
||||
option(PLUGIN_UPDATER_ONEAPI "DPC++ updater" OFF)
|
||||
option(ADD_PKGCONFIG "Add xgboost.pc into system." ON)
|
||||
@@ -92,6 +95,9 @@ endif (R_LIB AND GOOGLE_TEST)
|
||||
if (USE_AVX)
|
||||
message(SEND_ERROR "The option 'USE_AVX' is deprecated as experimental AVX features have been removed from XGBoost.")
|
||||
endif (USE_AVX)
|
||||
if (PLUGIN_LZ4)
|
||||
message(SEND_ERROR "The option 'PLUGIN_LZ4' is removed from XGBoost.")
|
||||
endif (PLUGIN_LZ4)
|
||||
if (PLUGIN_RMM AND NOT (USE_CUDA))
|
||||
message(SEND_ERROR "`PLUGIN_RMM` must be enabled with `USE_CUDA` flag.")
|
||||
endif (PLUGIN_RMM AND NOT (USE_CUDA))
|
||||
@@ -109,6 +115,23 @@ endif (ENABLE_ALL_WARNINGS)
|
||||
if (BUILD_STATIC_LIB AND (R_LIB OR JVM_BINDINGS))
|
||||
message(SEND_ERROR "Cannot build a static library libxgboost.a when R or JVM packages are enabled.")
|
||||
endif (BUILD_STATIC_LIB AND (R_LIB OR JVM_BINDINGS))
|
||||
if (PLUGIN_RMM AND (NOT BUILD_WITH_CUDA_CUB))
|
||||
message(SEND_ERROR "Cannot build with RMM using cub submodule.")
|
||||
endif (PLUGIN_RMM AND (NOT BUILD_WITH_CUDA_CUB))
|
||||
if (PLUGIN_FEDERATED)
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
message(SEND_ERROR "Cannot cross compile with federated learning support")
|
||||
endif ()
|
||||
if (BUILD_STATIC_LIB)
|
||||
message(SEND_ERROR "Cannot build static lib with federated learning support")
|
||||
endif ()
|
||||
if (R_LIB OR JVM_BINDINGS)
|
||||
message(SEND_ERROR "Cannot enable federated learning support when R or JVM packages are enabled.")
|
||||
endif ()
|
||||
if (WIN32)
|
||||
message(SEND_ERROR "Federated learning not supported for Windows platform")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
#-- Sanitizer
|
||||
if (USE_SANITIZER)
|
||||
@@ -117,18 +140,22 @@ if (USE_SANITIZER)
|
||||
endif (USE_SANITIZER)
|
||||
|
||||
if (USE_CUDA)
|
||||
SET(USE_OPENMP ON CACHE BOOL "CUDA requires OpenMP" FORCE)
|
||||
set(USE_OPENMP ON CACHE BOOL "CUDA requires OpenMP" FORCE)
|
||||
# `export CXX=' is ignored by CMake CUDA.
|
||||
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER})
|
||||
message(STATUS "Configured CUDA host compiler: ${CMAKE_CUDA_HOST_COMPILER}")
|
||||
|
||||
enable_language(CUDA)
|
||||
if (${CMAKE_CUDA_COMPILER_VERSION} VERSION_LESS 10.0)
|
||||
message(FATAL_ERROR "CUDA version must be at least 10.0!")
|
||||
if (${CMAKE_CUDA_COMPILER_VERSION} VERSION_LESS 11.0)
|
||||
message(FATAL_ERROR "CUDA version must be at least 11.0!")
|
||||
endif()
|
||||
set(GEN_CODE "")
|
||||
format_gencode_flags("${GPU_COMPUTE_VER}" GEN_CODE)
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/gputreeshap)
|
||||
|
||||
if ((${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 11.4) AND (NOT BUILD_WITH_CUDA_CUB))
|
||||
set(BUILD_WITH_CUDA_CUB ON)
|
||||
endif ()
|
||||
endif (USE_CUDA)
|
||||
|
||||
if (FORCE_COLORED_OUTPUT AND (CMAKE_GENERATOR STREQUAL "Ninja") AND
|
||||
@@ -144,31 +171,54 @@ if (USE_OPENMP)
|
||||
# Require CMake 3.16+ on Mac OSX, as previous versions of CMake had trouble locating
|
||||
# OpenMP on Mac. See https://github.com/dmlc/xgboost/pull/5146#issuecomment-568312706
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
endif (APPLE)
|
||||
find_package(OpenMP REQUIRED)
|
||||
find_package(OpenMP)
|
||||
if (NOT OpenMP_FOUND)
|
||||
# Try again with extra path info; required for libomp 15+ from Homebrew
|
||||
execute_process(COMMAND brew --prefix libomp
|
||||
OUTPUT_VARIABLE HOMEBREW_LIBOMP_PREFIX
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set(OpenMP_C_FLAGS
|
||||
"-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include")
|
||||
set(OpenMP_CXX_FLAGS
|
||||
"-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include")
|
||||
set(OpenMP_C_LIB_NAMES omp)
|
||||
set(OpenMP_CXX_LIB_NAMES omp)
|
||||
set(OpenMP_omp_LIBRARY ${HOMEBREW_LIBOMP_PREFIX}/lib/libomp.dylib)
|
||||
find_package(OpenMP REQUIRED)
|
||||
endif ()
|
||||
else ()
|
||||
find_package(OpenMP REQUIRED)
|
||||
endif ()
|
||||
endif (USE_OPENMP)
|
||||
#Add for IBM i
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "OS400")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -X64 qc <TARGET> <OBJECTS>")
|
||||
endif()
|
||||
|
||||
if (USE_NCCL)
|
||||
find_package(Nccl REQUIRED)
|
||||
endif (USE_NCCL)
|
||||
|
||||
# dmlc-core
|
||||
msvc_use_static_runtime()
|
||||
if (FORCE_SHARED_CRT)
|
||||
set(DMLC_FORCE_SHARED_CRT ON)
|
||||
endif ()
|
||||
add_subdirectory(${xgboost_SOURCE_DIR}/dmlc-core)
|
||||
set_target_properties(dmlc PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(dmlc PRIVATE
|
||||
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
||||
if (TARGET dmlc_unit_tests)
|
||||
target_compile_options(dmlc_unit_tests PRIVATE
|
||||
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
||||
endif (TARGET dmlc_unit_tests)
|
||||
endif (MSVC)
|
||||
if (ENABLE_ALL_WARNINGS)
|
||||
target_compile_options(dmlc PRIVATE -Wall -Wextra)
|
||||
endif (ENABLE_ALL_WARNINGS)
|
||||
|
||||
# rabit
|
||||
add_subdirectory(rabit)
|
||||
if (RABIT_BUILD_MPI)
|
||||
find_package(MPI REQUIRED)
|
||||
endif (RABIT_BUILD_MPI)
|
||||
|
||||
# core xgboost
|
||||
add_subdirectory(${xgboost_SOURCE_DIR}/src)
|
||||
@@ -179,9 +229,18 @@ if (R_LIB)
|
||||
add_subdirectory(${xgboost_SOURCE_DIR}/R-package)
|
||||
endif (R_LIB)
|
||||
|
||||
# This creates its own shared library `xgboost4j'.
|
||||
if (JVM_BINDINGS)
|
||||
add_subdirectory(${xgboost_SOURCE_DIR}/jvm-packages)
|
||||
endif (JVM_BINDINGS)
|
||||
|
||||
# Plugin
|
||||
add_subdirectory(${xgboost_SOURCE_DIR}/plugin)
|
||||
|
||||
if (PLUGIN_RMM)
|
||||
find_package(rmm REQUIRED)
|
||||
endif (PLUGIN_RMM)
|
||||
|
||||
#-- library
|
||||
if (BUILD_STATIC_LIB)
|
||||
add_library(xgboost STATIC)
|
||||
@@ -189,48 +248,37 @@ else (BUILD_STATIC_LIB)
|
||||
add_library(xgboost SHARED)
|
||||
endif (BUILD_STATIC_LIB)
|
||||
target_link_libraries(xgboost PRIVATE objxgboost)
|
||||
|
||||
if (USE_CUDA)
|
||||
xgboost_set_cuda_flags(xgboost)
|
||||
endif (USE_CUDA)
|
||||
|
||||
#-- Hide all C++ symbols
|
||||
if (HIDE_CXX_SYMBOLS)
|
||||
foreach(target objxgboost xgboost dmlc)
|
||||
set_target_properties(${target} PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
endforeach()
|
||||
endif (HIDE_CXX_SYMBOLS)
|
||||
|
||||
target_include_directories(xgboost
|
||||
INTERFACE
|
||||
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
|
||||
|
||||
# This creates its own shared library `xgboost4j'.
|
||||
if (JVM_BINDINGS)
|
||||
add_subdirectory(${xgboost_SOURCE_DIR}/jvm-packages)
|
||||
endif (JVM_BINDINGS)
|
||||
#-- End shared library
|
||||
|
||||
#-- CLI for xgboost
|
||||
add_executable(runxgboost ${xgboost_SOURCE_DIR}/src/cli_main.cc)
|
||||
target_link_libraries(runxgboost PRIVATE objxgboost)
|
||||
if (USE_NVTX)
|
||||
enable_nvtx(runxgboost)
|
||||
endif (USE_NVTX)
|
||||
|
||||
target_include_directories(runxgboost
|
||||
PRIVATE
|
||||
${xgboost_SOURCE_DIR}/include
|
||||
${xgboost_SOURCE_DIR}/dmlc-core/include
|
||||
${xgboost_SOURCE_DIR}/rabit/include)
|
||||
set_target_properties(
|
||||
runxgboost PROPERTIES
|
||||
OUTPUT_NAME xgboost
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON)
|
||||
${xgboost_SOURCE_DIR}/rabit/include
|
||||
)
|
||||
set_target_properties(runxgboost PROPERTIES OUTPUT_NAME xgboost)
|
||||
#-- End CLI for xgboost
|
||||
|
||||
# Common setup for all targets
|
||||
foreach(target xgboost objxgboost dmlc runxgboost)
|
||||
xgboost_target_properties(${target})
|
||||
xgboost_target_link_libraries(${target})
|
||||
xgboost_target_defs(${target})
|
||||
endforeach()
|
||||
|
||||
if (JVM_BINDINGS)
|
||||
xgboost_target_properties(xgboost4j)
|
||||
xgboost_target_link_libraries(xgboost4j)
|
||||
xgboost_target_defs(xgboost4j)
|
||||
endif (JVM_BINDINGS)
|
||||
|
||||
set_output_directory(runxgboost ${xgboost_SOURCE_DIR})
|
||||
set_output_directory(xgboost ${xgboost_SOURCE_DIR}/lib)
|
||||
# Ensure these two targets do not build simultaneously, as they produce outputs with conflicting names
|
||||
@@ -255,6 +303,8 @@ if (BUILD_C_DOC)
|
||||
run_doxygen()
|
||||
endif (BUILD_C_DOC)
|
||||
|
||||
include(CPack)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
# Install all headers. Please note that currently the C++ headers does not form an "API".
|
||||
install(DIRECTORY ${xgboost_SOURCE_DIR}/include/xgboost
|
||||
@@ -295,7 +345,7 @@ write_basic_package_version_file(
|
||||
COMPATIBILITY AnyNewerVersion)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_BINARY_DIR}/cmake/xgboost-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake/xgboost-config.cmake
|
||||
${CMAKE_BINARY_DIR}/cmake/xgboost-config-version.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/xgboost)
|
||||
|
||||
@@ -303,12 +353,18 @@ install(
|
||||
if (GOOGLE_TEST)
|
||||
enable_testing()
|
||||
# Unittests.
|
||||
add_executable(testxgboost)
|
||||
target_link_libraries(testxgboost PRIVATE objxgboost)
|
||||
xgboost_target_properties(testxgboost)
|
||||
xgboost_target_link_libraries(testxgboost)
|
||||
xgboost_target_defs(testxgboost)
|
||||
|
||||
add_subdirectory(${xgboost_SOURCE_DIR}/tests/cpp)
|
||||
|
||||
add_test(
|
||||
NAME TestXGBoostLib
|
||||
COMMAND testxgboost
|
||||
WORKING_DIRECTORY ${xgboost_BINARY_DIR})
|
||||
|
||||
# CLI tests
|
||||
configure_file(
|
||||
${xgboost_SOURCE_DIR}/tests/cli/machine.conf.in
|
||||
|
||||
@@ -10,8 +10,8 @@ The Project Management Committee(PMC) consists group of active committers that m
|
||||
- Tianqi is a Ph.D. student working on large-scale machine learning. He is the creator of the project.
|
||||
* [Michael Benesty](https://github.com/pommedeterresautee)
|
||||
- Michael is a lawyer and data scientist in France. He is the creator of XGBoost interactive analysis module in R.
|
||||
* [Yuan Tang](https://github.com/terrytangyuan), Ant Group
|
||||
- Yuan is a software engineer in Ant Group. He contributed mostly in R and Python packages.
|
||||
* [Yuan Tang](https://github.com/terrytangyuan), Akuity
|
||||
- Yuan is a founding engineer at Akuity. He contributed mostly in R and Python packages.
|
||||
* [Nan Zhu](https://github.com/CodingCat), Uber
|
||||
- Nan is a software engineer in Uber. He contributed mostly in JVM packages.
|
||||
* [Jiaming Yuan](https://github.com/trivialfis)
|
||||
@@ -43,7 +43,7 @@ Committers are people who have made substantial contribution to the project and
|
||||
|
||||
Become a Committer
|
||||
------------------
|
||||
XGBoost is a opensource project and we are actively looking for new committers who are willing to help maintaining and lead the project.
|
||||
XGBoost is a open source project and we are actively looking for new committers who are willing to help maintaining and lead the project.
|
||||
Committers comes from contributors who:
|
||||
* Made substantial contribution to the project.
|
||||
* Willing to spent time on maintaining and lead the project.
|
||||
@@ -59,7 +59,7 @@ List of Contributors
|
||||
* [Skipper Seabold](https://github.com/jseabold)
|
||||
- Skipper is the major contributor to the scikit-learn module of XGBoost.
|
||||
* [Zygmunt Zając](https://github.com/zygmuntz)
|
||||
- Zygmunt is the master behind the early stopping feature frequently used by kagglers.
|
||||
- Zygmunt is the master behind the early stopping feature frequently used by Kagglers.
|
||||
* [Ajinkya Kale](https://github.com/ajkl)
|
||||
* [Boliang Chen](https://github.com/cblsjtu)
|
||||
* [Yangqing Men](https://github.com/yanqingmen)
|
||||
@@ -91,7 +91,7 @@ List of Contributors
|
||||
* [Henry Gouk](https://github.com/henrygouk)
|
||||
* [Pierre de Sahb](https://github.com/pdesahb)
|
||||
* [liuliang01](https://github.com/liuliang01)
|
||||
- liuliang01 added support for the qid column for LibSVM input format. This makes ranking task easier in distributed setting.
|
||||
- liuliang01 added support for the qid column for LIBSVM input format. This makes ranking task easier in distributed setting.
|
||||
* [Andrew Thia](https://github.com/BlueTea88)
|
||||
- Andrew Thia implemented feature interaction constraints
|
||||
* [Wei Tian](https://github.com/weitian)
|
||||
|
||||
457
Jenkinsfile
vendored
457
Jenkinsfile
vendored
@@ -1,457 +0,0 @@
|
||||
#!/usr/bin/groovy
|
||||
// -*- mode: groovy -*-
|
||||
// Jenkins pipeline
|
||||
// See documents at https://jenkins.io/doc/book/pipeline/jenkinsfile/
|
||||
|
||||
// Command to run command inside a docker container
|
||||
dockerRun = 'tests/ci_build/ci_build.sh'
|
||||
|
||||
// Which CUDA version to use when building reference distribution wheel
|
||||
ref_cuda_ver = '10.0'
|
||||
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field
|
||||
def commit_id // necessary to pass a variable from one stage to another
|
||||
|
||||
pipeline {
|
||||
// Each stage specify its own agent
|
||||
agent none
|
||||
|
||||
environment {
|
||||
DOCKER_CACHE_ECR_ID = '492475357299'
|
||||
DOCKER_CACHE_ECR_REGION = 'us-west-2'
|
||||
}
|
||||
|
||||
// Setup common job properties
|
||||
options {
|
||||
ansiColor('xterm')
|
||||
timestamps()
|
||||
timeout(time: 240, unit: 'MINUTES')
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
preserveStashes()
|
||||
}
|
||||
|
||||
// Build stages
|
||||
stages {
|
||||
stage('Jenkins Linux: Initialize') {
|
||||
agent { label 'job_initializer' }
|
||||
steps {
|
||||
script {
|
||||
def buildNumber = env.BUILD_NUMBER as int
|
||||
if (buildNumber > 1) milestone(buildNumber - 1)
|
||||
milestone(buildNumber)
|
||||
|
||||
checkoutSrcs()
|
||||
commit_id = "${GIT_COMMIT}"
|
||||
}
|
||||
sh 'python3 tests/jenkins_get_approval.py'
|
||||
stash name: 'srcs'
|
||||
}
|
||||
}
|
||||
stage('Jenkins Linux: Build') {
|
||||
agent none
|
||||
steps {
|
||||
script {
|
||||
parallel ([
|
||||
'clang-tidy': { ClangTidy() },
|
||||
'build-cpu': { BuildCPU() },
|
||||
'build-cpu-arm64': { BuildCPUARM64() },
|
||||
'build-cpu-rabit-mock': { BuildCPUMock() },
|
||||
// Build reference, distribution-ready Python wheel with CUDA 10.0
|
||||
// using CentOS 6 image
|
||||
'build-gpu-cuda10.0': { BuildCUDA(cuda_version: '10.0') },
|
||||
// The build-gpu-* builds below use Ubuntu image
|
||||
'build-gpu-cuda10.1': { BuildCUDA(cuda_version: '10.1') },
|
||||
'build-gpu-cuda10.2': { BuildCUDA(cuda_version: '10.2', build_rmm: true) },
|
||||
'build-gpu-cuda11.0': { BuildCUDA(cuda_version: '11.0') },
|
||||
'build-gpu-rpkg': { BuildRPackageWithCUDA(cuda_version: '10.0') },
|
||||
'build-jvm-packages-gpu-cuda10.0': { BuildJVMPackagesWithCUDA(spark_version: '3.0.0', cuda_version: '10.0') },
|
||||
'build-jvm-packages': { BuildJVMPackages(spark_version: '3.0.0') },
|
||||
'build-jvm-doc': { BuildJVMDoc() }
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Jenkins Linux: Test') {
|
||||
agent none
|
||||
steps {
|
||||
script {
|
||||
parallel ([
|
||||
'test-python-cpu': { TestPythonCPU() },
|
||||
'test-python-cpu-arm64': { TestPythonCPUARM64() },
|
||||
// artifact_cuda_version doesn't apply to RMM tests; RMM tests will always match CUDA version between artifact and host env
|
||||
'test-python-gpu-cuda10.2': { TestPythonGPU(artifact_cuda_version: '10.0', host_cuda_version: '10.2', test_rmm: true) },
|
||||
'test-python-gpu-cuda11.0-cross': { TestPythonGPU(artifact_cuda_version: '10.0', host_cuda_version: '11.0') },
|
||||
'test-python-gpu-cuda11.0': { TestPythonGPU(artifact_cuda_version: '11.0', host_cuda_version: '11.0') },
|
||||
'test-python-mgpu-cuda10.2': { TestPythonGPU(artifact_cuda_version: '10.0', host_cuda_version: '10.2', multi_gpu: true, test_rmm: true) },
|
||||
'test-cpp-gpu-cuda10.2': { TestCppGPU(artifact_cuda_version: '10.2', host_cuda_version: '10.2', test_rmm: true) },
|
||||
'test-cpp-gpu-cuda11.0': { TestCppGPU(artifact_cuda_version: '11.0', host_cuda_version: '11.0') },
|
||||
'test-jvm-jdk8': { CrossTestJVMwithJDK(jdk_version: '8', spark_version: '3.0.0') },
|
||||
'test-jvm-jdk11': { CrossTestJVMwithJDK(jdk_version: '11') },
|
||||
'test-jvm-jdk12': { CrossTestJVMwithJDK(jdk_version: '12') }
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Jenkins Linux: Deploy') {
|
||||
agent none
|
||||
steps {
|
||||
script {
|
||||
parallel ([
|
||||
'deploy-jvm-packages': { DeployJVMPackages(spark_version: '3.0.0') }
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check out source code from git
|
||||
def checkoutSrcs() {
|
||||
retry(5) {
|
||||
try {
|
||||
timeout(time: 2, unit: 'MINUTES') {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
}
|
||||
} catch (exc) {
|
||||
deleteDir()
|
||||
error "Failed to fetch source codes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def GetCUDABuildContainerType(cuda_version) {
|
||||
return (cuda_version == ref_cuda_ver) ? 'gpu_build_centos6' : 'gpu_build'
|
||||
}
|
||||
|
||||
def ClangTidy() {
|
||||
node('linux && cpu_build') {
|
||||
unstash name: 'srcs'
|
||||
echo "Running clang-tidy job..."
|
||||
def container_type = "clang_tidy"
|
||||
def docker_binary = "docker"
|
||||
def dockerArgs = "--build-arg CUDA_VERSION_ARG=10.1"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} ${dockerArgs} python3 tests/ci_build/tidy.py
|
||||
"""
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildCPU() {
|
||||
node('linux && cpu') {
|
||||
unstash name: 'srcs'
|
||||
echo "Build CPU"
|
||||
def container_type = "cpu"
|
||||
def docker_binary = "docker"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} rm -fv dmlc-core/include/dmlc/build_config_default.h
|
||||
# This step is not necessary, but here we include it, to ensure that DMLC_CORE_USE_CMAKE flag is correctly propagated
|
||||
# We want to make sure that we use the configured header build/dmlc/build_config.h instead of include/dmlc/build_config_default.h.
|
||||
# See discussion at https://github.com/dmlc/xgboost/issues/5510
|
||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/build_via_cmake.sh -DPLUGIN_LZ4=ON -DPLUGIN_DENSE_PARSER=ON
|
||||
${dockerRun} ${container_type} ${docker_binary} bash -c "cd build && ctest --extra-verbose"
|
||||
"""
|
||||
// Sanitizer test
|
||||
def docker_extra_params = "CI_DOCKER_EXTRA_PARAMS_INIT='-e ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer -e ASAN_OPTIONS=symbolize=1 -e UBSAN_OPTIONS=print_stacktrace=1:log_path=ubsan_error.log --cap-add SYS_PTRACE'"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/build_via_cmake.sh -DUSE_SANITIZER=ON -DENABLED_SANITIZERS="address;leak;undefined" \
|
||||
-DCMAKE_BUILD_TYPE=Debug -DSANITIZER_PATH=/usr/lib/x86_64-linux-gnu/
|
||||
${docker_extra_params} ${dockerRun} ${container_type} ${docker_binary} bash -c "cd build && ctest --exclude-regex AllTestsInDMLCUnitTests --extra-verbose"
|
||||
"""
|
||||
|
||||
stash name: 'xgboost_cli', includes: 'xgboost'
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildCPUARM64() {
|
||||
node('linux && arm64') {
|
||||
unstash name: 'srcs'
|
||||
echo "Build CPU ARM64"
|
||||
def container_type = "aarch64"
|
||||
def docker_binary = "docker"
|
||||
def wheel_tag = "manylinux2014_aarch64"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/build_via_cmake.sh --conda-env=aarch64_test -DOPEN_MP:BOOL=ON -DHIDE_CXX_SYMBOL=ON
|
||||
${dockerRun} ${container_type} ${docker_binary} bash -c "cd build && ctest --extra-verbose"
|
||||
${dockerRun} ${container_type} ${docker_binary} bash -c "cd python-package && rm -rf dist/* && python setup.py bdist_wheel --universal"
|
||||
${dockerRun} ${container_type} ${docker_binary} python tests/ci_build/rename_whl.py python-package/dist/*.whl ${commit_id} ${wheel_tag}
|
||||
${dockerRun} ${container_type} ${docker_binary} bash -c "auditwheel repair --plat ${wheel_tag} python-package/dist/*.whl && python tests/ci_build/rename_whl.py wheelhouse/*.whl ${commit_id} ${wheel_tag}"
|
||||
mv -v wheelhouse/*.whl python-package/dist/
|
||||
# Make sure that libgomp.so is vendored in the wheel
|
||||
${dockerRun} ${container_type} ${docker_binary} bash -c "unzip -l python-package/dist/*.whl | grep libgomp || exit -1"
|
||||
"""
|
||||
echo 'Stashing Python wheel...'
|
||||
stash name: "xgboost_whl_arm64_cpu", includes: 'python-package/dist/*.whl'
|
||||
if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('release')) {
|
||||
echo 'Uploading Python wheel...'
|
||||
path = ("${BRANCH_NAME}" == 'master') ? '' : "${BRANCH_NAME}/"
|
||||
s3Upload bucket: 'xgboost-nightly-builds', path: path, acl: 'PublicRead', workingDir: 'python-package/dist', includePathPattern:'**/*.whl'
|
||||
}
|
||||
stash name: 'xgboost_cli_arm64', includes: 'xgboost'
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildCPUMock() {
|
||||
node('linux && cpu') {
|
||||
unstash name: 'srcs'
|
||||
echo "Build CPU with rabit mock"
|
||||
def container_type = "cpu"
|
||||
def docker_binary = "docker"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/build_mock_cmake.sh
|
||||
"""
|
||||
echo 'Stashing rabit C++ test executable (xgboost)...'
|
||||
stash name: 'xgboost_rabit_tests', includes: 'xgboost'
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildCUDA(args) {
|
||||
node('linux && cpu_build') {
|
||||
unstash name: 'srcs'
|
||||
echo "Build with CUDA ${args.cuda_version}"
|
||||
def container_type = GetCUDABuildContainerType(args.cuda_version)
|
||||
def docker_binary = "docker"
|
||||
def docker_args = "--build-arg CUDA_VERSION_ARG=${args.cuda_version}"
|
||||
def arch_flag = ""
|
||||
if (env.BRANCH_NAME != 'master' && !(env.BRANCH_NAME.startsWith('release'))) {
|
||||
arch_flag = "-DGPU_COMPUTE_VER=75"
|
||||
}
|
||||
def wheel_tag = "manylinux2010_x86_64"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/build_via_cmake.sh -DUSE_CUDA=ON -DUSE_NCCL=ON -DOPEN_MP:BOOL=ON -DHIDE_CXX_SYMBOLS=ON ${arch_flag}
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} bash -c "cd python-package && rm -rf dist/* && python setup.py bdist_wheel --universal"
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} python tests/ci_build/rename_whl.py python-package/dist/*.whl ${commit_id} ${wheel_tag}
|
||||
"""
|
||||
if (args.cuda_version == ref_cuda_ver) {
|
||||
sh """
|
||||
${dockerRun} auditwheel_x86_64 ${docker_binary} auditwheel repair --plat ${wheel_tag} python-package/dist/*.whl
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} python tests/ci_build/rename_whl.py wheelhouse/*.whl ${commit_id} ${wheel_tag}
|
||||
mv -v wheelhouse/*.whl python-package/dist/
|
||||
# Make sure that libgomp.so is vendored in the wheel
|
||||
${dockerRun} auditwheel_x86_64 ${docker_binary} bash -c "unzip -l python-package/dist/*.whl | grep libgomp || exit -1"
|
||||
"""
|
||||
}
|
||||
echo 'Stashing Python wheel...'
|
||||
stash name: "xgboost_whl_cuda${args.cuda_version}", includes: 'python-package/dist/*.whl'
|
||||
if (args.cuda_version == ref_cuda_ver && (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('release'))) {
|
||||
echo 'Uploading Python wheel...'
|
||||
path = ("${BRANCH_NAME}" == 'master') ? '' : "${BRANCH_NAME}/"
|
||||
s3Upload bucket: 'xgboost-nightly-builds', path: path, acl: 'PublicRead', workingDir: 'python-package/dist', includePathPattern:'**/*.whl'
|
||||
}
|
||||
echo 'Stashing C++ test executable (testxgboost)...'
|
||||
stash name: "xgboost_cpp_tests_cuda${args.cuda_version}", includes: 'build/testxgboost'
|
||||
if (args.build_rmm) {
|
||||
echo "Build with CUDA ${args.cuda_version} and RMM"
|
||||
container_type = "rmm"
|
||||
docker_binary = "docker"
|
||||
docker_args = "--build-arg CUDA_VERSION_ARG=${args.cuda_version}"
|
||||
sh """
|
||||
rm -rf build/
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/build_via_cmake.sh --conda-env=gpu_test -DUSE_CUDA=ON -DUSE_NCCL=ON -DPLUGIN_RMM=ON ${arch_flag}
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} bash -c "cd python-package && rm -rf dist/* && python setup.py bdist_wheel --universal"
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} python tests/ci_build/rename_whl.py python-package/dist/*.whl ${commit_id} manylinux2010_x86_64
|
||||
"""
|
||||
echo 'Stashing Python wheel...'
|
||||
stash name: "xgboost_whl_rmm_cuda${args.cuda_version}", includes: 'python-package/dist/*.whl'
|
||||
echo 'Stashing C++ test executable (testxgboost)...'
|
||||
stash name: "xgboost_cpp_tests_rmm_cuda${args.cuda_version}", includes: 'build/testxgboost'
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildRPackageWithCUDA(args) {
|
||||
node('linux && cpu_build') {
|
||||
unstash name: 'srcs'
|
||||
def container_type = 'gpu_build_r_centos6'
|
||||
def docker_binary = "docker"
|
||||
def docker_args = "--build-arg CUDA_VERSION_ARG=10.0"
|
||||
if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('release')) {
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/build_r_pkg_with_cuda.sh ${commit_id}
|
||||
"""
|
||||
echo 'Uploading R tarball...'
|
||||
path = ("${BRANCH_NAME}" == 'master') ? '' : "${BRANCH_NAME}/"
|
||||
s3Upload bucket: 'xgboost-nightly-builds', path: path, acl: 'PublicRead', includePathPattern:'xgboost_r_gpu_linux_*.tar.gz'
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildJVMPackagesWithCUDA(args) {
|
||||
node('linux && mgpu') {
|
||||
unstash name: 'srcs'
|
||||
echo "Build XGBoost4J-Spark with Spark ${args.spark_version}, CUDA ${args.cuda_version}"
|
||||
def container_type = "jvm_gpu_build"
|
||||
def docker_binary = "nvidia-docker"
|
||||
def docker_args = "--build-arg CUDA_VERSION_ARG=${args.cuda_version}"
|
||||
def arch_flag = ""
|
||||
if (env.BRANCH_NAME != 'master' && !(env.BRANCH_NAME.startsWith('release'))) {
|
||||
arch_flag = "-DGPU_COMPUTE_VER=75"
|
||||
}
|
||||
// Use only 4 CPU cores
|
||||
def docker_extra_params = "CI_DOCKER_EXTRA_PARAMS_INIT='--cpuset-cpus 0-3'"
|
||||
sh """
|
||||
${docker_extra_params} ${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/build_jvm_packages.sh ${args.spark_version} -Duse.cuda=ON $arch_flag
|
||||
"""
|
||||
echo "Stashing XGBoost4J JAR with CUDA ${args.cuda_version} ..."
|
||||
stash name: 'xgboost4j_jar_gpu', includes: "jvm-packages/xgboost4j-gpu/target/*.jar,jvm-packages/xgboost4j-spark-gpu/target/*.jar"
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildJVMPackages(args) {
|
||||
node('linux && cpu') {
|
||||
unstash name: 'srcs'
|
||||
echo "Build XGBoost4J-Spark with Spark ${args.spark_version}"
|
||||
def container_type = "jvm"
|
||||
def docker_binary = "docker"
|
||||
// Use only 4 CPU cores
|
||||
def docker_extra_params = "CI_DOCKER_EXTRA_PARAMS_INIT='--cpuset-cpus 0-3'"
|
||||
sh """
|
||||
${docker_extra_params} ${dockerRun} ${container_type} ${docker_binary} tests/ci_build/build_jvm_packages.sh ${args.spark_version}
|
||||
"""
|
||||
echo 'Stashing XGBoost4J JAR...'
|
||||
stash name: 'xgboost4j_jar', includes: "jvm-packages/xgboost4j/target/*.jar,jvm-packages/xgboost4j-spark/target/*.jar,jvm-packages/xgboost4j-example/target/*.jar"
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def BuildJVMDoc() {
|
||||
node('linux && cpu') {
|
||||
unstash name: 'srcs'
|
||||
echo "Building JVM doc..."
|
||||
def container_type = "jvm"
|
||||
def docker_binary = "docker"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/build_jvm_doc.sh ${BRANCH_NAME}
|
||||
"""
|
||||
if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('release')) {
|
||||
echo 'Uploading doc...'
|
||||
s3Upload file: "jvm-packages/${BRANCH_NAME}.tar.bz2", bucket: 'xgboost-docs', acl: 'PublicRead', path: "${BRANCH_NAME}.tar.bz2"
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def TestPythonCPU() {
|
||||
node('linux && cpu') {
|
||||
unstash name: "xgboost_whl_cuda${ref_cuda_ver}"
|
||||
unstash name: 'srcs'
|
||||
unstash name: 'xgboost_cli'
|
||||
echo "Test Python CPU"
|
||||
def container_type = "cpu"
|
||||
def docker_binary = "docker"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/test_python.sh cpu
|
||||
"""
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def TestPythonCPUARM64() {
|
||||
node('linux && arm64') {
|
||||
unstash name: "xgboost_whl_arm64_cpu"
|
||||
unstash name: 'srcs'
|
||||
unstash name: 'xgboost_cli_arm64'
|
||||
echo "Test Python CPU ARM64"
|
||||
def container_type = "aarch64"
|
||||
def docker_binary = "docker"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/test_python.sh cpu-arm64
|
||||
"""
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def TestPythonGPU(args) {
|
||||
def nodeReq = (args.multi_gpu) ? 'linux && mgpu' : 'linux && gpu'
|
||||
def artifact_cuda_version = (args.artifact_cuda_version) ?: ref_cuda_ver
|
||||
node(nodeReq) {
|
||||
unstash name: "xgboost_whl_cuda${artifact_cuda_version}"
|
||||
unstash name: "xgboost_cpp_tests_cuda${artifact_cuda_version}"
|
||||
unstash name: 'srcs'
|
||||
echo "Test Python GPU: CUDA ${args.host_cuda_version}"
|
||||
def container_type = "gpu"
|
||||
def docker_binary = "nvidia-docker"
|
||||
def docker_args = "--build-arg CUDA_VERSION_ARG=${args.host_cuda_version}"
|
||||
def mgpu_indicator = (args.multi_gpu) ? 'mgpu' : 'gpu'
|
||||
// Allocate extra space in /dev/shm to enable NCCL
|
||||
def docker_extra_params = (args.multi_gpu) ? "CI_DOCKER_EXTRA_PARAMS_INIT='--shm-size=4g'" : ''
|
||||
sh "${docker_extra_params} ${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_python.sh ${mgpu_indicator}"
|
||||
if (args.test_rmm) {
|
||||
sh "rm -rfv build/ python-package/dist/"
|
||||
unstash name: "xgboost_whl_rmm_cuda${args.host_cuda_version}"
|
||||
unstash name: "xgboost_cpp_tests_rmm_cuda${args.host_cuda_version}"
|
||||
sh "${docker_extra_params} ${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_python.sh ${mgpu_indicator} --use-rmm-pool"
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def TestCppGPU(args) {
|
||||
def nodeReq = 'linux && mgpu'
|
||||
def artifact_cuda_version = (args.artifact_cuda_version) ?: ref_cuda_ver
|
||||
node(nodeReq) {
|
||||
unstash name: "xgboost_cpp_tests_cuda${artifact_cuda_version}"
|
||||
unstash name: 'srcs'
|
||||
echo "Test C++, CUDA ${args.host_cuda_version}"
|
||||
def container_type = "gpu"
|
||||
def docker_binary = "nvidia-docker"
|
||||
def docker_args = "--build-arg CUDA_VERSION_ARG=${args.host_cuda_version}"
|
||||
sh "${dockerRun} ${container_type} ${docker_binary} ${docker_args} build/testxgboost"
|
||||
if (args.test_rmm) {
|
||||
sh "rm -rfv build/"
|
||||
unstash name: "xgboost_cpp_tests_rmm_cuda${args.host_cuda_version}"
|
||||
echo "Test C++, CUDA ${args.host_cuda_version} with RMM"
|
||||
container_type = "rmm"
|
||||
docker_binary = "nvidia-docker"
|
||||
docker_args = "--build-arg CUDA_VERSION_ARG=${args.host_cuda_version}"
|
||||
sh """
|
||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} bash -c "source activate gpu_test && build/testxgboost --use-rmm-pool --gtest_filter=-*DeathTest.*"
|
||||
"""
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def CrossTestJVMwithJDK(args) {
|
||||
node('linux && cpu') {
|
||||
unstash name: 'xgboost4j_jar'
|
||||
unstash name: 'srcs'
|
||||
if (args.spark_version != null) {
|
||||
echo "Test XGBoost4J on a machine with JDK ${args.jdk_version}, Spark ${args.spark_version}"
|
||||
} else {
|
||||
echo "Test XGBoost4J on a machine with JDK ${args.jdk_version}"
|
||||
}
|
||||
def container_type = "jvm_cross"
|
||||
def docker_binary = "docker"
|
||||
def spark_arg = (args.spark_version != null) ? "--build-arg SPARK_VERSION=${args.spark_version}" : ""
|
||||
def docker_args = "--build-arg JDK_VERSION=${args.jdk_version} ${spark_arg}"
|
||||
// Run integration tests only when spark_version is given
|
||||
def docker_extra_params = (args.spark_version != null) ? "CI_DOCKER_EXTRA_PARAMS_INIT='-e RUN_INTEGRATION_TEST=1'" : ""
|
||||
sh """
|
||||
${docker_extra_params} ${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_jvm_cross.sh
|
||||
"""
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def DeployJVMPackages(args) {
|
||||
node('linux && cpu') {
|
||||
unstash name: 'srcs'
|
||||
if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('release')) {
|
||||
echo 'Deploying to xgboost-maven-repo S3 repo...'
|
||||
sh """
|
||||
${dockerRun} jvm_gpu_build docker --build-arg CUDA_VERSION_ARG=10.0 tests/ci_build/deploy_jvm_packages.sh ${args.spark_version}
|
||||
"""
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
#!/usr/bin/groovy
|
||||
// -*- mode: groovy -*-
|
||||
|
||||
/* Jenkins pipeline for Windows AMD64 target */
|
||||
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field
|
||||
def commit_id // necessary to pass a variable from one stage to another
|
||||
|
||||
pipeline {
|
||||
agent none
|
||||
|
||||
// Setup common job properties
|
||||
options {
|
||||
timestamps()
|
||||
timeout(time: 240, unit: 'MINUTES')
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
preserveStashes()
|
||||
}
|
||||
|
||||
// Build stages
|
||||
stages {
|
||||
stage('Jenkins Win64: Initialize') {
|
||||
agent { label 'job_initializer' }
|
||||
steps {
|
||||
script {
|
||||
def buildNumber = env.BUILD_NUMBER as int
|
||||
if (buildNumber > 1) milestone(buildNumber - 1)
|
||||
milestone(buildNumber)
|
||||
checkoutSrcs()
|
||||
commit_id = "${GIT_COMMIT}"
|
||||
}
|
||||
sh 'python3 tests/jenkins_get_approval.py'
|
||||
stash name: 'srcs'
|
||||
}
|
||||
}
|
||||
stage('Jenkins Win64: Build') {
|
||||
agent none
|
||||
steps {
|
||||
script {
|
||||
parallel ([
|
||||
'build-win64-cuda10.1': { BuildWin64() }
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Jenkins Win64: Test') {
|
||||
agent none
|
||||
steps {
|
||||
script {
|
||||
parallel ([
|
||||
'test-win64-cuda10.1': { TestWin64() },
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check out source code from git
|
||||
def checkoutSrcs() {
|
||||
retry(5) {
|
||||
try {
|
||||
timeout(time: 2, unit: 'MINUTES') {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
}
|
||||
} catch (exc) {
|
||||
deleteDir()
|
||||
error "Failed to fetch source codes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def BuildWin64() {
|
||||
node('win64 && cuda10_unified') {
|
||||
unstash name: 'srcs'
|
||||
echo "Building XGBoost for Windows AMD64 target..."
|
||||
bat "nvcc --version"
|
||||
def arch_flag = ""
|
||||
if (env.BRANCH_NAME != 'master' && !(env.BRANCH_NAME.startsWith('release'))) {
|
||||
arch_flag = "-DGPU_COMPUTE_VER=75"
|
||||
}
|
||||
bat """
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G"Visual Studio 15 2017 Win64" -DUSE_CUDA=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON ${arch_flag} -DCMAKE_UNITY_BUILD=ON
|
||||
"""
|
||||
bat """
|
||||
cd build
|
||||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe" xgboost.sln /m /p:Configuration=Release /nodeReuse:false
|
||||
"""
|
||||
bat """
|
||||
cd python-package
|
||||
conda activate && python setup.py bdist_wheel --universal && for /R %%i in (dist\\*.whl) DO python ../tests/ci_build/rename_whl.py "%%i" ${commit_id} win_amd64
|
||||
"""
|
||||
echo "Insert vcomp140.dll (OpenMP runtime) into the wheel..."
|
||||
bat """
|
||||
cd python-package\\dist
|
||||
COPY /B ..\\..\\tests\\ci_build\\insert_vcomp140.py
|
||||
conda activate && python insert_vcomp140.py *.whl
|
||||
"""
|
||||
echo 'Stashing Python wheel...'
|
||||
stash name: 'xgboost_whl', includes: 'python-package/dist/*.whl'
|
||||
if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('release')) {
|
||||
echo 'Uploading Python wheel...'
|
||||
path = ("${BRANCH_NAME}" == 'master') ? '' : "${BRANCH_NAME}/"
|
||||
s3Upload bucket: 'xgboost-nightly-builds', path: path, acl: 'PublicRead', workingDir: 'python-package/dist', includePathPattern:'**/*.whl'
|
||||
}
|
||||
echo 'Stashing C++ test executable (testxgboost)...'
|
||||
stash name: 'xgboost_cpp_tests', includes: 'build/testxgboost.exe'
|
||||
stash name: 'xgboost_cli', includes: 'xgboost.exe'
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
def TestWin64() {
|
||||
node('win64 && cuda10_unified') {
|
||||
unstash name: 'srcs'
|
||||
unstash name: 'xgboost_whl'
|
||||
unstash name: 'xgboost_cli'
|
||||
unstash name: 'xgboost_cpp_tests'
|
||||
echo "Test Win64"
|
||||
bat "nvcc --version"
|
||||
echo "Running C++ tests..."
|
||||
bat "build\\testxgboost.exe"
|
||||
echo "Installing Python dependencies..."
|
||||
def env_name = 'win64_' + UUID.randomUUID().toString().replaceAll('-', '')
|
||||
bat "conda env create -n ${env_name} --file=tests/ci_build/conda_env/win64_test.yml"
|
||||
echo "Installing Python wheel..."
|
||||
bat """
|
||||
conda activate ${env_name} && for /R %%i in (python-package\\dist\\*.whl) DO python -m pip install "%%i"
|
||||
"""
|
||||
echo "Running Python tests..."
|
||||
bat "conda activate ${env_name} && python -m pytest -v -s -rxXs --fulltrace tests\\python"
|
||||
bat """
|
||||
conda activate ${env_name} && python -m pytest -v -s -rxXs --fulltrace -m "(not slow) and (not mgpu)" tests\\python-gpu
|
||||
"""
|
||||
bat "conda env remove --name ${env_name}"
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
19
Makefile
19
Makefile
@@ -87,14 +87,6 @@ cover: check
|
||||
endif
|
||||
|
||||
|
||||
# dask is required to pass, others are not
|
||||
# If any of the dask tests failed, contributor won't see the other error.
|
||||
mypy:
|
||||
cd python-package; \
|
||||
mypy ./xgboost/dask.py ../tests/python/test_with_dask.py --follow-imports=silent; \
|
||||
mypy ../tests/python-gpu/test_gpu_with_dask.py --follow-imports=silent; \
|
||||
mypy . || true ;
|
||||
|
||||
clean:
|
||||
$(RM) -rf build lib bin *~ */*~ */*/*~ */*/*/*~ */*.o */*/*.o */*/*/*.o #xgboost
|
||||
$(RM) -rf build_tests *.gcov tests/cpp/xgboost_test
|
||||
@@ -131,20 +123,13 @@ Rpack: clean_all
|
||||
cp -r dmlc-core/include xgboost/src/dmlc-core/include
|
||||
cp -r dmlc-core/src xgboost/src/dmlc-core/src
|
||||
cp ./LICENSE xgboost
|
||||
# Modify PKGROOT in Makevars.in
|
||||
cat R-package/src/Makevars.in|sed '2s/.*/PKGROOT=./' > xgboost/src/Makevars.in
|
||||
# Configure Makevars.win (Windows-specific Makevars, likely using MinGW)
|
||||
cp xgboost/src/Makevars.in xgboost/src/Makevars.win
|
||||
cat xgboost/src/Makevars.in| sed '3s/.*/ENABLE_STD_THREAD=0/' > xgboost/src/Makevars.win
|
||||
sed -i -e 's/@OPENMP_CXXFLAGS@/$$\(SHLIB_OPENMP_CXXFLAGS\)/g' xgboost/src/Makevars.win
|
||||
sed -i -e 's/-pthread/$$\(SHLIB_PTHREAD_FLAGS\)/g' xgboost/src/Makevars.win
|
||||
sed -i -e 's/@ENDIAN_FLAG@/-DDMLC_CMAKE_LITTLE_ENDIAN=1/g' xgboost/src/Makevars.win
|
||||
sed -i -e 's/@BACKTRACE_LIB@//g' xgboost/src/Makevars.win
|
||||
sed -i -e 's/@OPENMP_LIB@//g' xgboost/src/Makevars.win
|
||||
cat R-package/src/Makevars.win|sed '2s/.*/PKGROOT=./' > xgboost/src/Makevars.win
|
||||
rm -f xgboost/src/Makevars.win-e # OSX sed create this extra file; remove it
|
||||
bash R-package/remove_warning_suppression_pragma.sh
|
||||
bash xgboost/remove_warning_suppression_pragma.sh
|
||||
rm xgboost/remove_warning_suppression_pragma.sh
|
||||
rm xgboost/CMakeLists.txt
|
||||
rm -rfv xgboost/tests/helper_scripts/
|
||||
|
||||
R ?= R
|
||||
|
||||
750
NEWS.md
750
NEWS.md
@@ -3,6 +3,740 @@ XGBoost Change Log
|
||||
|
||||
This file records the changes in xgboost library in reverse chronological order.
|
||||
|
||||
## v1.6.1 (2022 May 9)
|
||||
This is a patch release for bug fixes and Spark barrier mode support. The R package is unchanged.
|
||||
|
||||
### Experimental support for categorical data
|
||||
- Fix segfault when the number of samples is smaller than the number of categories. (https://github.com/dmlc/xgboost/pull/7853)
|
||||
- Enable partition-based split for all model types. (https://github.com/dmlc/xgboost/pull/7857)
|
||||
|
||||
### JVM packages
|
||||
We replaced the old parallelism tracker with spark barrier mode to improve the robustness of the JVM package and fix the GPU training pipeline.
|
||||
- Fix GPU training pipeline quantile synchronization. (#7823, #7834)
|
||||
- Use barrier model in spark package. (https://github.com/dmlc/xgboost/pull/7836, https://github.com/dmlc/xgboost/pull/7840, https://github.com/dmlc/xgboost/pull/7845, https://github.com/dmlc/xgboost/pull/7846)
|
||||
- Fix shared object loading on some platforms. (https://github.com/dmlc/xgboost/pull/7844)
|
||||
|
||||
## v1.6.0 (2022 Apr 16)
|
||||
|
||||
After a long period of development, XGBoost v1.6.0 is packed with many new features and
|
||||
improvements. We summarize them in the following sections starting with an introduction to
|
||||
some major new features, then moving on to language binding specific changes including new
|
||||
features and notable bug fixes for that binding.
|
||||
|
||||
### Development of categorical data support
|
||||
This version of XGBoost features new improvements and full coverage of experimental
|
||||
categorical data support in Python and C package with tree model. Both `hist`, `approx`
|
||||
and `gpu_hist` now support training with categorical data. Also, partition-based
|
||||
categorical split is introduced in this release. This split type is first available in
|
||||
LightGBM in the context of gradient boosting. The previous XGBoost release supported one-hot split where the splitting criteria is of form `x \in {c}`, i.e. the categorical feature `x` is tested against a single candidate. The new release allows for more expressive conditions: `x \in S` where the categorical feature `x` is tested against multiple candidates. Moreover, it is now possible to use any tree algorithms (`hist`, `approx`, `gpu_hist`) when creating categorical splits. For more
|
||||
information, please see our tutorial on [categorical
|
||||
data](https://xgboost.readthedocs.io/en/latest/tutorials/categorical.html), along with
|
||||
examples linked on that page. (#7380, #7708, #7695, #7330, #7307, #7322, #7705,
|
||||
#7652, #7592, #7666, #7576, #7569, #7529, #7575, #7393, #7465, #7385, #7371, #7745, #7810)
|
||||
|
||||
In the future, we will continue to improve categorical data support with new features and
|
||||
optimizations. Also, we are looking forward to bringing the feature beyond Python binding,
|
||||
contributions and feedback are welcomed! Lastly, as a result of experimental status, the
|
||||
behavior might be subject to change, especially the default value of related
|
||||
hyper-parameters.
|
||||
|
||||
### Experimental support for multi-output model
|
||||
|
||||
XGBoost 1.6 features initial support for the multi-output model, which includes
|
||||
multi-output regression and multi-label classification. Along with this, the XGBoost
|
||||
classifier has proper support for base margin without to need for the user to flatten the
|
||||
input. In this initial support, XGBoost builds one model for each target similar to the
|
||||
sklearn meta estimator, for more details, please see our [quick
|
||||
introduction](https://xgboost.readthedocs.io/en/latest/tutorials/multioutput.html).
|
||||
|
||||
(#7365, #7736, #7607, #7574, #7521, #7514, #7456, #7453, #7455, #7434, #7429, #7405, #7381)
|
||||
|
||||
### External memory support
|
||||
External memory support for both approx and hist tree method is considered feature
|
||||
complete in XGBoost 1.6. Building upon the iterator-based interface introduced in the
|
||||
previous version, now both `hist` and `approx` iterates over each batch of data during
|
||||
training and prediction. In previous versions, `hist` concatenates all the batches into
|
||||
an internal representation, which is removed in this version. As a result, users can
|
||||
expect higher scalability in terms of data size but might experience lower performance due
|
||||
to disk IO. (#7531, #7320, #7638, #7372)
|
||||
|
||||
### Rewritten approx
|
||||
|
||||
The `approx` tree method is rewritten based on the existing `hist` tree method. The
|
||||
rewrite closes the feature gap between `approx` and `hist` and improves the performance.
|
||||
Now the behavior of `approx` should be more aligned with `hist` and `gpu_hist`. Here is a
|
||||
list of user-visible changes:
|
||||
|
||||
- Supports both `max_leaves` and `max_depth`.
|
||||
- Supports `grow_policy`.
|
||||
- Supports monotonic constraint.
|
||||
- Supports feature weights.
|
||||
- Use `max_bin` to replace `sketch_eps`.
|
||||
- Supports categorical data.
|
||||
- Faster performance for many of the datasets.
|
||||
- Improved performance and robustness for distributed training.
|
||||
- Supports prediction cache.
|
||||
- Significantly better performance for external memory when `depthwise` policy is used.
|
||||
|
||||
### New serialization format
|
||||
Based on the existing JSON serialization format, we introduce UBJSON support as a more
|
||||
efficient alternative. Both formats will be available in the future and we plan to
|
||||
gradually [phase out](https://github.com/dmlc/xgboost/issues/7547) support for the old
|
||||
binary model format. Users can opt to use the different formats in the serialization
|
||||
function by providing the file extension `json` or `ubj`. Also, the `save_raw` function in
|
||||
all supported languages bindings gains a new parameter for exporting the model in different
|
||||
formats, available options are `json`, `ubj`, and `deprecated`, see document for the
|
||||
language binding you are using for details. Lastly, the default internal serialization
|
||||
format is set to UBJSON, which affects Python pickle and R RDS. (#7572, #7570, #7358,
|
||||
#7571, #7556, #7549, #7416)
|
||||
|
||||
### General new features and improvements
|
||||
Aside from the major new features mentioned above, some others are summarized here:
|
||||
|
||||
* Users can now access the build information of XGBoost binary in Python and C
|
||||
interface. (#7399, #7553)
|
||||
* Auto-configuration of `seed_per_iteration` is removed, now distributed training should
|
||||
generate closer results to single node training when sampling is used. (#7009)
|
||||
* A new parameter `huber_slope` is introduced for the `Pseudo-Huber` objective.
|
||||
* During source build, XGBoost can choose cub in the system path automatically. (#7579)
|
||||
* XGBoost now honors the CPU counts from CFS, which is usually set in docker
|
||||
environments. (#7654, #7704)
|
||||
* The metric `aucpr` is rewritten for better performance and GPU support. (#7297, #7368)
|
||||
* Metric calculation is now performed in double precision. (#7364)
|
||||
* XGBoost no longer mutates the global OpenMP thread limit. (#7537, #7519, #7608, #7590,
|
||||
#7589, #7588, #7687)
|
||||
* The default behavior of `max_leave` and `max_depth` is now unified (#7302, #7551).
|
||||
* CUDA fat binary is now compressed. (#7601)
|
||||
* Deterministic result for evaluation metric and linear model. In previous versions of
|
||||
XGBoost, evaluation results might differ slightly for each run due to parallel reduction
|
||||
for floating-point values, which is now addressed. (#7362, #7303, #7316, #7349)
|
||||
* XGBoost now uses double for GPU Hist node sum, which improves the accuracy of
|
||||
`gpu_hist`. (#7507)
|
||||
|
||||
### Performance improvements
|
||||
Most of the performance improvements are integrated into other refactors during feature
|
||||
developments. The `approx` should see significant performance gain for many datasets as
|
||||
mentioned in the previous section, while the `hist` tree method also enjoys improved
|
||||
performance with the removal of the internal `pruner` along with some other
|
||||
refactoring. Lastly, `gpu_hist` no longer synchronizes the device during training. (#7737)
|
||||
|
||||
### General bug fixes
|
||||
This section lists bug fixes that are not specific to any language binding.
|
||||
* The `num_parallel_tree` is now a model parameter instead of a training hyper-parameter,
|
||||
which fixes model IO with random forest. (#7751)
|
||||
* Fixes in CMake script for exporting configuration. (#7730)
|
||||
* XGBoost can now handle unsorted sparse input. This includes text file formats like
|
||||
libsvm and scipy sparse matrix where column index might not be sorted. (#7731)
|
||||
* Fix tree param feature type, this affects inputs with the number of columns greater than
|
||||
the maximum value of int32. (#7565)
|
||||
* Fix external memory with gpu_hist and subsampling. (#7481)
|
||||
* Check the number of trees in inplace predict, this avoids a potential segfault when an
|
||||
incorrect value for `iteration_range` is provided. (#7409)
|
||||
* Fix non-stable result in cox regression (#7756)
|
||||
|
||||
### Changes in the Python package
|
||||
Other than the changes in Dask, the XGBoost Python package gained some new features and
|
||||
improvements along with small bug fixes.
|
||||
|
||||
* Python 3.7 is required as the lowest Python version. (#7682)
|
||||
* Pre-built binary wheel for Apple Silicon. (#7621, #7612, #7747) Apple Silicon users will
|
||||
now be able to run `pip install xgboost` to install XGBoost.
|
||||
* MacOS users no longer need to install `libomp` from Homebrew, as the XGBoost wheel now
|
||||
bundles `libomp.dylib` library.
|
||||
* There are new parameters for users to specify the custom metric with new
|
||||
behavior. XGBoost can now output transformed prediction values when a custom objective is
|
||||
not supplied. See our explanation in the
|
||||
[tutorial](https://xgboost.readthedocs.io/en/latest/tutorials/custom_metric_obj.html#reverse-link-function)
|
||||
for details.
|
||||
* For the sklearn interface, following the estimator guideline from scikit-learn, all
|
||||
parameters in `fit` that are not related to input data are moved into the constructor
|
||||
and can be set by `set_params`. (#6751, #7420, #7375, #7369)
|
||||
* Apache arrow format is now supported, which can bring better performance to users'
|
||||
pipeline (#7512)
|
||||
* Pandas nullable types are now supported (#7760)
|
||||
* A new function `get_group` is introduced for `DMatrix` to allow users to get the group
|
||||
information in the custom objective function. (#7564)
|
||||
* More training parameters are exposed in the sklearn interface instead of relying on the
|
||||
`**kwargs`. (#7629)
|
||||
* A new attribute `feature_names_in_` is defined for all sklearn estimators like
|
||||
`XGBRegressor` to follow the convention of sklearn. (#7526)
|
||||
* More work on Python type hint. (#7432, #7348, #7338, #7513, #7707)
|
||||
* Support the latest pandas Index type. (#7595)
|
||||
* Fix for Feature shape mismatch error on s390x platform (#7715)
|
||||
* Fix using feature names for constraints with multiple groups (#7711)
|
||||
* We clarified the behavior of the callback function when it contains mutable
|
||||
states. (#7685)
|
||||
* Lastly, there are some code cleanups and maintenance work. (#7585, #7426, #7634, #7665,
|
||||
#7667, #7377, #7360, #7498, #7438, #7667, #7752, #7749, #7751)
|
||||
|
||||
### Changes in the Dask interface
|
||||
* Dask module now supports user-supplied host IP and port address of scheduler node.
|
||||
Please see [introduction](https://xgboost.readthedocs.io/en/latest/tutorials/dask.html#troubleshooting) and
|
||||
[API document](https://xgboost.readthedocs.io/en/latest/python/python_api.html#optional-dask-configuration)
|
||||
for reference. (#7645, #7581)
|
||||
* Internal `DMatrix` construction in dask now honers thread configuration. (#7337)
|
||||
* A fix for `nthread` configuration using the Dask sklearn interface. (#7633)
|
||||
* The Dask interface can now handle empty partitions. An empty partition is different
|
||||
from an empty worker, the latter refers to the case when a worker has no partition of an
|
||||
input dataset, while the former refers to some partitions on a worker that has zero
|
||||
sizes. (#7644, #7510)
|
||||
* Scipy sparse matrix is supported as Dask array partition. (#7457)
|
||||
* Dask interface is no longer considered experimental. (#7509)
|
||||
|
||||
### Changes in the R package
|
||||
This section summarizes the new features, improvements, and bug fixes to the R package.
|
||||
|
||||
* `load.raw` can optionally construct a booster as return. (#7686)
|
||||
* Fix parsing decision stump, which affects both transforming text representation to data
|
||||
table and plotting. (#7689)
|
||||
* Implement feature weights. (#7660)
|
||||
* Some improvements for complying the CRAN release policy. (#7672, #7661, #7763)
|
||||
* Support CSR data for predictions (#7615)
|
||||
* Document update (#7263, #7606)
|
||||
* New maintainer for the CRAN package (#7691, #7649)
|
||||
* Handle non-standard installation of toolchain on macos (#7759)
|
||||
|
||||
### Changes in JVM-packages
|
||||
Some new features for JVM-packages are introduced for a more integrated GPU pipeline and
|
||||
better compatibility with musl-based Linux. Aside from this, we have a few notable bug
|
||||
fixes.
|
||||
|
||||
* User can specify the tracker IP address for training, which helps running XGBoost on
|
||||
restricted network environments. (#7808)
|
||||
* Add support for detecting musl-based Linux (#7624)
|
||||
* Add `DeviceQuantileDMatrix` to Scala binding (#7459)
|
||||
* Add Rapids plugin support, now more of the JVM pipeline can be accelerated by RAPIDS (#7491, #7779, #7793, #7806)
|
||||
* The setters for CPU and GPU are more aligned (#7692, #7798)
|
||||
* Control logging for early stopping (#7326)
|
||||
* Do not repartition when nWorker = 1 (#7676)
|
||||
* Fix the prediction issue for `multi:softmax` (#7694)
|
||||
* Fix for serialization of custom objective and eval (#7274)
|
||||
* Update documentation about Python tracker (#7396)
|
||||
* Remove jackson from dependency, which fixes CVE-2020-36518. (#7791)
|
||||
* Some refactoring to the training pipeline for better compatibility between CPU and
|
||||
GPU. (#7440, #7401, #7789, #7784)
|
||||
* Maintenance work. (#7550, #7335, #7641, #7523, #6792, #4676)
|
||||
|
||||
### Deprecation
|
||||
Other than the changes in the Python package and serialization, we removed some deprecated
|
||||
features in previous releases. Also, as mentioned in the previous section, we plan to
|
||||
phase out the old binary format in future releases.
|
||||
|
||||
* Remove old warning in 1.3 (#7279)
|
||||
* Remove label encoder deprecated in 1.3. (#7357)
|
||||
* Remove old callback deprecated in 1.3. (#7280)
|
||||
* Pre-built binary will no longer support deprecated CUDA architectures including sm35 and
|
||||
sm50. Users can continue to use these platforms with source build. (#7767)
|
||||
|
||||
### Documentation
|
||||
This section lists some of the general changes to XGBoost's document, for language binding
|
||||
specific change please visit related sections.
|
||||
|
||||
* Document is overhauled to use the new RTD theme, along with integration of Python
|
||||
examples using Sphinx gallery. Also, we replaced most of the hard-coded URLs with sphinx
|
||||
references. (#7347, #7346, #7468, #7522, #7530)
|
||||
* Small update along with fixes for broken links, typos, etc. (#7684, #7324, #7334, #7655,
|
||||
#7628, #7623, #7487, #7532, #7500, #7341, #7648, #7311)
|
||||
* Update document for GPU. [skip ci] (#7403)
|
||||
* Document the status of RTD hosting. (#7353)
|
||||
* Update document for building from source. (#7664)
|
||||
* Add note about CRAN release [skip ci] (#7395)
|
||||
|
||||
### Maintenance
|
||||
This is a summary of maintenance work that is not specific to any language binding.
|
||||
|
||||
* Add CMake option to use /MD runtime (#7277)
|
||||
* Add clang-format configuration. (#7383)
|
||||
* Code cleanups (#7539, #7536, #7466, #7499, #7533, #7735, #7722, #7668, #7304, #7293,
|
||||
#7321, #7356, #7345, #7387, #7577, #7548, #7469, #7680, #7433, #7398)
|
||||
* Improved tests with better coverage and latest dependency (#7573, #7446, #7650, #7520,
|
||||
#7373, #7723, #7611, #7771)
|
||||
* Improved automation of the release process. (#7278, #7332, #7470)
|
||||
* Compiler workarounds (#7673)
|
||||
* Change shebang used in CLI demo. (#7389)
|
||||
* Update affiliation (#7289)
|
||||
|
||||
### CI
|
||||
Some fixes and update to XGBoost's CI infrastructure. (#7739, #7701, #7382, #7662, #7646,
|
||||
#7582, #7407, #7417, #7475, #7474, #7479, #7472, #7626)
|
||||
|
||||
|
||||
## v1.5.0 (2021 Oct 11)
|
||||
|
||||
This release comes with many exciting new features and optimizations, along with some bug
|
||||
fixes. We will describe the experimental categorical data support and the external memory
|
||||
interface independently. Package-specific new features will be listed in respective
|
||||
sections.
|
||||
|
||||
### Development on categorical data support
|
||||
In version 1.3, XGBoost introduced an experimental feature for handling categorical data
|
||||
natively, without one-hot encoding. XGBoost can fit categorical splits in decision
|
||||
trees. (Currently, the generated splits will be of form `x \in {v}`, where the input is
|
||||
compared to a single category value. A future version of XGBoost will generate splits that
|
||||
compare the input against a list of multiple category values.)
|
||||
|
||||
Most of the other features, including prediction, SHAP value computation, feature
|
||||
importance, and model plotting were revised to natively handle categorical splits. Also,
|
||||
all Python interfaces including native interface with and without quantized `DMatrix`,
|
||||
scikit-learn interface, and Dask interface now accept categorical data with a wide range
|
||||
of data structures support including numpy/cupy array and cuDF/pandas/modin dataframe. In
|
||||
practice, the following are required for enabling categorical data support during
|
||||
training:
|
||||
|
||||
- Use Python package.
|
||||
- Use `gpu_hist` to train the model.
|
||||
- Use JSON model file format for saving the model.
|
||||
|
||||
Once the model is trained, it can be used with most of the features that are available on
|
||||
the Python package. For a quick introduction, see
|
||||
https://xgboost.readthedocs.io/en/latest/tutorials/categorical.html
|
||||
|
||||
Related PRs: (#7011, #7001, #7042, #7041, #7047, #7043, #7036, #7054, #7053, #7065, #7213, #7228, #7220, #7221, #7231, #7306)
|
||||
|
||||
* Next steps
|
||||
|
||||
- Revise the CPU training algorithm to handle categorical data natively and generate categorical splits
|
||||
- Extend the CPU and GPU algorithms to generate categorical splits of form `x \in S`
|
||||
where the input is compared with multiple category values. split. (#7081)
|
||||
|
||||
### External memory
|
||||
This release features a brand-new interface and implementation for external memory (also
|
||||
known as out-of-core training). (#6901, #7064, #7088, #7089, #7087, #7092, #7070,
|
||||
#7216). The new implementation leverages the data iterator interface, which is currently
|
||||
used to create `DeviceQuantileDMatrix`. For a quick introduction, see
|
||||
https://xgboost.readthedocs.io/en/latest/tutorials/external_memory.html#data-iterator
|
||||
. During the development of this new interface, `lz4` compression is removed. (#7076).
|
||||
Please note that external memory support is still experimental and not ready for
|
||||
production use yet. All future development will focus on this new interface and users are
|
||||
advised to migrate. (You are using the old interface if you are using a URL suffix to use
|
||||
external memory.)
|
||||
|
||||
### New features in Python package
|
||||
* Support numpy array interface and all numeric types from numpy in `DMatrix`
|
||||
construction and `inplace_predict` (#6998, #7003). Now XGBoost no longer makes data
|
||||
copy when input is numpy array view.
|
||||
* The early stopping callback in Python has a new `min_delta` parameter to control the
|
||||
stopping behavior (#7137)
|
||||
* Python package now supports calculating feature scores for the linear model, which is
|
||||
also available on R package. (#7048)
|
||||
* Python interface now supports configuring constraints using feature names instead of
|
||||
feature indices.
|
||||
* Typehint support for more Python code including scikit-learn interface and rabit
|
||||
module. (#6799, #7240)
|
||||
* Add tutorial for XGBoost-Ray (#6884)
|
||||
|
||||
### New features in R package
|
||||
* In 1.4 we have a new prediction function in the C API which is used by the Python
|
||||
package. This release revises the R package to use the new prediction function as well.
|
||||
A new parameter `iteration_range` for the predict function is available, which can be
|
||||
used for specifying the range of trees for running prediction. (#6819, #7126)
|
||||
* R package now supports the `nthread` parameter in `DMatrix` construction. (#7127)
|
||||
|
||||
### New features in JVM packages
|
||||
* Support GPU dataframe and `DeviceQuantileDMatrix` (#7195). Constructing `DMatrix`
|
||||
with GPU data structures and the interface for quantized `DMatrix` were first
|
||||
introduced in the Python package and are now available in the xgboost4j package.
|
||||
* JVM packages now support saving and getting early stopping attributes. (#7095) Here is a
|
||||
quick [example](https://github.com/dmlc/xgboost/jvm-packages/xgboost4j-example/src/main/java/ml/dmlc/xgboost4j/java/example/EarlyStopping.java "example") in JAVA (#7252).
|
||||
|
||||
### General new features
|
||||
* We now have a pre-built binary package for R on Windows with GPU support. (#7185)
|
||||
* CUDA compute capability 86 is now part of the default CMake build configuration with
|
||||
newly added support for CUDA 11.4. (#7131, #7182, #7254)
|
||||
* XGBoost can be compiled using system CUB provided by CUDA 11.x installation. (#7232)
|
||||
|
||||
### Optimizations
|
||||
The performance for both `hist` and `gpu_hist` has been significantly improved in 1.5
|
||||
with the following optimizations:
|
||||
* GPU multi-class model training now supports prediction cache. (#6860)
|
||||
* GPU histogram building is sped up and the overall training time is 2-3 times faster on
|
||||
large datasets (#7180, #7198). In addition, we removed the parameter `deterministic_histogram` and now
|
||||
the GPU algorithm is always deterministic.
|
||||
* CPU hist has an optimized procedure for data sampling (#6922)
|
||||
* More performance optimization in regression and binary classification objectives on
|
||||
CPU (#7206)
|
||||
* Tree model dump is now performed in parallel (#7040)
|
||||
|
||||
### Breaking changes
|
||||
* `n_gpus` was deprecated in 1.0 release and is now removed.
|
||||
* Feature grouping in CPU hist tree method is removed, which was disabled long
|
||||
ago. (#7018)
|
||||
* C API for Quantile DMatrix is changed to be consistent with the new external memory
|
||||
implementation. (#7082)
|
||||
|
||||
### Notable general bug fixes
|
||||
* XGBoost no long changes global CUDA device ordinal when `gpu_id` is specified (#6891,
|
||||
#6987)
|
||||
* Fix `gamma` negative likelihood evaluation metric. (#7275)
|
||||
* Fix integer value of `verbose_eal` for `xgboost.cv` function in Python. (#7291)
|
||||
* Remove extra sync in CPU hist for dense data, which can lead to incorrect tree node
|
||||
statistics. (#7120, #7128)
|
||||
* Fix a bug in GPU hist when data size is larger than `UINT32_MAX` with missing
|
||||
values. (#7026)
|
||||
* Fix a thread safety issue in prediction with the `softmax` objective. (#7104)
|
||||
* Fix a thread safety issue in CPU SHAP value computation. (#7050) Please note that all
|
||||
prediction functions in Python are thread-safe.
|
||||
* Fix model slicing. (#7149, #7078)
|
||||
* Workaround a bug in old GCC which can lead to segfault during construction of
|
||||
DMatrix. (#7161)
|
||||
* Fix histogram truncation in GPU hist, which can lead to slightly-off results. (#7181)
|
||||
* Fix loading GPU linear model pickle files on CPU-only machine. (#7154)
|
||||
* Check input value is duplicated when CPU quantile queue is full (#7091)
|
||||
* Fix parameter loading with training continuation. (#7121)
|
||||
* Fix CMake interface for exposing C library by specifying dependencies. (#7099)
|
||||
* Callback and early stopping are explicitly disabled for the scikit-learn interface
|
||||
random forest estimator. (#7236)
|
||||
* Fix compilation error on x86 (32-bit machine) (#6964)
|
||||
* Fix CPU memory usage with extremely sparse datasets (#7255)
|
||||
* Fix a bug in GPU multi-class AUC implementation with weighted data (#7300)
|
||||
|
||||
### Python package
|
||||
Other than the items mentioned in the previous sections, there are some Python-specific
|
||||
improvements.
|
||||
* Change development release postfix to `dev` (#6988)
|
||||
* Fix early stopping behavior with MAPE metric (#7061)
|
||||
* Fixed incorrect feature mismatch error message (#6949)
|
||||
* Add predictor to skl constructor. (#7000, #7159)
|
||||
* Re-enable feature validation in predict proba. (#7177)
|
||||
* scikit learn interface regression estimator now can pass the scikit-learn estimator
|
||||
check and is fully compatible with scikit-learn utilities. `__sklearn_is_fitted__` is
|
||||
implemented as part of the changes (#7130, #7230)
|
||||
* Conform the latest pylint. (#7071, #7241)
|
||||
* Support latest panda range index in DMatrix construction. (#7074)
|
||||
* Fix DMatrix construction from pandas series. (#7243)
|
||||
* Fix typo and grammatical mistake in error message (#7134)
|
||||
* [dask] disable work stealing explicitly for training tasks (#6794)
|
||||
* [dask] Set dataframe index in predict. (#6944)
|
||||
* [dask] Fix prediction on df with latest dask. (#6969)
|
||||
* [dask] Fix dask predict on `DaskDMatrix` with `iteration_range`. (#7005)
|
||||
* [dask] Disallow importing non-dask estimators from xgboost.dask (#7133)
|
||||
|
||||
### R package
|
||||
Improvements other than new features on R package:
|
||||
* Optimization for updating R handles in-place (#6903)
|
||||
* Removed the magrittr dependency. (#6855, #6906, #6928)
|
||||
* The R package now hides all C++ symbols to avoid conflicts. (#7245)
|
||||
* Other maintenance including code cleanups, document updates. (#6863, #6915, #6930, #6966, #6967)
|
||||
|
||||
### JVM packages
|
||||
Improvements other than new features on JVM packages:
|
||||
* Constructors with implicit missing value are deprecated due to confusing behaviors. (#7225)
|
||||
* Reduce scala-compiler, scalatest dependency scopes (#6730)
|
||||
* Making the Java library loader emit helpful error messages on missing dependencies. (#6926)
|
||||
* JVM packages now use the Python tracker in XGBoost instead of dmlc. The one in XGBoost
|
||||
is shared between JVM packages and Python Dask and enjoys better maintenance (#7132)
|
||||
* Fix "key not found: train" error (#6842)
|
||||
* Fix model loading from stream (#7067)
|
||||
|
||||
### General document improvements
|
||||
* Overhaul the installation documents. (#6877)
|
||||
* A few demos are added for AFT with dask (#6853), callback with dask (#6995), inference
|
||||
in C (#7151), `process_type`. (#7135)
|
||||
* Fix PDF format of document. (#7143)
|
||||
* Clarify the behavior of `use_rmm`. (#6808)
|
||||
* Clarify prediction function. (#6813)
|
||||
* Improve tutorial on feature interactions (#7219)
|
||||
* Add small example for dask sklearn interface. (#6970)
|
||||
* Update Python intro. (#7235)
|
||||
* Some fixes/updates (#6810, #6856, #6935, #6948, #6976, #7084, #7097, #7170, #7173, #7174, #7226, #6979, #6809, #6796, #6979)
|
||||
|
||||
### Maintenance
|
||||
* Some refactoring around CPU hist, which lead to better performance but are listed under general maintenance tasks:
|
||||
- Extract evaluate splits from CPU hist. (#7079)
|
||||
- Merge lossgude and depthwise strategies for CPU hist (#7007)
|
||||
- Simplify sparse and dense CPU hist kernels (#7029)
|
||||
- Extract histogram builder from CPU Hist. (#7152)
|
||||
|
||||
* Others
|
||||
- Fix `gpu_id` with custom objective. (#7015)
|
||||
- Fix typos in AUC. (#6795)
|
||||
- Use constexpr in `dh::CopyIf`. (#6828)
|
||||
- Update dmlc-core. (#6862)
|
||||
- Bump version to 1.5.0 snapshot in master. (#6875)
|
||||
- Relax shotgun test. (#6900)
|
||||
- Guard against index error in prediction. (#6982)
|
||||
- Hide symbols in CI build + hide symbols for C and CUDA (#6798)
|
||||
- Persist data in dask test. (#7077)
|
||||
- Fix typo in arguments of PartitionBuilder::Init (#7113)
|
||||
- Fix typo in src/common/hist.cc BuildHistKernel (#7116)
|
||||
- Use upstream URI in distributed quantile tests. (#7129)
|
||||
- Include cpack (#7160)
|
||||
- Remove synchronization in monitor. (#7164)
|
||||
- Remove unused code. (#7175)
|
||||
- Fix building on CUDA 11.0. (#7187)
|
||||
- Better error message for `ncclUnhandledCudaError`. (#7190)
|
||||
- Add noexcept to JSON objects. (#7205)
|
||||
- Improve wording for warning (#7248)
|
||||
- Fix typo in release script. [skip ci] (#7238)
|
||||
- Relax shotgun test. (#6918)
|
||||
- Relax test for decision stump in distributed environment. (#6919)
|
||||
- [dask] speed up tests (#7020)
|
||||
|
||||
### CI
|
||||
* [CI] Rotate access keys for uploading MacOS artifacts from Travis CI (#7253)
|
||||
* Reduce Travis environment setup time. (#6912)
|
||||
* Restore R cache on github action. (#6985)
|
||||
* [CI] Remove stray build artifact to avoid error in artifact packaging (#6994)
|
||||
* [CI] Move appveyor tests to action (#6986)
|
||||
* Remove appveyor badge. [skip ci] (#7035)
|
||||
* [CI] Configure RAPIDS, dask, modin (#7033)
|
||||
* Test on s390x. (#7038)
|
||||
* [CI] Upgrade to CMake 3.14 (#7060)
|
||||
* [CI] Update R cache. (#7102)
|
||||
* [CI] Pin libomp to 11.1.0 (#7107)
|
||||
* [CI] Upgrade build image to CentOS 7 + GCC 8; require CUDA 10.1 and later (#7141)
|
||||
* [dask] Work around segfault in prediction. (#7112)
|
||||
* [dask] Remove the workaround for segfault. (#7146)
|
||||
* [CI] Fix hanging Python setup in Windows CI (#7186)
|
||||
* [CI] Clean up in beginning of each task in Win CI (#7189)
|
||||
* Fix travis. (#7237)
|
||||
|
||||
### Acknowledgement
|
||||
* **Contributors**: Adam Pocock (@Craigacp), Jeff H (@JeffHCross), Johan Hansson (@JohanWork), Jose Manuel Llorens (@JoseLlorensRipolles), Benjamin Szőke (@Livius90), @ReeceGoding, @ShvetsKS, Robert Zabel (@ZabelTech), Ali (@ali5h), Andrew Ziem (@az0), Andy Adinets (@canonizer), @david-cortes, Daniel Saxton (@dsaxton), Emil Sadek (@esadek), @farfarawayzyt, Gil Forsyth (@gforsyth), @giladmaya, @graue70, Philip Hyunsu Cho (@hcho3), James Lamb (@jameslamb), José Morales (@jmoralez), Kai Fricke (@krfricke), Christian Lorentzen (@lorentzenchr), Mads R. B. Kristensen (@madsbk), Anton Kostin (@masguit42), Martin Petříček (@mpetricek-corp), @naveenkb, Taewoo Kim (@oOTWK), Viktor Szathmáry (@phraktle), Robert Maynard (@robertmaynard), TP Boudreau (@tpboudreau), Jiaming Yuan (@trivialfis), Paul Taylor (@trxcllnt), @vslaykovsky, Bobby Wang (@wbo4958),
|
||||
* **Reviewers**: Nan Zhu (@CodingCat), Adam Pocock (@Craigacp), Jose Manuel Llorens (@JoseLlorensRipolles), Kodi Arfer (@Kodiologist), Benjamin Szőke (@Livius90), Mark Guryanov (@MarkGuryanov), Rory Mitchell (@RAMitchell), @ReeceGoding, @ShvetsKS, Egor Smirnov (@SmirnovEgorRu), Andrew Ziem (@az0), @candalfigomoro, Andy Adinets (@canonizer), Dante Gama Dessavre (@dantegd), @david-cortes, Daniel Saxton (@dsaxton), @farfarawayzyt, Gil Forsyth (@gforsyth), Harutaka Kawamura (@harupy), Philip Hyunsu Cho (@hcho3), @jakirkham, James Lamb (@jameslamb), José Morales (@jmoralez), James Bourbeau (@jrbourbeau), Christian Lorentzen (@lorentzenchr), Martin Petříček (@mpetricek-corp), Nikolay Petrov (@napetrov), @naveenkb, Viktor Szathmáry (@phraktle), Robin Teuwens (@rteuwens), Yuan Tang (@terrytangyuan), TP Boudreau (@tpboudreau), Jiaming Yuan (@trivialfis), @vkuzmin-uber, Bobby Wang (@wbo4958), William Hicks (@wphicks)
|
||||
|
||||
|
||||
## v1.4.2 (2021.05.13)
|
||||
This is a patch release for Python package with following fixes:
|
||||
|
||||
* Handle the latest version of cupy.ndarray in inplace_predict. (#6933)
|
||||
* Ensure output array from predict_leaf is (n_samples, ) when there's only 1 tree. 1.4.0 outputs (n_samples, 1). (#6889)
|
||||
* Fix empty dataset handling with multi-class AUC. (#6947)
|
||||
* Handle object type from pandas in inplace_predict. (#6927)
|
||||
|
||||
|
||||
## v1.4.1 (2021.04.20)
|
||||
This is a bug fix release.
|
||||
|
||||
* Fix GPU implementation of AUC on some large datasets. (#6866)
|
||||
|
||||
## v1.4.0 (2021.04.12)
|
||||
|
||||
### Introduction of pre-built binary package for R, with GPU support
|
||||
Starting with release 1.4.0, users now have the option of installing `{xgboost}` without
|
||||
having to build it from the source. This is particularly advantageous for users who want
|
||||
to take advantage of the GPU algorithm (`gpu_hist`), as previously they'd have to build
|
||||
`{xgboost}` from the source using CMake and NVCC. Now installing `{xgboost}` with GPU
|
||||
support is as easy as: `R CMD INSTALL ./xgboost_r_gpu_linux.tar.gz`. (#6827)
|
||||
|
||||
See the instructions at https://xgboost.readthedocs.io/en/latest/build.html
|
||||
|
||||
### Improvements on prediction functions
|
||||
XGBoost has many prediction types including shap value computation and inplace prediction.
|
||||
In 1.4 we overhauled the underlying prediction functions for C API and Python API with an
|
||||
unified interface. (#6777, #6693, #6653, #6662, #6648, #6668, #6804)
|
||||
* Starting with 1.4, sklearn interface prediction will use inplace predict by default when
|
||||
input data is supported.
|
||||
* Users can use inplace predict with `dart` booster and enable GPU acceleration just
|
||||
like `gbtree`.
|
||||
* Also all prediction functions with tree models are now thread-safe. Inplace predict is
|
||||
improved with `base_margin` support.
|
||||
* A new set of C predict functions are exposed in the public interface.
|
||||
* A user-visible change is a newly added parameter called `strict_shape`. See
|
||||
https://xgboost.readthedocs.io/en/latest/prediction.html for more details.
|
||||
|
||||
|
||||
### Improvement on Dask interface
|
||||
* Starting with 1.4, the Dask interface is considered to be feature-complete, which means
|
||||
all of the models found in the single node Python interface are now supported in Dask,
|
||||
including but not limited to ranking and random forest. Also, the prediction function
|
||||
is significantly faster and supports shap value computation.
|
||||
- Most of the parameters found in single node sklearn interface are supported by
|
||||
Dask interface. (#6471, #6591)
|
||||
- Implements learning to rank. On the Dask interface, we use the newly added support of
|
||||
query ID to enable group structure. (#6576)
|
||||
- The Dask interface has Python type hints support. (#6519)
|
||||
- All models can be safely pickled. (#6651)
|
||||
- Random forest estimators are now supported. (#6602)
|
||||
- Shap value computation is now supported. (#6575, #6645, #6614)
|
||||
- Evaluation result is printed on the scheduler process. (#6609)
|
||||
- `DaskDMatrix` (and device quantile dmatrix) now accepts all meta-information. (#6601)
|
||||
|
||||
* Prediction optimization. We enhanced and speeded up the prediction function for the
|
||||
Dask interface. See the latest Dask tutorial page in our document for an overview of
|
||||
how you can optimize it even further. (#6650, #6645, #6648, #6668)
|
||||
|
||||
* Bug fixes
|
||||
- If you are using the latest Dask and distributed where `distributed.MultiLock` is
|
||||
present, XGBoost supports training multiple models on the same cluster in
|
||||
parallel. (#6743)
|
||||
- A bug fix for when using `dask.client` to launch async task, XGBoost might use a
|
||||
different client object internally. (#6722)
|
||||
|
||||
* Other improvements on documents, blogs, tutorials, and demos. (#6389, #6366, #6687,
|
||||
#6699, #6532, #6501)
|
||||
|
||||
### Python package
|
||||
With changes from Dask and general improvement on prediction, we have made some
|
||||
enhancements on the general Python interface and IO for booster information. Starting
|
||||
from 1.4, booster feature names and types can be saved into the JSON model. Also some
|
||||
model attributes like `best_iteration`, `best_score` are restored upon model load. On
|
||||
sklearn interface, some attributes are now implemented as Python object property with
|
||||
better documents.
|
||||
|
||||
* Breaking change: All `data` parameters in prediction functions are renamed to `X`
|
||||
for better compliance to sklearn estimator interface guidelines.
|
||||
* Breaking change: XGBoost used to generate some pseudo feature names with `DMatrix`
|
||||
when inputs like `np.ndarray` don't have column names. The procedure is removed to
|
||||
avoid conflict with other inputs. (#6605)
|
||||
* Early stopping with training continuation is now supported. (#6506)
|
||||
* Optional import for Dask and cuDF are now lazy. (#6522)
|
||||
* As mentioned in the prediction improvement summary, the sklearn interface uses inplace
|
||||
prediction whenever possible. (#6718)
|
||||
* Booster information like feature names and feature types are now saved into the JSON
|
||||
model file. (#6605)
|
||||
* All `DMatrix` interfaces including `DeviceQuantileDMatrix` and counterparts in Dask
|
||||
interface (as mentioned in the Dask changes summary) now accept all the meta-information
|
||||
like `group` and `qid` in their constructor for better consistency. (#6601)
|
||||
* Booster attributes are restored upon model load so users don't have to call `attr`
|
||||
manually. (#6593)
|
||||
* On sklearn interface, all models accept `base_margin` for evaluation datasets. (#6591)
|
||||
* Improvements over the setup script including smaller sdist size and faster installation
|
||||
if the C++ library is already built (#6611, #6694, #6565).
|
||||
|
||||
* Bug fixes for Python package:
|
||||
- Don't validate feature when number of rows is 0. (#6472)
|
||||
- Move metric configuration into booster. (#6504)
|
||||
- Calling XGBModel.fit() should clear the Booster by default (#6562)
|
||||
- Support `_estimator_type`. (#6582)
|
||||
- [dask, sklearn] Fix predict proba. (#6566, #6817)
|
||||
- Restore unknown data support. (#6595)
|
||||
- Fix learning rate scheduler with cv. (#6720)
|
||||
- Fixes small typo in sklearn documentation (#6717)
|
||||
- [python-package] Fix class Booster: feature_types = None (#6705)
|
||||
- Fix divide by 0 in feature importance when no split is found. (#6676)
|
||||
|
||||
|
||||
### JVM package
|
||||
* [jvm-packages] fix early stopping doesn't work even without custom_eval setting (#6738)
|
||||
* fix potential TaskFailedListener's callback won't be called (#6612)
|
||||
* [jvm] Add ability to load booster direct from byte array (#6655)
|
||||
* [jvm-packages] JVM library loader extensions (#6630)
|
||||
|
||||
### R package
|
||||
* R documentation: Make construction of DMatrix consistent.
|
||||
* Fix R documentation for xgb.train. (#6764)
|
||||
|
||||
### ROC-AUC
|
||||
We re-implemented the ROC-AUC metric in XGBoost. The new implementation supports
|
||||
multi-class classification and has better support for learning to rank tasks that are not
|
||||
binary. Also, it has a better-defined average on distributed environments with additional
|
||||
handling for invalid datasets. (#6749, #6747, #6797)
|
||||
|
||||
### Global configuration.
|
||||
Starting from 1.4, XGBoost's Python, R and C interfaces support a new global configuration
|
||||
model where users can specify some global parameters. Currently, supported parameters are
|
||||
`verbosity` and `use_rmm`. The latter is experimental, see rmm plugin demo and
|
||||
related README file for details. (#6414, #6656)
|
||||
|
||||
### Other New features.
|
||||
* Better handling for input data types that support `__array_interface__`. For some
|
||||
data types including GPU inputs and `scipy.sparse.csr_matrix`, XGBoost employs
|
||||
`__array_interface__` for processing the underlying data. Starting from 1.4, XGBoost
|
||||
can accept arbitrary array strides (which means column-major is supported) without
|
||||
making data copies, potentially reducing a significant amount of memory consumption.
|
||||
Also version 3 of `__cuda_array_interface__` is now supported. (#6776, #6765, #6459,
|
||||
#6675)
|
||||
* Improved parameter validation, now feeding XGBoost with parameters that contain
|
||||
whitespace will trigger an error. (#6769)
|
||||
* For Python and R packages, file paths containing the home indicator `~` are supported.
|
||||
* As mentioned in the Python changes summary, the JSON model can now save feature
|
||||
information of the trained booster. The JSON schema is updated accordingly. (#6605)
|
||||
* Development of categorical data support is continued. Newly added weighted data support
|
||||
and `dart` booster support. (#6508, #6693)
|
||||
* As mentioned in Dask change summary, ranking now supports the `qid` parameter for
|
||||
query groups. (#6576)
|
||||
* `DMatrix.slice` can now consume a numpy array. (#6368)
|
||||
|
||||
### Other breaking changes
|
||||
* Aside from the feature name generation, there are 2 breaking changes:
|
||||
- Drop saving binary format for memory snapshot. (#6513, #6640)
|
||||
- Change default evaluation metric for binary:logitraw objective to logloss (#6647)
|
||||
|
||||
### CPU Optimization
|
||||
* Aside from the general changes on predict function, some optimizations are applied on
|
||||
CPU implementation. (#6683, #6550, #6696, #6700)
|
||||
* Also performance for sampling initialization in `hist` is improved. (#6410)
|
||||
|
||||
### Notable fixes in the core library
|
||||
These fixes do not reside in particular language bindings:
|
||||
* Fixes for gamma regression. This includes checking for invalid input values, fixes for
|
||||
gamma deviance metric, and better floating point guard for gamma negative log-likelihood
|
||||
metric. (#6778, #6537, #6761)
|
||||
* Random forest with `gpu_hist` might generate low accuracy in previous versions. (#6755)
|
||||
* Fix a bug in GPU sketching when data size exceeds limit of 32-bit integer. (#6826)
|
||||
* Memory consumption fix for row-major adapters (#6779)
|
||||
* Don't estimate sketch batch size when rmm is used. (#6807) (#6830)
|
||||
* Fix in-place predict with missing value. (#6787)
|
||||
* Re-introduce double buffer in UpdatePosition, to fix perf regression in gpu_hist (#6757)
|
||||
* Pass correct split_type to GPU predictor (#6491)
|
||||
* Fix DMatrix feature names/types IO. (#6507)
|
||||
* Use view for `SparsePage` exclusively to avoid some data access races. (#6590)
|
||||
* Check for invalid data. (#6742)
|
||||
* Fix relocatable include in CMakeList (#6734) (#6737)
|
||||
* Fix DMatrix slice with feature types. (#6689)
|
||||
|
||||
### Other deprecation notices:
|
||||
|
||||
* This release will be the last release to support CUDA 10.0. (#6642)
|
||||
|
||||
* Starting in the next release, the Python package will require Pip 19.3+ due to the use
|
||||
of manylinux2014 tag. Also, CentOS 6, RHEL 6 and other old distributions will not be
|
||||
supported.
|
||||
|
||||
### Known issue:
|
||||
|
||||
MacOS build of the JVM packages doesn't support multi-threading out of the box. To enable
|
||||
multi-threading with JVM packages, MacOS users will need to build the JVM packages from
|
||||
the source. See https://xgboost.readthedocs.io/en/latest/jvm/index.html#installation-from-source
|
||||
|
||||
|
||||
### Doc
|
||||
* Dedicated page for `tree_method` parameter is added. (#6564, #6633)
|
||||
* [doc] Add FLAML as a fast tuning tool for XGBoost (#6770)
|
||||
* Add document for tests directory. [skip ci] (#6760)
|
||||
* Fix doc string of config.py to use correct `versionadded` (#6458)
|
||||
* Update demo for prediction. (#6789)
|
||||
* [Doc] Document that AUCPR is for binary classification/ranking (#5899)
|
||||
* Update the C API comments (#6457)
|
||||
* Fix document. [skip ci] (#6669)
|
||||
|
||||
### Maintenance: Testing, continuous integration
|
||||
* Use CPU input for test_boost_from_prediction. (#6818)
|
||||
* [CI] Upload xgboost4j.dll to S3 (#6781)
|
||||
* Update dmlc-core submodule (#6745)
|
||||
* [CI] Use manylinux2010_x86_64 container to vendor libgomp (#6485)
|
||||
* Add conda-forge badge (#6502)
|
||||
* Fix merge conflict. (#6512)
|
||||
* [CI] Split up main.yml, add mypy. (#6515)
|
||||
* [Breaking] Upgrade cuDF and RMM to 0.18 nightlies; require RMM 0.18+ for RMM plugin (#6510)
|
||||
* "featue_map" typo changed to "feature_map" (#6540)
|
||||
* Add script for generating release tarball. (#6544)
|
||||
* Add credentials to .gitignore (#6559)
|
||||
* Remove warnings in tests. (#6554)
|
||||
* Update dmlc-core submodule and conform to new API (#6431)
|
||||
* Suppress hypothesis health check for dask client. (#6589)
|
||||
* Fix pylint. (#6714)
|
||||
* [CI] Clear R package cache (#6746)
|
||||
* Exclude dmlc test on github action. (#6625)
|
||||
* Tests for regression metrics with weights. (#6729)
|
||||
* Add helper script and doc for releasing pip package. (#6613)
|
||||
* Support pylint 2.7.0 (#6726)
|
||||
* Remove R cache in github action. (#6695)
|
||||
* [CI] Do not mix up stashed executable built for ARM and x86_64 platforms (#6646)
|
||||
* [CI] Add ARM64 test to Jenkins pipeline (#6643)
|
||||
* Disable s390x and arm64 tests on travis for now. (#6641)
|
||||
* Move sdist test to action. (#6635)
|
||||
* [dask] Rework base margin test. (#6627)
|
||||
|
||||
|
||||
### Maintenance: Refactor code for legibility and maintainability
|
||||
* Improve OpenMP exception handling (#6680)
|
||||
* Improve string view to reduce string allocation. (#6644)
|
||||
* Simplify Span checks. (#6685)
|
||||
* Use generic dispatching routine for array interface. (#6672)
|
||||
|
||||
|
||||
## v1.3.0 (2020.12.08)
|
||||
|
||||
### XGBoost4J-Spark: Exceptions should cancel jobs gracefully instead of killing SparkContext (#6019).
|
||||
@@ -873,7 +1607,7 @@ This release marks a major milestone for the XGBoost project.
|
||||
* Specify version macro in CMake. (#4730)
|
||||
* Include dmlc-tracker into XGBoost Python package (#4731)
|
||||
* [CI] Use long key ID for Ubuntu repository fingerprints. (#4783)
|
||||
* Remove plugin, cuda related code in automake & autoconf files (#4789)
|
||||
* Remove plugin, CUDA related code in automake & autoconf files (#4789)
|
||||
* Skip related tests when scikit-learn is not installed. (#4791)
|
||||
* Ignore vscode and clion files (#4866)
|
||||
* Use bundled Google Test by default (#4900)
|
||||
@@ -904,7 +1638,7 @@ This release marks a major milestone for the XGBoost project.
|
||||
### Usability Improvements, Documentation
|
||||
* Add Random Forest API to Python API doc (#4500)
|
||||
* Fix Python demo and doc. (#4545)
|
||||
* Remove doc about not supporting cuda 10.1 (#4578)
|
||||
* Remove doc about not supporting CUDA 10.1 (#4578)
|
||||
* Address some sphinx warnings and errors, add doc for building doc. (#4589)
|
||||
* Add instruction to run formatting checks locally (#4591)
|
||||
* Fix docstring for `XGBModel.predict()` (#4592)
|
||||
@@ -919,7 +1653,7 @@ This release marks a major milestone for the XGBoost project.
|
||||
* Update XGBoost4J-Spark doc (#4804)
|
||||
* Regular formatting for evaluation metrics (#4803)
|
||||
* [jvm-packages] Refine documentation for handling missing values in XGBoost4J-Spark (#4805)
|
||||
* Monitor for distributed envorinment (#4829). This is useful for identifying performance bottleneck.
|
||||
* Monitor for distributed environment (#4829). This is useful for identifying performance bottleneck.
|
||||
* Add check for length of weights and produce a good error message (#4872)
|
||||
* Fix DMatrix doc (#4884)
|
||||
* Export C++ headers in CMake installation (#4897)
|
||||
@@ -1391,7 +2125,7 @@ This release is packed with many new features and bug fixes.
|
||||
### Known issues
|
||||
* Quantile sketcher fails to produce any quantile for some edge cases (#2943)
|
||||
* The `hist` algorithm leaks memory when used with learning rate decay callback (#3579)
|
||||
* Using custom evaluation funciton together with early stopping causes assertion failure in XGBoost4J-Spark (#3595)
|
||||
* Using custom evaluation function together with early stopping causes assertion failure in XGBoost4J-Spark (#3595)
|
||||
* Early stopping doesn't work with `gblinear` learner (#3789)
|
||||
* Label and weight vectors are not reshared upon the change in number of GPUs (#3794). To get around this issue, delete the `DMatrix` object and re-load.
|
||||
* The `DMatrix` Python objects are initialized with incorrect values when given array slices (#3841)
|
||||
@@ -1485,7 +2219,7 @@ This version is only applicable for the Python package. The content is identical
|
||||
- Add scripts to cross-build and deploy artifacts (#3276, #3307)
|
||||
- Fix a compilation error for Scala 2.10 (#3332)
|
||||
* BREAKING CHANGES
|
||||
- `XGBClassifier.predict_proba()` no longer accepts paramter `output_margin`. The paramater makes no sense for `predict_proba()` because the method is to predict class probabilities, not raw margin scores.
|
||||
- `XGBClassifier.predict_proba()` no longer accepts parameter `output_margin`. The parameter makes no sense for `predict_proba()` because the method is to predict class probabilities, not raw margin scores.
|
||||
|
||||
## v0.71 (2018.04.11)
|
||||
* This is a minor release, mainly motivated by issues concerning `pip install`, e.g. #2426, #3189, #3118, and #3194.
|
||||
@@ -1501,7 +2235,7 @@ This version is only applicable for the Python package. The content is identical
|
||||
- AUC-PR metric for ranking task (#3172)
|
||||
- Monotonic constraints for 'hist' algorithm (#3085)
|
||||
* GPU support
|
||||
- Create an abtract 1D vector class that moves data seamlessly between the main and GPU memory (#2935, #3116, #3068). This eliminates unnecessary PCIe data transfer during training time.
|
||||
- Create an abstract 1D vector class that moves data seamlessly between the main and GPU memory (#2935, #3116, #3068). This eliminates unnecessary PCIe data transfer during training time.
|
||||
- Fix minor bugs (#3051, #3217)
|
||||
- Fix compatibility error for CUDA 9.1 (#3218)
|
||||
* Python package:
|
||||
@@ -1529,7 +2263,7 @@ This version is only applicable for the Python package. The content is identical
|
||||
* Refactored gbm to allow more friendly cache strategy
|
||||
- Specialized some prediction routine
|
||||
* Robust `DMatrix` construction from a sparse matrix
|
||||
* Faster consturction of `DMatrix` from 2D NumPy matrices: elide copies, use of multiple threads
|
||||
* Faster construction of `DMatrix` from 2D NumPy matrices: elide copies, use of multiple threads
|
||||
* Automatically remove nan from input data when it is sparse.
|
||||
- This can solve some of user reported problem of istart != hist.size
|
||||
* Fix the single-instance prediction function to obtain correct predictions
|
||||
@@ -1557,7 +2291,7 @@ This version is only applicable for the Python package. The content is identical
|
||||
- Faster, histogram-based tree algorithm (`tree_method='hist'`) .
|
||||
- GPU/CUDA accelerated tree algorithms (`tree_method='gpu_hist'` or `'gpu_exact'`), including the GPU-based predictor.
|
||||
- Monotonic constraints: when other features are fixed, force the prediction to be monotonic increasing with respect to a certain specified feature.
|
||||
- Faster gradient caculation using AVX SIMD
|
||||
- Faster gradient calculation using AVX SIMD
|
||||
- Ability to export models in JSON format
|
||||
- Support for Tweedie regression
|
||||
- Additional dropout options for DART: binomial+1, epsilon
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Package: xgboost
|
||||
Type: Package
|
||||
Title: Extreme Gradient Boosting
|
||||
Version: 1.4.2.1
|
||||
Date: 2020-08-28
|
||||
Version: 1.7.4.1
|
||||
Date: 2023-02-15
|
||||
Authors@R: c(
|
||||
person("Tianqi", "Chen", role = c("aut"),
|
||||
email = "tianqi.tchen@gmail.com"),
|
||||
person("Tong", "He", role = c("aut", "cre"),
|
||||
person("Tong", "He", role = c("aut"),
|
||||
email = "hetong007@gmail.com"),
|
||||
person("Michael", "Benesty", role = c("aut"),
|
||||
email = "michael@benesty.fr"),
|
||||
@@ -26,9 +26,12 @@ Authors@R: c(
|
||||
person("Min", "Lin", role = c("aut")),
|
||||
person("Yifeng", "Geng", role = c("aut")),
|
||||
person("Yutian", "Li", role = c("aut")),
|
||||
person("Jiaming", "Yuan", role = c("aut", "cre"),
|
||||
email = "jm.yuan@outlook.com"),
|
||||
person("XGBoost contributors", role = c("cph"),
|
||||
comment = "base XGBoost implementation")
|
||||
)
|
||||
Maintainer: Jiaming Yuan <jm.yuan@outlook.com>
|
||||
Description: Extreme Gradient Boosting, which is an efficient implementation
|
||||
of the gradient boosting framework from Chen & Guestrin (2016) <doi:10.1145/2939672.2939785>.
|
||||
This package is its R interface. The package includes efficient linear
|
||||
@@ -62,7 +65,6 @@ Imports:
|
||||
Matrix (>= 1.1-0),
|
||||
methods,
|
||||
data.table (>= 1.9.6),
|
||||
magrittr (>= 1.5),
|
||||
jsonlite (>= 1.0),
|
||||
RoxygenNote: 7.1.1
|
||||
RoxygenNote: 7.2.2
|
||||
SystemRequirements: GNU make, C++14
|
||||
|
||||
@@ -82,7 +82,6 @@ importFrom(graphics,points)
|
||||
importFrom(graphics,title)
|
||||
importFrom(jsonlite,fromJSON)
|
||||
importFrom(jsonlite,toJSON)
|
||||
importFrom(magrittr,"%>%")
|
||||
importFrom(stats,median)
|
||||
importFrom(stats,predict)
|
||||
importFrom(utils,head)
|
||||
|
||||
@@ -188,7 +188,7 @@ cb.reset.parameters <- function(new_params) {
|
||||
pnames <- gsub("\\.", "_", names(new_params))
|
||||
nrounds <- NULL
|
||||
|
||||
# run some checks in the begining
|
||||
# run some checks in the beginning
|
||||
init <- function(env) {
|
||||
nrounds <<- env$end_iteration - env$begin_iteration + 1
|
||||
|
||||
@@ -263,10 +263,7 @@ cb.reset.parameters <- function(new_params) {
|
||||
#' \itemize{
|
||||
#' \item \code{best_score} the evaluation score at the best iteration
|
||||
#' \item \code{best_iteration} at which boosting iteration the best score has occurred (1-based index)
|
||||
#' \item \code{best_ntreelimit} to use with the \code{ntreelimit} parameter in \code{predict}.
|
||||
#' It differs from \code{best_iteration} in multiclass or random forest settings.
|
||||
#' }
|
||||
#'
|
||||
#' The Same values are also stored as xgb-attributes:
|
||||
#' \itemize{
|
||||
#' \item \code{best_iteration} is stored as a 0-based iteration index (for interoperability of binary models)
|
||||
@@ -498,13 +495,12 @@ cb.cv.predict <- function(save_models = FALSE) {
|
||||
rep(NA_real_, N)
|
||||
}
|
||||
|
||||
ntreelimit <- NVL(env$basket$best_ntreelimit,
|
||||
env$end_iteration * env$num_parallel_tree)
|
||||
iterationrange <- c(1, NVL(env$basket$best_iteration, env$end_iteration) + 1)
|
||||
if (NVL(env$params[['booster']], '') == 'gblinear') {
|
||||
ntreelimit <- 0 # must be 0 for gblinear
|
||||
iterationrange <- c(1, 1) # must be 0 for gblinear
|
||||
}
|
||||
for (fd in env$bst_folds) {
|
||||
pr <- predict(fd$bst, fd$watchlist[[2]], ntreelimit = ntreelimit, reshape = TRUE)
|
||||
pr <- predict(fd$bst, fd$watchlist[[2]], iterationrange = iterationrange, reshape = TRUE)
|
||||
if (is.matrix(pred)) {
|
||||
pred[fd$index, ] <- pr
|
||||
} else {
|
||||
@@ -533,7 +529,7 @@ cb.cv.predict <- function(save_models = FALSE) {
|
||||
#' Callback closure for collecting the model coefficients history of a gblinear booster
|
||||
#' during its training.
|
||||
#'
|
||||
#' @param sparse when set to FALSE/TURE, a dense/sparse matrix is used to store the result.
|
||||
#' @param sparse when set to FALSE/TRUE, a dense/sparse matrix is used to store the result.
|
||||
#' Sparse format is useful when one expects only a subset of coefficients to be non-zero,
|
||||
#' when using the "thrifty" feature selector with fairly small number of top features
|
||||
#' selected per iteration.
|
||||
@@ -548,9 +544,11 @@ cb.cv.predict <- function(save_models = FALSE) {
|
||||
#'
|
||||
#' @return
|
||||
#' Results are stored in the \code{coefs} element of the closure.
|
||||
#' The \code{\link{xgb.gblinear.history}} convenience function provides an easy way to access it.
|
||||
#' The \code{\link{xgb.gblinear.history}} convenience function provides an easy
|
||||
#' way to access it.
|
||||
#' With \code{xgb.train}, it is either a dense of a sparse matrix.
|
||||
#' While with \code{xgb.cv}, it is a list (an element per each fold) of such matrices.
|
||||
#' While with \code{xgb.cv}, it is a list (an element per each fold) of such
|
||||
#' matrices.
|
||||
#'
|
||||
#' @seealso
|
||||
#' \code{\link{callbacks}}, \code{\link{xgb.gblinear.history}}.
|
||||
@@ -560,10 +558,9 @@ cb.cv.predict <- function(save_models = FALSE) {
|
||||
#' #
|
||||
#' # In the iris dataset, it is hard to linearly separate Versicolor class from the rest
|
||||
#' # without considering the 2nd order interactions:
|
||||
#' require(magrittr)
|
||||
#' x <- model.matrix(Species ~ .^2, iris)[,-1]
|
||||
#' colnames(x)
|
||||
#' dtrain <- xgb.DMatrix(scale(x), label = 1*(iris$Species == "versicolor"))
|
||||
#' dtrain <- xgb.DMatrix(scale(x), label = 1*(iris$Species == "versicolor"), nthread = 2)
|
||||
#' param <- list(booster = "gblinear", objective = "reg:logistic", eval_metric = "auc",
|
||||
#' lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||
#' # For 'shotgun', which is a default linear updater, using high eta values may result in
|
||||
@@ -581,21 +578,21 @@ cb.cv.predict <- function(save_models = FALSE) {
|
||||
#' bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 200, eta = 0.8,
|
||||
#' updater = 'coord_descent', feature_selector = 'thrifty', top_k = 1,
|
||||
#' callbacks = list(cb.gblinear.history()))
|
||||
#' xgb.gblinear.history(bst) %>% matplot(type = 'l')
|
||||
#' matplot(xgb.gblinear.history(bst), type = 'l')
|
||||
#' # Componentwise boosting is known to have similar effect to Lasso regularization.
|
||||
#' # Try experimenting with various values of top_k, eta, nrounds,
|
||||
#' # as well as different feature_selectors.
|
||||
#'
|
||||
#' # For xgb.cv:
|
||||
#' bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 100, eta = 0.8,
|
||||
#' callbacks = list(cb.gblinear.history()))
|
||||
#' callbacks = list(cb.gblinear.history()))
|
||||
#' # coefficients in the CV fold #3
|
||||
#' xgb.gblinear.history(bst)[[3]] %>% matplot(type = 'l')
|
||||
#' matplot(xgb.gblinear.history(bst)[[3]], type = 'l')
|
||||
#'
|
||||
#'
|
||||
#' #### Multiclass classification:
|
||||
#' #
|
||||
#' dtrain <- xgb.DMatrix(scale(x), label = as.numeric(iris$Species) - 1)
|
||||
#' dtrain <- xgb.DMatrix(scale(x), label = as.numeric(iris$Species) - 1, nthread = 2)
|
||||
#' param <- list(booster = "gblinear", objective = "multi:softprob", num_class = 3,
|
||||
#' lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||
#' # For the default linear updater 'shotgun' it sometimes is helpful
|
||||
@@ -603,15 +600,15 @@ cb.cv.predict <- function(save_models = FALSE) {
|
||||
#' bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 70, eta = 0.5,
|
||||
#' callbacks = list(cb.gblinear.history()))
|
||||
#' # Will plot the coefficient paths separately for each class:
|
||||
#' xgb.gblinear.history(bst, class_index = 0) %>% matplot(type = 'l')
|
||||
#' xgb.gblinear.history(bst, class_index = 1) %>% matplot(type = 'l')
|
||||
#' xgb.gblinear.history(bst, class_index = 2) %>% matplot(type = 'l')
|
||||
#' matplot(xgb.gblinear.history(bst, class_index = 0), type = 'l')
|
||||
#' matplot(xgb.gblinear.history(bst, class_index = 1), type = 'l')
|
||||
#' matplot(xgb.gblinear.history(bst, class_index = 2), type = 'l')
|
||||
#'
|
||||
#' # CV:
|
||||
#' bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 70, eta = 0.5,
|
||||
#' callbacks = list(cb.gblinear.history(FALSE)))
|
||||
#' # 1st forld of 1st class
|
||||
#' xgb.gblinear.history(bst, class_index = 0)[[1]] %>% matplot(type = 'l')
|
||||
#' # 1st fold of 1st class
|
||||
#' matplot(xgb.gblinear.history(bst, class_index = 0)[[1]], type = 'l')
|
||||
#'
|
||||
#' @export
|
||||
cb.gblinear.history <- function(sparse=FALSE) {
|
||||
@@ -642,9 +639,14 @@ cb.gblinear.history <- function(sparse=FALSE) {
|
||||
if (!is.null(env$bst)) { # # xgb.train:
|
||||
coefs <<- list2mat(coefs)
|
||||
} else { # xgb.cv:
|
||||
# first lapply transposes the list
|
||||
coefs <<- lapply(seq_along(coefs[[1]]), function(i) lapply(coefs, "[[", i)) %>%
|
||||
lapply(function(x) list2mat(x))
|
||||
# second lapply transposes the list
|
||||
coefs <<- lapply(
|
||||
X = lapply(
|
||||
X = seq_along(coefs[[1]]),
|
||||
FUN = function(i) lapply(coefs, "[[", i)
|
||||
),
|
||||
FUN = list2mat
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# This file is for the low level reuseable utility functions
|
||||
# that are not supposed to be visibe to a user.
|
||||
# This file is for the low level reusable utility functions
|
||||
# that are not supposed to be visible to a user.
|
||||
#
|
||||
|
||||
#
|
||||
@@ -178,7 +178,8 @@ xgb.iter.eval <- function(booster_handle, watchlist, iter, feval = NULL) {
|
||||
} else {
|
||||
res <- sapply(seq_along(watchlist), function(j) {
|
||||
w <- watchlist[[j]]
|
||||
preds <- predict(booster_handle, w, outputmargin = TRUE, ntreelimit = 0) # predict using all trees
|
||||
## predict using all trees
|
||||
preds <- predict(booster_handle, w, outputmargin = TRUE, iterationrange = c(1, 1))
|
||||
eval_res <- feval(preds, w)
|
||||
out <- eval_res$value
|
||||
names(out) <- paste0(evnames[j], "-", eval_res$metric)
|
||||
@@ -284,7 +285,7 @@ xgb.createFolds <- function(y, k = 10)
|
||||
for (i in seq_along(numInClass)) {
|
||||
## create a vector of integers from 1:k as many times as possible without
|
||||
## going over the number of samples in the class. Note that if the number
|
||||
## of samples in a class is less than k, nothing is producd here.
|
||||
## of samples in a class is less than k, nothing is produced here.
|
||||
seqVector <- rep(seq_len(k), numInClass[i] %/% k)
|
||||
## add enough random integers to get length(seqVector) == numInClass[i]
|
||||
if (numInClass[i] %% k > 0) seqVector <- c(seqVector, sample.int(k, numInClass[i] %% k))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Construct an internal xgboost Booster and return a handle to it.
|
||||
# internal utility function
|
||||
xgb.Booster.handle <- function(params = list(), cachelist = list(),
|
||||
modelfile = NULL) {
|
||||
modelfile = NULL, handle = NULL) {
|
||||
if (typeof(cachelist) != "list" ||
|
||||
!all(vapply(cachelist, inherits, logical(1), what = 'xgb.DMatrix'))) {
|
||||
stop("cachelist must be a list of xgb.DMatrix objects")
|
||||
@@ -20,7 +20,7 @@ xgb.Booster.handle <- function(params = list(), cachelist = list(),
|
||||
return(handle)
|
||||
} else if (typeof(modelfile) == "raw") {
|
||||
## A memory buffer
|
||||
bst <- xgb.unserialize(modelfile)
|
||||
bst <- xgb.unserialize(modelfile, handle)
|
||||
xgb.parameters(bst) <- params
|
||||
return (bst)
|
||||
} else if (inherits(modelfile, "xgb.Booster")) {
|
||||
@@ -129,7 +129,7 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
||||
stop("argument type must be xgb.Booster")
|
||||
|
||||
if (is.null.handle(object$handle)) {
|
||||
object$handle <- xgb.Booster.handle(modelfile = object$raw)
|
||||
object$handle <- xgb.Booster.handle(modelfile = object$raw, handle = object$handle)
|
||||
} else {
|
||||
if (is.null(object$raw) && saveraw) {
|
||||
object$raw <- xgb.serialize(object$handle)
|
||||
@@ -162,14 +162,17 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
||||
#' Predicted values based on either xgboost model or model handle object.
|
||||
#'
|
||||
#' @param object Object of class \code{xgb.Booster} or \code{xgb.Booster.handle}
|
||||
#' @param newdata takes \code{matrix}, \code{dgCMatrix}, local data file or \code{xgb.DMatrix}.
|
||||
#' @param newdata takes \code{matrix}, \code{dgCMatrix}, \code{dgRMatrix}, \code{dsparseVector},
|
||||
#' local data file or \code{xgb.DMatrix}.
|
||||
#'
|
||||
#' For single-row predictions on sparse data, it's recommended to use CSR format. If passing
|
||||
#' a sparse vector, it will take it as a row vector.
|
||||
#' @param missing Missing is only used when input is dense matrix. Pick a float value that represents
|
||||
#' missing values in data (e.g., sometimes 0 or some other extreme value is used).
|
||||
#' @param outputmargin whether the prediction should be returned in the for of original untransformed
|
||||
#' sum of predictions from boosting iterations' results. E.g., setting \code{outputmargin=TRUE} for
|
||||
#' logistic regression would result in predictions for log-odds instead of probabilities.
|
||||
#' @param ntreelimit limit the number of model's trees or boosting iterations used in prediction (see Details).
|
||||
#' It will use all the trees by default (\code{NULL} value).
|
||||
#' @param ntreelimit Deprecated, use \code{iterationrange} instead.
|
||||
#' @param predleaf whether predict leaf index.
|
||||
#' @param predcontrib whether to return feature contributions to individual predictions (see Details).
|
||||
#' @param approxcontrib whether to use a fast approximation for feature contributions (see Details).
|
||||
@@ -179,16 +182,19 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
||||
#' or predinteraction flags is TRUE.
|
||||
#' @param training whether is the prediction result used for training. For dart booster,
|
||||
#' training predicting will perform dropout.
|
||||
#' @param iterationrange Specifies which layer of trees are used in prediction. For
|
||||
#' example, if a random forest is trained with 100 rounds. Specifying
|
||||
#' `iterationrange=(1, 21)`, then only the forests built during [1, 21) (half open set)
|
||||
#' rounds are used in this prediction. It's 1-based index just like R vector. When set
|
||||
#' to \code{c(1, 1)} XGBoost will use all trees.
|
||||
#' @param strict_shape Default is \code{FALSE}. When it's set to \code{TRUE}, output
|
||||
#' type and shape of prediction are invariant to model type.
|
||||
#'
|
||||
#' @param ... Parameters passed to \code{predict.xgb.Booster}
|
||||
#'
|
||||
#' @details
|
||||
#' Note that \code{ntreelimit} is not necessarily equal to the number of boosting iterations
|
||||
#' and it is not necessarily equal to the number of trees in a model.
|
||||
#' E.g., in a random forest-like model, \code{ntreelimit} would limit the number of trees.
|
||||
#' But for multiclass classification, while there are multiple trees per iteration,
|
||||
#' \code{ntreelimit} limits the number of boosting iterations.
|
||||
#'
|
||||
#' Also note that \code{ntreelimit} would currently do nothing for predictions from gblinear,
|
||||
#' Note that \code{iterationrange} would currently do nothing for predictions from gblinear,
|
||||
#' since gblinear doesn't keep its boosting history.
|
||||
#'
|
||||
#' One possible practical applications of the \code{predleaf} option is to use the model
|
||||
@@ -209,7 +215,8 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
||||
#' of the most important features first. See below about the format of the returned results.
|
||||
#'
|
||||
#' @return
|
||||
#' For regression or binary classification, it returns a vector of length \code{nrows(newdata)}.
|
||||
#' The return type is different depending whether \code{strict_shape} is set to \code{TRUE}. By default,
|
||||
#' for regression or binary classification, it returns a vector of length \code{nrows(newdata)}.
|
||||
#' For multiclass classification, either a \code{num_class * nrows(newdata)} vector or
|
||||
#' a \code{(nrows(newdata), num_class)} dimension matrix is returned, depending on
|
||||
#' the \code{reshape} value.
|
||||
@@ -231,6 +238,13 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
||||
#' For a multiclass case, a list of \code{num_class} elements is returned, where each element is
|
||||
#' such an array.
|
||||
#'
|
||||
#' When \code{strict_shape} is set to \code{TRUE}, the output is always an array. For
|
||||
#' normal prediction, the output is a 2-dimension array \code{(num_class, nrow(newdata))}.
|
||||
#'
|
||||
#' For \code{predcontrib = TRUE}, output is \code{(ncol(newdata) + 1, num_class, nrow(newdata))}
|
||||
#' For \code{predinteraction = TRUE}, output is \code{(ncol(newdata) + 1, ncol(newdata) + 1, num_class, nrow(newdata))}
|
||||
#' For \code{predleaf = TRUE}, output is \code{(n_trees_in_forest, num_class, n_iterations, nrow(newdata))}
|
||||
#'
|
||||
#' @seealso
|
||||
#' \code{\link{xgb.train}}.
|
||||
#'
|
||||
@@ -253,7 +267,7 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
||||
#' # use all trees by default
|
||||
#' pred <- predict(bst, test$data)
|
||||
#' # use only the 1st tree
|
||||
#' pred1 <- predict(bst, test$data, ntreelimit = 1)
|
||||
#' pred1 <- predict(bst, test$data, iterationrange = c(1, 2))
|
||||
#'
|
||||
#' # Predicting tree leafs:
|
||||
#' # the result is an nsamples X ntrees matrix
|
||||
@@ -305,94 +319,152 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
||||
#' all.equal(pred, pred_labels)
|
||||
#' # prediction from using only 5 iterations should result
|
||||
#' # in the same error as seen in iteration 5:
|
||||
#' pred5 <- predict(bst, as.matrix(iris[, -5]), ntreelimit=5)
|
||||
#' pred5 <- predict(bst, as.matrix(iris[, -5]), iterationrange=c(1, 6))
|
||||
#' sum(pred5 != lb)/length(lb)
|
||||
#'
|
||||
#'
|
||||
#' ## random forest-like model of 25 trees for binary classification:
|
||||
#'
|
||||
#' set.seed(11)
|
||||
#' bst <- xgboost(data = train$data, label = train$label, max_depth = 5,
|
||||
#' nthread = 2, nrounds = 1, objective = "binary:logistic",
|
||||
#' num_parallel_tree = 25, subsample = 0.6, colsample_bytree = 0.1)
|
||||
#' # Inspect the prediction error vs number of trees:
|
||||
#' lb <- test$label
|
||||
#' dtest <- xgb.DMatrix(test$data, label=lb)
|
||||
#' err <- sapply(1:25, function(n) {
|
||||
#' pred <- predict(bst, dtest, ntreelimit=n)
|
||||
#' sum((pred > 0.5) != lb)/length(lb)
|
||||
#' })
|
||||
#' plot(err, type='l', ylim=c(0,0.1), xlab='#trees')
|
||||
#'
|
||||
#' @rdname predict.xgb.Booster
|
||||
#' @export
|
||||
predict.xgb.Booster <- function(object, newdata, missing = NA, outputmargin = FALSE, ntreelimit = NULL,
|
||||
predleaf = FALSE, predcontrib = FALSE, approxcontrib = FALSE, predinteraction = FALSE,
|
||||
reshape = FALSE, training = FALSE, ...) {
|
||||
|
||||
reshape = FALSE, training = FALSE, iterationrange = NULL, strict_shape = FALSE, ...) {
|
||||
object <- xgb.Booster.complete(object, saveraw = FALSE)
|
||||
|
||||
if (!inherits(newdata, "xgb.DMatrix"))
|
||||
newdata <- xgb.DMatrix(newdata, missing = missing)
|
||||
newdata <- xgb.DMatrix(newdata, missing = missing, nthread = NVL(object$params[["nthread"]], -1))
|
||||
if (!is.null(object[["feature_names"]]) &&
|
||||
!is.null(colnames(newdata)) &&
|
||||
!identical(object[["feature_names"]], colnames(newdata)))
|
||||
stop("Feature names stored in `object` and `newdata` are different!")
|
||||
if (is.null(ntreelimit))
|
||||
ntreelimit <- NVL(object$best_ntreelimit, 0)
|
||||
if (NVL(object$params[['booster']], '') == 'gblinear')
|
||||
|
||||
if (NVL(object$params[['booster']], '') == 'gblinear' || is.null(ntreelimit))
|
||||
ntreelimit <- 0
|
||||
if (ntreelimit < 0)
|
||||
stop("ntreelimit cannot be negative")
|
||||
|
||||
option <- 0L + 1L * as.logical(outputmargin) + 2L * as.logical(predleaf) + 4L * as.logical(predcontrib) +
|
||||
8L * as.logical(approxcontrib) + 16L * as.logical(predinteraction)
|
||||
if (ntreelimit != 0 && is.null(iterationrange)) {
|
||||
## only ntreelimit, initialize iteration range
|
||||
iterationrange <- c(0, 0)
|
||||
} else if (ntreelimit == 0 && !is.null(iterationrange)) {
|
||||
## only iteration range, handle 1-based indexing
|
||||
iterationrange <- c(iterationrange[1] - 1, iterationrange[2] - 1)
|
||||
} else if (ntreelimit != 0 && !is.null(iterationrange)) {
|
||||
## both are specified, let libgxgboost throw an error
|
||||
} else {
|
||||
## no limit is supplied, use best
|
||||
if (is.null(object$best_iteration)) {
|
||||
iterationrange <- c(0, 0)
|
||||
} else {
|
||||
## We don't need to + 1 as R is 1-based index.
|
||||
iterationrange <- c(0, as.integer(object$best_iteration))
|
||||
}
|
||||
}
|
||||
## Handle the 0 length values.
|
||||
box <- function(val) {
|
||||
if (length(val) == 0) {
|
||||
cval <- vector(, 1)
|
||||
cval[0] <- val
|
||||
return(cval)
|
||||
}
|
||||
return (val)
|
||||
}
|
||||
|
||||
ret <- .Call(XGBoosterPredict_R, object$handle, newdata, option[1],
|
||||
as.integer(ntreelimit), as.integer(training))
|
||||
## We set strict_shape to TRUE then drop the dimensions conditionally
|
||||
args <- list(
|
||||
training = box(training),
|
||||
strict_shape = box(TRUE),
|
||||
iteration_begin = box(as.integer(iterationrange[1])),
|
||||
iteration_end = box(as.integer(iterationrange[2])),
|
||||
ntree_limit = box(as.integer(ntreelimit)),
|
||||
type = box(as.integer(0))
|
||||
)
|
||||
|
||||
set_type <- function(type) {
|
||||
if (args$type != 0) {
|
||||
stop("One type of prediction at a time.")
|
||||
}
|
||||
return(box(as.integer(type)))
|
||||
}
|
||||
if (outputmargin) {
|
||||
args$type <- set_type(1)
|
||||
}
|
||||
if (predcontrib) {
|
||||
args$type <- set_type(if (approxcontrib) 3 else 2)
|
||||
}
|
||||
if (predinteraction) {
|
||||
args$type <- set_type(if (approxcontrib) 5 else 4)
|
||||
}
|
||||
if (predleaf) {
|
||||
args$type <- set_type(6)
|
||||
}
|
||||
|
||||
predts <- .Call(
|
||||
XGBoosterPredictFromDMatrix_R, object$handle, newdata, jsonlite::toJSON(args, auto_unbox = TRUE)
|
||||
)
|
||||
names(predts) <- c("shape", "results")
|
||||
shape <- predts$shape
|
||||
ret <- predts$results
|
||||
|
||||
n_ret <- length(ret)
|
||||
n_row <- nrow(newdata)
|
||||
npred_per_case <- n_ret / n_row
|
||||
if (n_row != shape[1]) {
|
||||
stop("Incorrect predict shape.")
|
||||
}
|
||||
|
||||
if (n_ret %% n_row != 0)
|
||||
stop("prediction length ", n_ret, " is not multiple of nrows(newdata) ", n_row)
|
||||
arr <- array(data = ret, dim = rev(shape))
|
||||
|
||||
cnames <- if (!is.null(colnames(newdata))) c(colnames(newdata), "BIAS") else NULL
|
||||
n_groups <- shape[2]
|
||||
|
||||
## Needed regardless of whether strict shape is being used.
|
||||
if (predcontrib) {
|
||||
dimnames(arr) <- list(cnames, NULL, NULL)
|
||||
} else if (predinteraction) {
|
||||
dimnames(arr) <- list(cnames, cnames, NULL, NULL)
|
||||
}
|
||||
if (strict_shape) {
|
||||
return(arr) # strict shape is calculated by libxgboost uniformly.
|
||||
}
|
||||
|
||||
if (predleaf) {
|
||||
ret <- if (n_ret == n_row) {
|
||||
matrix(ret, ncol = 1)
|
||||
## Predict leaf
|
||||
arr <- if (n_ret == n_row) {
|
||||
matrix(arr, ncol = 1)
|
||||
} else {
|
||||
matrix(ret, nrow = n_row, byrow = TRUE)
|
||||
matrix(arr, nrow = n_row, byrow = TRUE)
|
||||
}
|
||||
} else if (predcontrib) {
|
||||
n_col1 <- ncol(newdata) + 1
|
||||
n_group <- npred_per_case / n_col1
|
||||
cnames <- if (!is.null(colnames(newdata))) c(colnames(newdata), "BIAS") else NULL
|
||||
ret <- if (n_ret == n_row) {
|
||||
matrix(ret, ncol = 1, dimnames = list(NULL, cnames))
|
||||
} else if (n_group == 1) {
|
||||
matrix(ret, nrow = n_row, byrow = TRUE, dimnames = list(NULL, cnames))
|
||||
## Predict contribution
|
||||
arr <- aperm(a = arr, perm = c(2, 3, 1)) # [group, row, col]
|
||||
arr <- if (n_ret == n_row) {
|
||||
matrix(arr, ncol = 1, dimnames = list(NULL, cnames))
|
||||
} else if (n_groups != 1) {
|
||||
## turns array into list of matrices
|
||||
lapply(seq_len(n_groups), function(g) arr[g, , ])
|
||||
} else {
|
||||
arr <- array(ret, c(n_col1, n_group, n_row),
|
||||
dimnames = list(cnames, NULL, NULL)) %>% aperm(c(2, 3, 1)) # [group, row, col]
|
||||
lapply(seq_len(n_group), function(g) arr[g, , ])
|
||||
## remove the first axis (group)
|
||||
dn <- dimnames(arr)
|
||||
matrix(arr[1, , ], nrow = dim(arr)[2], ncol = dim(arr)[3], dimnames = c(dn[2], dn[3]))
|
||||
}
|
||||
} else if (predinteraction) {
|
||||
n_col1 <- ncol(newdata) + 1
|
||||
n_group <- npred_per_case / n_col1^2
|
||||
cnames <- if (!is.null(colnames(newdata))) c(colnames(newdata), "BIAS") else NULL
|
||||
ret <- if (n_ret == n_row) {
|
||||
matrix(ret, ncol = 1, dimnames = list(NULL, cnames))
|
||||
} else if (n_group == 1) {
|
||||
array(ret, c(n_col1, n_col1, n_row), dimnames = list(cnames, cnames, NULL)) %>% aperm(c(3, 1, 2))
|
||||
## Predict interaction
|
||||
arr <- aperm(a = arr, perm = c(3, 4, 1, 2)) # [group, row, col, col]
|
||||
arr <- if (n_ret == n_row) {
|
||||
matrix(arr, ncol = 1, dimnames = list(NULL, cnames))
|
||||
} else if (n_groups != 1) {
|
||||
## turns array into list of matrices
|
||||
lapply(seq_len(n_groups), function(g) arr[g, , , ])
|
||||
} else {
|
||||
arr <- array(ret, c(n_col1, n_col1, n_group, n_row),
|
||||
dimnames = list(cnames, cnames, NULL, NULL)) %>% aperm(c(3, 4, 1, 2)) # [group, row, col1, col2]
|
||||
lapply(seq_len(n_group), function(g) arr[g, , , ])
|
||||
## remove the first axis (group)
|
||||
arr <- arr[1, , , , drop = FALSE]
|
||||
array(arr, dim = dim(arr)[2:4], dimnames(arr)[2:4])
|
||||
}
|
||||
} else {
|
||||
## Normal prediction
|
||||
arr <- if (reshape && n_groups != 1) {
|
||||
matrix(arr, ncol = n_groups, byrow = TRUE)
|
||||
} else {
|
||||
as.vector(ret)
|
||||
}
|
||||
} else if (reshape && npred_per_case > 1) {
|
||||
ret <- matrix(ret, nrow = n_row, byrow = TRUE)
|
||||
}
|
||||
return(ret)
|
||||
return(arr)
|
||||
}
|
||||
|
||||
#' @rdname predict.xgb.Booster
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
#' Construct xgb.DMatrix object
|
||||
#'
|
||||
#' Construct xgb.DMatrix object from either a dense matrix, a sparse matrix, or a local file.
|
||||
#' Supported input file formats are either a libsvm text file or a binary file that was created previously by
|
||||
#' Supported input file formats are either a LIBSVM text file or a binary file that was created previously by
|
||||
#' \code{\link{xgb.DMatrix.save}}).
|
||||
#'
|
||||
#' @param data a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object, or a character
|
||||
#' string representing a filename.
|
||||
#' @param data a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object,
|
||||
#' a \code{dgRMatrix} object (only when making predictions from a fitted model),
|
||||
#' a \code{dsparseVector} object (only when making predictions from a fitted model, will be
|
||||
#' interpreted as a row vector), or a character string representing a filename.
|
||||
#' @param info a named list of additional information to store in the \code{xgb.DMatrix} object.
|
||||
#' See \code{\link{setinfo}} for the specific allowed kinds of
|
||||
#' @param missing a float value to represents missing values in data (used only when input is a dense matrix).
|
||||
#' It is useful when a 0 or some other extreme value represents missing values in data.
|
||||
#' @param silent whether to suppress printing an informational message after loading from a file.
|
||||
#' @param nthread Number of threads used for creating DMatrix.
|
||||
#' @param ... the \code{info} data could be passed directly as parameters, without creating an \code{info} list.
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#' xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||
#' dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||
#' if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
||||
#' @export
|
||||
xgb.DMatrix <- function(data, info = list(), missing = NA, silent = FALSE, ...) {
|
||||
xgb.DMatrix <- function(data, info = list(), missing = NA, silent = FALSE, nthread = NULL, ...) {
|
||||
cnames <- NULL
|
||||
if (typeof(data) == "character") {
|
||||
if (length(data) > 1)
|
||||
@@ -29,16 +32,32 @@ xgb.DMatrix <- function(data, info = list(), missing = NA, silent = FALSE, ...)
|
||||
data <- path.expand(data)
|
||||
handle <- .Call(XGDMatrixCreateFromFile_R, data, as.integer(silent))
|
||||
} else if (is.matrix(data)) {
|
||||
handle <- .Call(XGDMatrixCreateFromMat_R, data, missing)
|
||||
handle <- .Call(XGDMatrixCreateFromMat_R, data, missing, as.integer(NVL(nthread, -1)))
|
||||
cnames <- colnames(data)
|
||||
} else if (inherits(data, "dgCMatrix")) {
|
||||
handle <- .Call(XGDMatrixCreateFromCSC_R, data@p, data@i, data@x, nrow(data))
|
||||
handle <- .Call(
|
||||
XGDMatrixCreateFromCSC_R, data@p, data@i, data@x, nrow(data), as.integer(NVL(nthread, -1))
|
||||
)
|
||||
cnames <- colnames(data)
|
||||
} else if (inherits(data, "dgRMatrix")) {
|
||||
handle <- .Call(
|
||||
XGDMatrixCreateFromCSR_R, data@p, data@j, data@x, ncol(data), as.integer(NVL(nthread, -1))
|
||||
)
|
||||
cnames <- colnames(data)
|
||||
} else if (inherits(data, "dsparseVector")) {
|
||||
indptr <- c(0L, as.integer(length(data@i)))
|
||||
ind <- as.integer(data@i) - 1L
|
||||
handle <- .Call(
|
||||
XGDMatrixCreateFromCSR_R, indptr, ind, data@x, length(data), as.integer(NVL(nthread, -1))
|
||||
)
|
||||
} else {
|
||||
stop("xgb.DMatrix does not support construction from ", typeof(data))
|
||||
}
|
||||
dmat <- handle
|
||||
attributes(dmat) <- list(.Dimnames = list(NULL, cnames), class = "xgb.DMatrix")
|
||||
attributes(dmat) <- list(class = "xgb.DMatrix")
|
||||
if (!is.null(cnames)) {
|
||||
setinfo(dmat, "feature_name", cnames)
|
||||
}
|
||||
|
||||
info <- append(info, list(...))
|
||||
for (i in seq_along(info)) {
|
||||
@@ -51,12 +70,12 @@ xgb.DMatrix <- function(data, info = list(), missing = NA, silent = FALSE, ...)
|
||||
|
||||
# get dmatrix from data, label
|
||||
# internal helper method
|
||||
xgb.get.DMatrix <- function(data, label = NULL, missing = NA, weight = NULL) {
|
||||
xgb.get.DMatrix <- function(data, label = NULL, missing = NA, weight = NULL, nthread = NULL) {
|
||||
if (inherits(data, "dgCMatrix") || is.matrix(data)) {
|
||||
if (is.null(label)) {
|
||||
stop("label must be provided when data is a matrix")
|
||||
}
|
||||
dtrain <- xgb.DMatrix(data, label = label, missing = missing)
|
||||
dtrain <- xgb.DMatrix(data, label = label, missing = missing, nthread = nthread)
|
||||
if (!is.null(weight)){
|
||||
setinfo(dtrain, "weight", weight)
|
||||
}
|
||||
@@ -91,7 +110,7 @@ xgb.get.DMatrix <- function(data, label = NULL, missing = NA, weight = NULL) {
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' train <- agaricus.train
|
||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label, nthread = 2)
|
||||
#'
|
||||
#' stopifnot(nrow(dtrain) == nrow(train$data))
|
||||
#' stopifnot(ncol(dtrain) == ncol(train$data))
|
||||
@@ -119,7 +138,7 @@ dim.xgb.DMatrix <- function(x) {
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' train <- agaricus.train
|
||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label, nthread = 2)
|
||||
#' dimnames(dtrain)
|
||||
#' colnames(dtrain)
|
||||
#' colnames(dtrain) <- make.names(1:ncol(train$data))
|
||||
@@ -128,7 +147,9 @@ dim.xgb.DMatrix <- function(x) {
|
||||
#' @rdname dimnames.xgb.DMatrix
|
||||
#' @export
|
||||
dimnames.xgb.DMatrix <- function(x) {
|
||||
attr(x, '.Dimnames')
|
||||
fn <- getinfo(x, "feature_name")
|
||||
## row names is null.
|
||||
list(NULL, fn)
|
||||
}
|
||||
|
||||
#' @rdname dimnames.xgb.DMatrix
|
||||
@@ -139,13 +160,13 @@ dimnames.xgb.DMatrix <- function(x) {
|
||||
if (!is.null(value[[1L]]))
|
||||
stop("xgb.DMatrix does not have rownames")
|
||||
if (is.null(value[[2]])) {
|
||||
attr(x, '.Dimnames') <- NULL
|
||||
setinfo(x, "feature_name", NULL)
|
||||
return(x)
|
||||
}
|
||||
if (ncol(x) != length(value[[2]]))
|
||||
stop("can't assign ", length(value[[2]]), " colnames to a ",
|
||||
ncol(x), " column xgb.DMatrix")
|
||||
attr(x, '.Dimnames') <- value
|
||||
if (ncol(x) != length(value[[2]])) {
|
||||
stop("can't assign ", length(value[[2]]), " colnames to a ", ncol(x), " column xgb.DMatrix")
|
||||
}
|
||||
setinfo(x, "feature_name", value[[2]])
|
||||
x
|
||||
}
|
||||
|
||||
@@ -161,9 +182,9 @@ dimnames.xgb.DMatrix <- function(x) {
|
||||
#' The \code{name} field can be one of the following:
|
||||
#'
|
||||
#' \itemize{
|
||||
#' \item \code{label}: label Xgboost learn from ;
|
||||
#' \item \code{label}: label XGBoost learn from ;
|
||||
#' \item \code{weight}: to do a weight rescale ;
|
||||
#' \item \code{base_margin}: base margin is the base prediction Xgboost will boost from ;
|
||||
#' \item \code{base_margin}: base margin is the base prediction XGBoost will boost from ;
|
||||
#' \item \code{nrow}: number of rows of the \code{xgb.DMatrix}.
|
||||
#'
|
||||
#' }
|
||||
@@ -172,7 +193,7 @@ dimnames.xgb.DMatrix <- function(x) {
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#'
|
||||
#' labels <- getinfo(dtrain, 'label')
|
||||
#' setinfo(dtrain, 'label', 1-labels)
|
||||
@@ -187,13 +208,17 @@ getinfo <- function(object, ...) UseMethod("getinfo")
|
||||
#' @export
|
||||
getinfo.xgb.DMatrix <- function(object, name, ...) {
|
||||
if (typeof(name) != "character" ||
|
||||
length(name) != 1 ||
|
||||
!name %in% c('label', 'weight', 'base_margin', 'nrow',
|
||||
'label_lower_bound', 'label_upper_bound')) {
|
||||
stop("getinfo: name must be one of the following\n",
|
||||
" 'label', 'weight', 'base_margin', 'nrow', 'label_lower_bound', 'label_upper_bound'")
|
||||
length(name) != 1 ||
|
||||
!name %in% c('label', 'weight', 'base_margin', 'nrow',
|
||||
'label_lower_bound', 'label_upper_bound', "feature_type", "feature_name")) {
|
||||
stop(
|
||||
"getinfo: name must be one of the following\n",
|
||||
" 'label', 'weight', 'base_margin', 'nrow', 'label_lower_bound', 'label_upper_bound', 'feature_type', 'feature_name'"
|
||||
)
|
||||
}
|
||||
if (name != "nrow"){
|
||||
if (name == "feature_name" || name == "feature_type") {
|
||||
ret <- .Call(XGDMatrixGetStrFeatureInfo_R, object, name)
|
||||
} else if (name != "nrow"){
|
||||
ret <- .Call(XGDMatrixGetInfo_R, object, name)
|
||||
} else {
|
||||
ret <- nrow(object)
|
||||
@@ -216,15 +241,15 @@ getinfo.xgb.DMatrix <- function(object, name, ...) {
|
||||
#' The \code{name} field can be one of the following:
|
||||
#'
|
||||
#' \itemize{
|
||||
#' \item \code{label}: label Xgboost learn from ;
|
||||
#' \item \code{label}: label XGBoost learn from ;
|
||||
#' \item \code{weight}: to do a weight rescale ;
|
||||
#' \item \code{base_margin}: base margin is the base prediction Xgboost will boost from ;
|
||||
#' \item \code{base_margin}: base margin is the base prediction XGBoost will boost from ;
|
||||
#' \item \code{group}: number of rows in each group (to use with \code{rank:pairwise} objective).
|
||||
#' }
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#'
|
||||
#' labels <- getinfo(dtrain, 'label')
|
||||
#' setinfo(dtrain, 'label', 1-labels)
|
||||
@@ -271,6 +296,37 @@ setinfo.xgb.DMatrix <- function(object, name, info, ...) {
|
||||
.Call(XGDMatrixSetInfo_R, object, name, as.integer(info))
|
||||
return(TRUE)
|
||||
}
|
||||
if (name == "feature_weights") {
|
||||
if (length(info) != ncol(object)) {
|
||||
stop("The number of feature weights must equal to the number of columns in the input data")
|
||||
}
|
||||
.Call(XGDMatrixSetInfo_R, object, name, as.numeric(info))
|
||||
return(TRUE)
|
||||
}
|
||||
|
||||
set_feat_info <- function(name) {
|
||||
msg <- sprintf(
|
||||
"The number of %s must equal to the number of columns in the input data. %s vs. %s",
|
||||
name,
|
||||
length(info),
|
||||
ncol(object)
|
||||
)
|
||||
if (!is.null(info)) {
|
||||
info <- as.list(info)
|
||||
if (length(info) != ncol(object)) {
|
||||
stop(msg)
|
||||
}
|
||||
}
|
||||
.Call(XGDMatrixSetStrFeatureInfo_R, object, name, info)
|
||||
}
|
||||
if (name == "feature_name") {
|
||||
set_feat_info("feature_name")
|
||||
return(TRUE)
|
||||
}
|
||||
if (name == "feature_type") {
|
||||
set_feat_info("feature_type")
|
||||
return(TRUE)
|
||||
}
|
||||
stop("setinfo: unknown info name ", name)
|
||||
return(FALSE)
|
||||
}
|
||||
@@ -289,7 +345,7 @@ setinfo.xgb.DMatrix <- function(object, name, info, ...) {
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#'
|
||||
#' dsub <- slice(dtrain, 1:42)
|
||||
#' labels1 <- getinfo(dsub, 'label')
|
||||
@@ -345,7 +401,7 @@ slice.xgb.DMatrix <- function(object, idxset, ...) {
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#'
|
||||
#' dtrain
|
||||
#' print(dtrain, verbose=TRUE)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#' xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||
#' dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||
#' if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#'
|
||||
#' International Workshop on Data Mining for Online Advertising (ADKDD) - August 24, 2014
|
||||
#'
|
||||
#' \url{https://research.fb.com/publications/practical-lessons-from-predicting-clicks-on-ads-at-facebook/}.
|
||||
#' \url{https://research.facebook.com/publications/practical-lessons-from-predicting-clicks-on-ads-at-facebook/}.
|
||||
#'
|
||||
#' Extract explaining the method:
|
||||
#'
|
||||
@@ -48,8 +48,8 @@
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' data(agaricus.test, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtest <- with(agaricus.test, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#' dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#'
|
||||
#' param <- list(max_depth=2, eta=1, silent=1, objective='binary:logistic')
|
||||
#' nrounds = 4
|
||||
@@ -65,8 +65,12 @@
|
||||
#' new.features.test <- xgb.create.features(model = bst, agaricus.test$data)
|
||||
#'
|
||||
#' # learning with new features
|
||||
#' new.dtrain <- xgb.DMatrix(data = new.features.train, label = agaricus.train$label)
|
||||
#' new.dtest <- xgb.DMatrix(data = new.features.test, label = agaricus.test$label)
|
||||
#' new.dtrain <- xgb.DMatrix(
|
||||
#' data = new.features.train, label = agaricus.train$label, nthread = 2
|
||||
#' )
|
||||
#' new.dtest <- xgb.DMatrix(
|
||||
#' data = new.features.test, label = agaricus.test$label, nthread = 2
|
||||
#' )
|
||||
#' watchlist <- list(train = new.dtrain)
|
||||
#' bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
||||
#'
|
||||
@@ -79,7 +83,7 @@
|
||||
#' accuracy.after, "!\n"))
|
||||
#'
|
||||
#' @export
|
||||
xgb.create.features <- function(model, data, ...){
|
||||
xgb.create.features <- function(model, data, ...) {
|
||||
check.deprecation(...)
|
||||
pred_with_leaf <- predict(model, data, predleaf = TRUE)
|
||||
cols <- lapply(as.data.frame(pred_with_leaf), factor)
|
||||
|
||||
@@ -101,9 +101,7 @@
|
||||
#' parameter or randomly generated.
|
||||
#' \item \code{best_iteration} iteration number with the best evaluation metric value
|
||||
#' (only available with early stopping).
|
||||
#' \item \code{best_ntreelimit} the \code{ntreelimit} value corresponding to the best iteration,
|
||||
#' which could further be used in \code{predict} method
|
||||
#' (only available with early stopping).
|
||||
#' \item \code{best_ntreelimit} and the \code{ntreelimit} Deprecated attributes, use \code{best_iteration} instead.
|
||||
#' \item \code{pred} CV prediction values available when \code{prediction} is set.
|
||||
#' It is either vector or matrix (see \code{\link{cb.cv.predict}}).
|
||||
#' \item \code{models} a list of the CV folds' models. It is only available with the explicit
|
||||
@@ -112,9 +110,9 @@
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#' cv <- xgb.cv(data = dtrain, nrounds = 3, nthread = 2, nfold = 5, metrics = list("rmse","auc"),
|
||||
#' max_depth = 3, eta = 1, objective = "binary:logistic")
|
||||
#' max_depth = 3, eta = 1, objective = "binary:logistic")
|
||||
#' print(cv)
|
||||
#' print(cv, verbose=TRUE)
|
||||
#'
|
||||
@@ -194,7 +192,7 @@ xgb.cv <- function(params=list(), data, nrounds, nfold, label = NULL, missing =
|
||||
|
||||
# create the booster-folds
|
||||
# train_folds
|
||||
dall <- xgb.get.DMatrix(data, label, missing)
|
||||
dall <- xgb.get.DMatrix(data, label, missing, nthread = params$nthread)
|
||||
bst_folds <- lapply(seq_along(folds), function(k) {
|
||||
dtest <- slice(dall, folds[[k]])
|
||||
# code originally contributed by @RolandASc on stackoverflow
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#' @param fname the name of the text file where to save the model text dump.
|
||||
#' If not provided or set to \code{NULL}, the model is returned as a \code{character} vector.
|
||||
#' @param fmap feature map file representing feature types.
|
||||
#' Detailed description could be found at
|
||||
#' \url{https://github.com/dmlc/xgboost/wiki/Binary-Classification#dump-model}.
|
||||
#' See demo/ for walkthrough example in R, and
|
||||
#' \url{https://github.com/dmlc/xgboost/blob/master/demo/data/featmap.txt}
|
||||
#' for example Format.
|
||||
|
||||
@@ -96,40 +96,44 @@ xgb.importance <- function(feature_names = NULL, model = NULL, trees = NULL,
|
||||
if (!(is.null(feature_names) || is.character(feature_names)))
|
||||
stop("feature_names: Has to be a character vector")
|
||||
|
||||
model_text_dump <- xgb.dump(model = model, with_stats = TRUE)
|
||||
|
||||
# linear model
|
||||
if (model_text_dump[2] == "bias:"){
|
||||
weights <- which(model_text_dump == "weight:") %>%
|
||||
{model_text_dump[(. + 1):length(model_text_dump)]} %>%
|
||||
as.numeric
|
||||
|
||||
num_class <- NVL(model$params$num_class, 1)
|
||||
if (is.null(feature_names))
|
||||
feature_names <- seq(to = length(weights) / num_class) - 1
|
||||
if (length(feature_names) * num_class != length(weights))
|
||||
stop("feature_names length does not match the number of features used in the model")
|
||||
|
||||
result <- if (num_class == 1) {
|
||||
data.table(Feature = feature_names, Weight = weights)[order(-abs(Weight))]
|
||||
model <- xgb.Booster.complete(model)
|
||||
config <- jsonlite::fromJSON(xgb.config(model))
|
||||
if (config$learner$gradient_booster$name == "gblinear") {
|
||||
args <- list(importance_type = "weight", feature_names = feature_names)
|
||||
results <- .Call(
|
||||
XGBoosterFeatureScore_R, model$handle, jsonlite::toJSON(args, auto_unbox = TRUE, null = "null")
|
||||
)
|
||||
names(results) <- c("features", "shape", "weight")
|
||||
n_classes <- if (length(results$shape) == 2) { results$shape[2] } else { 0 }
|
||||
importance <- if (n_classes == 0) {
|
||||
data.table(Feature = results$features, Weight = results$weight)[order(-abs(Weight))]
|
||||
} else {
|
||||
data.table(Feature = rep(feature_names, each = num_class),
|
||||
Weight = weights,
|
||||
Class = seq_len(num_class) - 1)[order(Class, -abs(Weight))]
|
||||
data.table(
|
||||
Feature = rep(results$features, each = n_classes), Weight = results$weight, Class = seq_len(n_classes) - 1
|
||||
)[order(Class, -abs(Weight))]
|
||||
}
|
||||
} else { # tree model
|
||||
result <- xgb.model.dt.tree(feature_names = feature_names,
|
||||
text = model_text_dump,
|
||||
trees = trees)[
|
||||
Feature != "Leaf", .(Gain = sum(Quality),
|
||||
Cover = sum(Cover),
|
||||
Frequency = .N), by = Feature][
|
||||
, `:=`(Gain = Gain / sum(Gain),
|
||||
Cover = Cover / sum(Cover),
|
||||
Frequency = Frequency / sum(Frequency))][
|
||||
order(Gain, decreasing = TRUE)]
|
||||
} else {
|
||||
concatenated <- list()
|
||||
output_names <- vector()
|
||||
for (importance_type in c("weight", "total_gain", "total_cover")) {
|
||||
args <- list(importance_type = importance_type, feature_names = feature_names, tree_idx = trees)
|
||||
results <- .Call(
|
||||
XGBoosterFeatureScore_R, model$handle, jsonlite::toJSON(args, auto_unbox = TRUE, null = "null")
|
||||
)
|
||||
names(results) <- c("features", "shape", importance_type)
|
||||
concatenated[
|
||||
switch(importance_type, "weight" = "Frequency", "total_gain" = "Gain", "total_cover" = "Cover")
|
||||
] <- results[importance_type]
|
||||
output_names <- results$features
|
||||
}
|
||||
importance <- data.table(
|
||||
Feature = output_names,
|
||||
Gain = concatenated$Gain / sum(concatenated$Gain),
|
||||
Cover = concatenated$Cover / sum(concatenated$Cover),
|
||||
Frequency = concatenated$Frequency / sum(concatenated$Frequency)
|
||||
)[order(Gain, decreasing = TRUE)]
|
||||
}
|
||||
result
|
||||
importance
|
||||
}
|
||||
|
||||
# Avoid error messages during CRAN check.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#' @param modelfile the name of the binary input file.
|
||||
#'
|
||||
#' @details
|
||||
#' The input file is expected to contain a model saved in an xgboost-internal binary format
|
||||
#' The input file is expected to contain a model saved in an xgboost model format
|
||||
#' using either \code{\link{xgb.save}} or \code{\link{cb.save.model}} in R, or using some
|
||||
#' appropriate methods from other xgboost interfaces. E.g., a model trained in Python and
|
||||
#' saved from there in xgboost format, could be loaded from R.
|
||||
@@ -38,6 +38,13 @@ xgb.load <- function(modelfile) {
|
||||
handle <- xgb.Booster.handle(modelfile = modelfile)
|
||||
# re-use modelfile if it is raw so we do not need to serialize
|
||||
if (typeof(modelfile) == "raw") {
|
||||
warning(
|
||||
paste(
|
||||
"The support for loading raw booster with `xgb.load` will be ",
|
||||
"discontinued in upcoming release. Use `xgb.load.raw` or",
|
||||
" `xgb.unserialize` instead. "
|
||||
)
|
||||
)
|
||||
bst <- xgb.handleToBooster(handle, modelfile)
|
||||
} else {
|
||||
bst <- xgb.handleToBooster(handle, NULL)
|
||||
|
||||
@@ -3,12 +3,21 @@
|
||||
#' User can generate raw memory buffer by calling xgb.save.raw
|
||||
#'
|
||||
#' @param buffer the buffer returned by xgb.save.raw
|
||||
#' @param as_booster Return the loaded model as xgb.Booster instead of xgb.Booster.handle.
|
||||
#'
|
||||
#' @export
|
||||
xgb.load.raw <- function(buffer) {
|
||||
xgb.load.raw <- function(buffer, as_booster = FALSE) {
|
||||
cachelist <- list()
|
||||
handle <- .Call(XGBoosterCreate_R, cachelist)
|
||||
.Call(XGBoosterLoadModelFromRaw_R, handle, buffer)
|
||||
class(handle) <- "xgb.Booster.handle"
|
||||
return (handle)
|
||||
|
||||
if (as_booster) {
|
||||
booster <- list(handle = handle, raw = NULL)
|
||||
class(booster) <- "xgb.Booster"
|
||||
booster <- xgb.Booster.complete(booster, saveraw = TRUE)
|
||||
return(booster)
|
||||
} else {
|
||||
return (handle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ xgb.model.dt.tree <- function(feature_names = NULL, model = NULL, text = NULL,
|
||||
}
|
||||
|
||||
if (length(text) < 2 ||
|
||||
sum(grepl('yes=(\\d+),no=(\\d+)', text)) < 1) {
|
||||
sum(grepl('leaf=(\\d+)', text)) < 1) {
|
||||
stop("Non-tree model detected! This function can only be used with tree models.")
|
||||
}
|
||||
|
||||
@@ -116,16 +116,28 @@ xgb.model.dt.tree <- function(feature_names = NULL, model = NULL, text = NULL,
|
||||
branch_rx <- paste0("f(\\d+)<(", anynumber_regex, ")\\] yes=(\\d+),no=(\\d+),missing=(\\d+),",
|
||||
"gain=(", anynumber_regex, "),cover=(", anynumber_regex, ")")
|
||||
branch_cols <- c("Feature", "Split", "Yes", "No", "Missing", "Quality", "Cover")
|
||||
td[isLeaf == FALSE,
|
||||
(branch_cols) := {
|
||||
matches <- regmatches(t, regexec(branch_rx, t))
|
||||
# skip some indices with spurious capture groups from anynumber_regex
|
||||
xtr <- do.call(rbind, matches)[, c(2, 3, 5, 6, 7, 8, 10), drop = FALSE]
|
||||
xtr[, 3:5] <- add.tree.id(xtr[, 3:5], Tree)
|
||||
as.data.table(xtr)
|
||||
}]
|
||||
td[
|
||||
isLeaf == FALSE,
|
||||
(branch_cols) := {
|
||||
matches <- regmatches(t, regexec(branch_rx, t))
|
||||
# skip some indices with spurious capture groups from anynumber_regex
|
||||
xtr <- do.call(rbind, matches)[, c(2, 3, 5, 6, 7, 8, 10), drop = FALSE]
|
||||
xtr[, 3:5] <- add.tree.id(xtr[, 3:5], Tree)
|
||||
if (length(xtr) == 0) {
|
||||
as.data.table(
|
||||
list(Feature = "NA", Split = "NA", Yes = "NA", No = "NA", Missing = "NA", Quality = "NA", Cover = "NA")
|
||||
)
|
||||
} else {
|
||||
as.data.table(xtr)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
# assign feature_names when available
|
||||
if (!is.null(feature_names)) {
|
||||
is_stump <- function() {
|
||||
return(length(td$Feature) == 1 && is.na(td$Feature))
|
||||
}
|
||||
if (!is.null(feature_names) && !is_stump()) {
|
||||
if (length(feature_names) <= max(as.numeric(td$Feature), na.rm = TRUE))
|
||||
stop("feature_names has less elements than there are features used in the model")
|
||||
td[isLeaf == FALSE, Feature := feature_names[as.numeric(Feature) + 1]]
|
||||
@@ -134,12 +146,18 @@ xgb.model.dt.tree <- function(feature_names = NULL, model = NULL, text = NULL,
|
||||
# parse leaf lines
|
||||
leaf_rx <- paste0("leaf=(", anynumber_regex, "),cover=(", anynumber_regex, ")")
|
||||
leaf_cols <- c("Feature", "Quality", "Cover")
|
||||
td[isLeaf == TRUE,
|
||||
(leaf_cols) := {
|
||||
matches <- regmatches(t, regexec(leaf_rx, t))
|
||||
xtr <- do.call(rbind, matches)[, c(2, 4)]
|
||||
c("Leaf", as.data.table(xtr))
|
||||
}]
|
||||
td[
|
||||
isLeaf == TRUE,
|
||||
(leaf_cols) := {
|
||||
matches <- regmatches(t, regexec(leaf_rx, t))
|
||||
xtr <- do.call(rbind, matches)[, c(2, 4)]
|
||||
if (length(xtr) == 2) {
|
||||
c("Leaf", as.data.table(xtr[1]), as.data.table(xtr[2]))
|
||||
} else {
|
||||
c("Leaf", as.data.table(xtr))
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
# convert some columns to numeric
|
||||
numeric_cols <- c("Split", "Quality", "Cover")
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
#' @export
|
||||
xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5, plot_width = NULL, plot_height = NULL,
|
||||
render = TRUE, ...){
|
||||
if (!requireNamespace("DiagrammeR", quietly = TRUE)) {
|
||||
stop("DiagrammeR is required for xgb.plot.multi.trees")
|
||||
}
|
||||
check.deprecation(...)
|
||||
tree.matrix <- xgb.model.dt.tree(feature_names = feature_names, model = model)
|
||||
|
||||
@@ -75,8 +78,8 @@ xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5,
|
||||
while (tree.matrix[, sum(is.na(abs.node.position))] > 0) {
|
||||
yes.row.nodes <- tree.matrix[abs.node.position %in% precedent.nodes & !is.na(Yes)]
|
||||
no.row.nodes <- tree.matrix[abs.node.position %in% precedent.nodes & !is.na(No)]
|
||||
yes.nodes.abs.pos <- yes.row.nodes[, abs.node.position] %>% paste0("_0")
|
||||
no.nodes.abs.pos <- no.row.nodes[, abs.node.position] %>% paste0("_1")
|
||||
yes.nodes.abs.pos <- paste0(yes.row.nodes[, abs.node.position], "_0")
|
||||
no.nodes.abs.pos <- paste0(no.row.nodes[, abs.node.position], "_1")
|
||||
|
||||
tree.matrix[ID %in% yes.row.nodes[, Yes], abs.node.position := yes.nodes.abs.pos]
|
||||
tree.matrix[ID %in% no.row.nodes[, No], abs.node.position := no.nodes.abs.pos]
|
||||
@@ -92,19 +95,28 @@ xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5,
|
||||
nodes.dt <- tree.matrix[
|
||||
, .(Quality = sum(Quality))
|
||||
, by = .(abs.node.position, Feature)
|
||||
][, .(Text = paste0(Feature[1:min(length(Feature), features_keep)],
|
||||
" (",
|
||||
format(Quality[1:min(length(Quality), features_keep)], digits = 5),
|
||||
")") %>%
|
||||
paste0(collapse = "\n"))
|
||||
, by = abs.node.position]
|
||||
][, .(Text = paste0(
|
||||
paste0(
|
||||
Feature[1:min(length(Feature), features_keep)],
|
||||
" (",
|
||||
format(Quality[1:min(length(Quality), features_keep)], digits = 5),
|
||||
")"
|
||||
),
|
||||
collapse = "\n"
|
||||
)
|
||||
)
|
||||
, by = abs.node.position
|
||||
]
|
||||
|
||||
edges.dt <- tree.matrix[Feature != "Leaf", .(abs.node.position, Yes)] %>%
|
||||
list(tree.matrix[Feature != "Leaf", .(abs.node.position, No)]) %>%
|
||||
rbindlist() %>%
|
||||
setnames(c("From", "To")) %>%
|
||||
.[, .N, .(From, To)] %>%
|
||||
.[, N := NULL]
|
||||
edges.dt <- data.table::rbindlist(
|
||||
l = list(
|
||||
tree.matrix[Feature != "Leaf", .(abs.node.position, Yes)],
|
||||
tree.matrix[Feature != "Leaf", .(abs.node.position, No)]
|
||||
)
|
||||
)
|
||||
data.table::setnames(edges.dt, c("From", "To"))
|
||||
edges.dt <- edges.dt[, .N, .(From, To)]
|
||||
edges.dt[, N := NULL]
|
||||
|
||||
nodes <- DiagrammeR::create_node_df(
|
||||
n = nrow(nodes.dt),
|
||||
@@ -120,21 +132,25 @@ xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5,
|
||||
nodes_df = nodes,
|
||||
edges_df = edges,
|
||||
attr_theme = NULL
|
||||
) %>%
|
||||
DiagrammeR::add_global_graph_attrs(
|
||||
)
|
||||
graph <- DiagrammeR::add_global_graph_attrs(
|
||||
graph = graph,
|
||||
attr_type = "graph",
|
||||
attr = c("layout", "rankdir"),
|
||||
value = c("dot", "LR")
|
||||
) %>%
|
||||
DiagrammeR::add_global_graph_attrs(
|
||||
)
|
||||
graph <- DiagrammeR::add_global_graph_attrs(
|
||||
graph = graph,
|
||||
attr_type = "node",
|
||||
attr = c("color", "fillcolor", "style", "shape", "fontname"),
|
||||
value = c("DimGray", "beige", "filled", "rectangle", "Helvetica")
|
||||
) %>%
|
||||
DiagrammeR::add_global_graph_attrs(
|
||||
)
|
||||
graph <- DiagrammeR::add_global_graph_attrs(
|
||||
graph = graph,
|
||||
attr_type = "edge",
|
||||
attr = c("color", "arrowsize", "arrowhead", "fontname"),
|
||||
value = c("DimGray", "1.5", "vee", "Helvetica"))
|
||||
value = c("DimGray", "1.5", "vee", "Helvetica")
|
||||
)
|
||||
|
||||
if (!render) return(invisible(graph))
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#' @param col_loess a color to use for the loess curves.
|
||||
#' @param span_loess the \code{span} parameter in \code{\link[stats]{loess}}'s call.
|
||||
#' @param which whether to do univariate or bivariate plotting. NOTE: only 1D is implemented so far.
|
||||
#' @param plot whether a plot should be drawn. If FALSE, only a lits of matrices is returned.
|
||||
#' @param plot whether a plot should be drawn. If FALSE, only a list of matrices is returned.
|
||||
#' @param ... other parameters passed to \code{plot}.
|
||||
#'
|
||||
#' @details
|
||||
@@ -157,7 +157,7 @@ xgb.plot.shap <- function(data, shap_contrib = NULL, features = NULL, top_n = 1,
|
||||
plot(x2plot, y, pch = pch, xlab = f, col = col, xlim = x_lim, ylim = y_lim, ylab = ylab, ...)
|
||||
grid()
|
||||
if (plot_loess) {
|
||||
# compress x to 3 digits, and mean-aggredate y
|
||||
# compress x to 3 digits, and mean-aggregate y
|
||||
zz <- data.table(x = signif(x, 3), y)[, .(.N, y = mean(y)), x]
|
||||
if (nrow(zz) <= 5) {
|
||||
lines(zz$x, zz$y, col = col_loess)
|
||||
|
||||
@@ -98,34 +98,46 @@ xgb.plot.tree <- function(feature_names = NULL, model = NULL, trees = NULL, plot
|
||||
data = dt$Feature,
|
||||
fontcolor = "black")
|
||||
|
||||
edges <- DiagrammeR::create_edge_df(
|
||||
from = match(dt[Feature != "Leaf", c(ID)] %>% rep(2), dt$ID),
|
||||
to = match(dt[Feature != "Leaf", c(Yes, No)], dt$ID),
|
||||
label = dt[Feature != "Leaf", paste("<", Split)] %>%
|
||||
c(rep("", nrow(dt[Feature != "Leaf"]))),
|
||||
style = dt[Feature != "Leaf", ifelse(Missing == Yes, "bold", "solid")] %>%
|
||||
c(dt[Feature != "Leaf", ifelse(Missing == No, "bold", "solid")]),
|
||||
rel = "leading_to")
|
||||
if (nrow(dt[Feature != "Leaf"]) != 0) {
|
||||
edges <- DiagrammeR::create_edge_df(
|
||||
from = match(rep(dt[Feature != "Leaf", c(ID)], 2), dt$ID),
|
||||
to = match(dt[Feature != "Leaf", c(Yes, No)], dt$ID),
|
||||
label = c(
|
||||
dt[Feature != "Leaf", paste("<", Split)],
|
||||
rep("", nrow(dt[Feature != "Leaf"]))
|
||||
),
|
||||
style = c(
|
||||
dt[Feature != "Leaf", ifelse(Missing == Yes, "bold", "solid")],
|
||||
dt[Feature != "Leaf", ifelse(Missing == No, "bold", "solid")]
|
||||
),
|
||||
rel = "leading_to")
|
||||
} else {
|
||||
edges <- NULL
|
||||
}
|
||||
|
||||
graph <- DiagrammeR::create_graph(
|
||||
nodes_df = nodes,
|
||||
edges_df = edges,
|
||||
attr_theme = NULL
|
||||
) %>%
|
||||
DiagrammeR::add_global_graph_attrs(
|
||||
)
|
||||
graph <- DiagrammeR::add_global_graph_attrs(
|
||||
graph = graph,
|
||||
attr_type = "graph",
|
||||
attr = c("layout", "rankdir"),
|
||||
value = c("dot", "LR")
|
||||
) %>%
|
||||
DiagrammeR::add_global_graph_attrs(
|
||||
)
|
||||
graph <- DiagrammeR::add_global_graph_attrs(
|
||||
graph = graph,
|
||||
attr_type = "node",
|
||||
attr = c("color", "style", "fontname"),
|
||||
value = c("DimGray", "filled", "Helvetica")
|
||||
) %>%
|
||||
DiagrammeR::add_global_graph_attrs(
|
||||
)
|
||||
graph <- DiagrammeR::add_global_graph_attrs(
|
||||
graph = graph,
|
||||
attr_type = "edge",
|
||||
attr = c("color", "arrowsize", "arrowhead", "fontname"),
|
||||
value = c("DimGray", "1.5", "vee", "Helvetica"))
|
||||
value = c("DimGray", "1.5", "vee", "Helvetica")
|
||||
)
|
||||
|
||||
if (!render) return(invisible(graph))
|
||||
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
#' Save xgboost model from xgboost or xgb.train
|
||||
#'
|
||||
#' @param model the model object.
|
||||
#' @param raw_format The format for encoding the booster. Available options are
|
||||
#' \itemize{
|
||||
#' \item \code{json}: Encode the booster into JSON text document.
|
||||
#' \item \code{ubj}: Encode the booster into Universal Binary JSON.
|
||||
#' \item \code{deprecated}: Encode the booster into old customized binary format.
|
||||
#' }
|
||||
#'
|
||||
#' Right now the default is \code{deprecated} but will be changed to \code{ubj} in upcoming release.
|
||||
#'
|
||||
#' @examples
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
@@ -17,7 +25,8 @@
|
||||
#' pred <- predict(bst, test$data)
|
||||
#'
|
||||
#' @export
|
||||
xgb.save.raw <- function(model) {
|
||||
xgb.save.raw <- function(model, raw_format = "deprecated") {
|
||||
handle <- xgb.get.handle(model)
|
||||
.Call(XGBoosterModelToRaw_R, handle)
|
||||
args <- list(format = raw_format)
|
||||
.Call(XGBoosterSaveModelToRaw_R, handle, jsonlite::toJSON(args, auto_unbox = TRUE))
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#' \item \code{colsample_bytree} subsample ratio of columns when constructing each tree. Default: 1
|
||||
#' \item \code{lambda} L2 regularization term on weights. Default: 1
|
||||
#' \item \code{alpha} L1 regularization term on weights. (there is no L1 reg on bias because it is not important). Default: 0
|
||||
#' \item \code{num_parallel_tree} Experimental parameter. number of trees to grow per round. Useful to test Random Forest through Xgboost (set \code{colsample_bytree < 1}, \code{subsample < 1} and \code{round = 1}) accordingly. Default: 1
|
||||
#' \item \code{num_parallel_tree} Experimental parameter. number of trees to grow per round. Useful to test Random Forest through XGBoost (set \code{colsample_bytree < 1}, \code{subsample < 1} and \code{round = 1}) accordingly. Default: 1
|
||||
#' \item \code{monotone_constraints} A numerical vector consists of \code{1}, \code{0} and \code{-1} with its length equals to the number of features in the training data. \code{1} is increasing, \code{-1} is decreasing and \code{0} is no constraint.
|
||||
#' \item \code{interaction_constraints} A list of vectors specifying feature indices of permitted interactions. Each item of the list represents one permitted interaction where specified features are allowed to interact with each other. Feature index values should start from \code{0} (\code{0} references the first column). Leave argument unspecified for no interaction constraints.
|
||||
#' }
|
||||
@@ -51,10 +51,10 @@
|
||||
#' \item \code{binary:logistic} logistic regression for binary classification. Output probability.
|
||||
#' \item \code{binary:logitraw} logistic regression for binary classification, output score before logistic transformation.
|
||||
#' \item \code{binary:hinge}: hinge loss for binary classification. This makes predictions of 0 or 1, rather than producing probabilities.
|
||||
#' \item \code{count:poisson}: poisson regression for count data, output mean of poisson distribution. \code{max_delta_step} is set to 0.7 by default in poisson regression (used to safeguard optimization).
|
||||
#' \item \code{count:poisson}: Poisson regression for count data, output mean of Poisson distribution. \code{max_delta_step} is set to 0.7 by default in poisson regression (used to safeguard optimization).
|
||||
#' \item \code{survival:cox}: Cox regression for right censored survival time data (negative values are considered right censored). Note that predictions are returned on the hazard ratio scale (i.e., as HR = exp(marginal_prediction) in the proportional hazard function \code{h(t) = h0(t) * HR)}.
|
||||
#' \item \code{survival:aft}: Accelerated failure time model for censored survival time data. See \href{https://xgboost.readthedocs.io/en/latest/tutorials/aft_survival_analysis.html}{Survival Analysis with Accelerated Failure Time} for details.
|
||||
#' \item \code{aft_loss_distribution}: Probabilty Density Function used by \code{survival:aft} and \code{aft-nloglik} metric.
|
||||
#' \item \code{aft_loss_distribution}: Probability Density Function used by \code{survival:aft} and \code{aft-nloglik} metric.
|
||||
#' \item \code{multi:softmax} set xgboost to do multiclass classification using the softmax objective. Class is represented by a number and should be from 0 to \code{num_class - 1}.
|
||||
#' \item \code{multi:softprob} same as softmax, but prediction outputs a vector of ndata * nclass elements, which can be further reshaped to ndata, nclass matrix. The result contains predicted probabilities of each data point belonging to each class.
|
||||
#' \item \code{rank:pairwise} set xgboost to do ranking task by minimizing the pairwise loss.
|
||||
@@ -126,11 +126,11 @@
|
||||
#' Parallelization is automatically enabled if \code{OpenMP} is present.
|
||||
#' Number of threads can also be manually specified via \code{nthread} parameter.
|
||||
#'
|
||||
#' The evaluation metric is chosen automatically by Xgboost (according to the objective)
|
||||
#' The evaluation metric is chosen automatically by XGBoost (according to the objective)
|
||||
#' when the \code{eval_metric} parameter is not provided.
|
||||
#' User may set one or several \code{eval_metric} parameters.
|
||||
#' Note that when using a customized metric, only this single metric can be used.
|
||||
#' The following is the list of built-in metrics for which Xgboost provides optimized implementation:
|
||||
#' The following is the list of built-in metrics for which XGBoost provides optimized implementation:
|
||||
#' \itemize{
|
||||
#' \item \code{rmse} root mean square error. \url{https://en.wikipedia.org/wiki/Root_mean_square_error}
|
||||
#' \item \code{logloss} negative log-likelihood. \url{https://en.wikipedia.org/wiki/Log-likelihood}
|
||||
@@ -171,9 +171,6 @@
|
||||
#' explicitly passed.
|
||||
#' \item \code{best_iteration} iteration number with the best evaluation metric value
|
||||
#' (only available with early stopping).
|
||||
#' \item \code{best_ntreelimit} the \code{ntreelimit} value corresponding to the best iteration,
|
||||
#' which could further be used in \code{predict} method
|
||||
#' (only available with early stopping).
|
||||
#' \item \code{best_score} the best evaluation metric value during early stopping.
|
||||
#' (only available with early stopping).
|
||||
#' \item \code{feature_names} names of the training dataset features
|
||||
@@ -195,8 +192,8 @@
|
||||
#' data(agaricus.train, package='xgboost')
|
||||
#' data(agaricus.test, package='xgboost')
|
||||
#'
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label))
|
||||
#' dtest <- with(agaricus.test, xgb.DMatrix(data, label = label))
|
||||
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#' dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
#' watchlist <- list(train = dtrain, eval = dtest)
|
||||
#'
|
||||
#' ## A simple xgb.train example:
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
#' Load the instance back from \code{\link{xgb.serialize}}
|
||||
#'
|
||||
#' @param buffer the buffer containing booster instance saved by \code{\link{xgb.serialize}}
|
||||
#' @param handle An \code{xgb.Booster.handle} object which will be overwritten with
|
||||
#' the new deserialized object. Must be a null handle (e.g. when loading the model through
|
||||
#' `readRDS`). If not provided, a new handle will be created.
|
||||
#' @return An \code{xgb.Booster.handle} object.
|
||||
#'
|
||||
#' @export
|
||||
xgb.unserialize <- function(buffer) {
|
||||
xgb.unserialize <- function(buffer, handle = NULL) {
|
||||
cachelist <- list()
|
||||
handle <- .Call(XGBoosterCreate_R, cachelist)
|
||||
if (is.null(handle)) {
|
||||
handle <- .Call(XGBoosterCreate_R, cachelist)
|
||||
} else {
|
||||
if (!is.null.handle(handle))
|
||||
stop("'handle' is not null/empty. Cannot overwrite existing handle.")
|
||||
.Call(XGBoosterCreateInEmptyObj_R, cachelist, handle)
|
||||
}
|
||||
tryCatch(
|
||||
.Call(XGBoosterUnserializeFromBuffer_R, handle, buffer),
|
||||
error = function(e) {
|
||||
|
||||
@@ -9,8 +9,8 @@ xgboost <- function(data = NULL, label = NULL, missing = NA, weight = NULL,
|
||||
early_stopping_rounds = NULL, maximize = NULL,
|
||||
save_period = NULL, save_name = "xgboost.model",
|
||||
xgb_model = NULL, callbacks = list(), ...) {
|
||||
|
||||
dtrain <- xgb.get.DMatrix(data, label, missing, weight)
|
||||
merged <- check.booster.params(params, ...)
|
||||
dtrain <- xgb.get.DMatrix(data, label, missing, weight, nthread = merged$nthread)
|
||||
|
||||
watchlist <- list(train = dtrain)
|
||||
|
||||
@@ -90,7 +90,6 @@ NULL
|
||||
#' @importFrom data.table setkey
|
||||
#' @importFrom data.table setkeyv
|
||||
#' @importFrom data.table setnames
|
||||
#' @importFrom magrittr %>%
|
||||
#' @importFrom jsonlite fromJSON
|
||||
#' @importFrom jsonlite toJSON
|
||||
#' @importFrom utils object.size str tail
|
||||
|
||||
@@ -30,4 +30,4 @@ Examples
|
||||
Development
|
||||
-----------
|
||||
|
||||
* See the [R Package section](https://xgboost.readthedocs.io/en/latest/contribute.html#r-package) of the contributors guide.
|
||||
* See the [R Package section](https://xgboost.readthedocs.io/en/latest/contrib/coding_guide.html#r-coding-guideline) of the contributors guide.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f src/Makevars
|
||||
rm -f CMakeLists.txt
|
||||
|
||||
1841
R-package/configure
vendored
1841
R-package/configure
vendored
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,25 @@
|
||||
|
||||
AC_PREREQ(2.69)
|
||||
|
||||
AC_INIT([xgboost],[0.6-3],[],[xgboost],[])
|
||||
AC_INIT([xgboost],[1.7.4],[],[xgboost],[])
|
||||
|
||||
# Use this line to set CC variable to a C compiler
|
||||
AC_PROG_CC
|
||||
: ${R_HOME=`R RHOME`}
|
||||
if test -z "${R_HOME}"; then
|
||||
echo "could not determine R_HOME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CXX14=`"${R_HOME}/bin/R" CMD config CXX14`
|
||||
CXX14STD=`"${R_HOME}/bin/R" CMD config CXX14STD`
|
||||
CXX="${CXX14} ${CXX14STD}"
|
||||
CXXFLAGS=`"${R_HOME}/bin/R" CMD config CXXFLAGS`
|
||||
|
||||
CC=`"${R_HOME}/bin/R" CMD config CC`
|
||||
CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS`
|
||||
CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS`
|
||||
|
||||
LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS`
|
||||
AC_LANG(C++)
|
||||
|
||||
### Check whether backtrace() is part of libc or the external lib libexecinfo
|
||||
AC_MSG_CHECKING([Backtrace lib])
|
||||
@@ -28,12 +43,19 @@ fi
|
||||
|
||||
if test `uname -s` = "Darwin"
|
||||
then
|
||||
OPENMP_CXXFLAGS='-Xclang -fopenmp'
|
||||
OPENMP_LIB='-lomp'
|
||||
if command -v brew &> /dev/null
|
||||
then
|
||||
HOMEBREW_LIBOMP_PREFIX=`brew --prefix libomp`
|
||||
else
|
||||
# Homebrew not found
|
||||
HOMEBREW_LIBOMP_PREFIX=''
|
||||
fi
|
||||
OPENMP_CXXFLAGS="-Xpreprocessor -fopenmp -I${HOMEBREW_LIBOMP_PREFIX}/include"
|
||||
OPENMP_LIB="-lomp -L${HOMEBREW_LIBOMP_PREFIX}/lib"
|
||||
ac_pkg_openmp=no
|
||||
AC_MSG_CHECKING([whether OpenMP will work in a package])
|
||||
AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include <omp.h>]], [[ return (omp_get_max_threads() <= 1); ]])])
|
||||
${CC} -o conftest conftest.c ${OPENMP_LIB} ${OPENMP_CXXFLAGS} 2>/dev/null && ./conftest && ac_pkg_openmp=yes
|
||||
${CXX} -o conftest conftest.cpp ${CPPFLAGS} ${LDFLAGS} ${OPENMP_LIB} ${OPENMP_CXXFLAGS} 2>/dev/null && ./conftest && ac_pkg_openmp=yes
|
||||
AC_MSG_RESULT([${ac_pkg_openmp}])
|
||||
if test "${ac_pkg_openmp}" = no; then
|
||||
OPENMP_CXXFLAGS=''
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
basic_walkthrough Basic feature walkthrough
|
||||
caret_wrapper Use xgboost to train in caret library
|
||||
custom_objective Cutomize loss function, and evaluation metric
|
||||
custom_objective Customize loss function, and evaluation metric
|
||||
boost_from_prediction Boosting from existing prediction
|
||||
predict_first_ntree Predicting using first n trees
|
||||
generalized_linear_model Generalized Linear Model
|
||||
@@ -8,8 +8,8 @@ cross_validation Cross validation
|
||||
create_sparse_matrix Create Sparse Matrix
|
||||
predict_leaf_indices Predicting the corresponding leaves
|
||||
early_stopping Early Stop in training
|
||||
poisson_regression Poisson Regression on count data
|
||||
tweedie_regression Tweddie Regression
|
||||
poisson_regression Poisson regression on count data
|
||||
tweedie_regression Tweedie regression
|
||||
gpu_accelerated GPU-accelerated tree building algorithms
|
||||
interaction_constraints Interaction constraints among features
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ XGBoost R Feature Walkthrough
|
||||
====
|
||||
* [Basic walkthrough of wrappers](basic_walkthrough.R)
|
||||
* [Train a xgboost model from caret library](caret_wrapper.R)
|
||||
* [Cutomize loss function, and evaluation metric](custom_objective.R)
|
||||
* [Customize loss function, and evaluation metric](custom_objective.R)
|
||||
* [Boosting from existing prediction](boost_from_prediction.R)
|
||||
* [Predicting using first n trees](predict_first_ntree.R)
|
||||
* [Generalized Linear Model](generalized_linear_model.R)
|
||||
|
||||
@@ -40,7 +40,7 @@ print("Train xgboost with verbose 2, also print information about tree")
|
||||
bst <- xgboost(data = dtrain, max_depth = 2, eta = 1, nrounds = 2,
|
||||
nthread = 2, objective = "binary:logistic", verbose = 2)
|
||||
|
||||
# you can also specify data as file path to a LibSVM format input
|
||||
# you can also specify data as file path to a LIBSVM format input
|
||||
# since we do not have this file with us, the following line is just for illustration
|
||||
# bst <- xgboost(data = 'agaricus.train.svm', max_depth = 2, eta = 1, nrounds = 2,objective = "binary:logistic")
|
||||
|
||||
@@ -63,7 +63,7 @@ print(paste("sum(abs(pred2-pred))=", sum(abs(pred2 - pred))))
|
||||
# save model to R's raw vector
|
||||
raw <- xgb.save.raw(bst)
|
||||
# load binary model to R
|
||||
bst3 <- xgb.load(raw)
|
||||
bst3 <- xgb.load.raw(raw)
|
||||
pred3 <- predict(bst3, test$data)
|
||||
# pred3 should be identical to pred
|
||||
print(paste("sum(abs(pred3-pred))=", sum(abs(pred3 - pred))))
|
||||
|
||||
@@ -2,17 +2,17 @@ require(xgboost)
|
||||
require(Matrix)
|
||||
require(data.table)
|
||||
if (!require(vcd)) {
|
||||
install.packages('vcd') #Available in Cran. Used for its dataset with categorical values.
|
||||
install.packages('vcd') #Available in CRAN. Used for its dataset with categorical values.
|
||||
require(vcd)
|
||||
}
|
||||
# According to its documentation, Xgboost works only on numbers.
|
||||
# According to its documentation, XGBoost works only on numbers.
|
||||
# Sometimes the dataset we have to work on have categorical data.
|
||||
# A categorical variable is one which have a fixed number of values. By example, if for each observation a variable called "Colour" can have only "red", "blue" or "green" as value, it is a categorical variable.
|
||||
#
|
||||
# In R, categorical variable is called Factor.
|
||||
# Type ?factor in console for more information.
|
||||
#
|
||||
# In this demo we will see how to transform a dense dataframe with categorical variables to a sparse matrix before analyzing it in Xgboost.
|
||||
# In this demo we will see how to transform a dense dataframe with categorical variables to a sparse matrix before analyzing it in XGBoost.
|
||||
# The method we are going to see is usually called "one hot encoding".
|
||||
|
||||
#load Arthritis dataset in memory.
|
||||
@@ -25,13 +25,13 @@ df <- data.table(Arthritis, keep.rownames = FALSE)
|
||||
cat("Print the dataset\n")
|
||||
print(df)
|
||||
|
||||
# 2 columns have factor type, one has ordinal type (ordinal variable is a categorical variable with values wich can be ordered, here: None > Some > Marked).
|
||||
# 2 columns have factor type, one has ordinal type (ordinal variable is a categorical variable with values which can be ordered, here: None > Some > Marked).
|
||||
cat("Structure of the dataset\n")
|
||||
str(df)
|
||||
|
||||
# Let's add some new categorical features to see if it helps. Of course these feature are highly correlated to the Age feature. Usually it's not a good thing in ML, but Tree algorithms (including boosted trees) are able to select the best features, even in case of highly correlated features.
|
||||
|
||||
# For the first feature we create groups of age by rounding the real age. Note that we transform it to factor (categorical data) so the algorithm treat them as independant values.
|
||||
# For the first feature we create groups of age by rounding the real age. Note that we transform it to factor (categorical data) so the algorithm treat them as independent values.
|
||||
df[, AgeDiscret := as.factor(round(Age / 10, 0))]
|
||||
|
||||
# Here is an even stronger simplification of the real age with an arbitrary split at 30 years old. I choose this value based on nothing. We will see later if simplifying the information based on arbitrary values is a good strategy (I am sure you already have an idea of how well it will work!).
|
||||
|
||||
@@ -22,10 +22,10 @@ xgb.cv(param, dtrain, nrounds, nfold = 5,
|
||||
metrics = 'error', showsd = FALSE)
|
||||
|
||||
###
|
||||
# you can also do cross validation with cutomized loss function
|
||||
# you can also do cross validation with customized loss function
|
||||
# See custom_objective.R
|
||||
##
|
||||
print ('running cross validation, with cutomsized loss function')
|
||||
print ('running cross validation, with customized loss function')
|
||||
|
||||
logregobj <- function(preds, dtrain) {
|
||||
labels <- getinfo(dtrain, "label")
|
||||
|
||||
@@ -12,7 +12,7 @@ watchlist <- list(eval = dtest, train = dtrain)
|
||||
num_round <- 2
|
||||
|
||||
# user define objective function, given prediction, return gradient and second order gradient
|
||||
# this is loglikelihood loss
|
||||
# this is log likelihood loss
|
||||
logregobj <- function(preds, dtrain) {
|
||||
labels <- getinfo(dtrain, "label")
|
||||
preds <- 1 / (1 + exp(-preds))
|
||||
@@ -23,9 +23,9 @@ logregobj <- function(preds, dtrain) {
|
||||
|
||||
# user defined evaluation function, return a pair metric_name, result
|
||||
# NOTE: when you do customized loss function, the default prediction value is margin
|
||||
# this may make buildin evalution metric not function properly
|
||||
# this may make builtin evaluation metric not function properly
|
||||
# for example, we are doing logistic loss, the prediction is score before logistic transformation
|
||||
# the buildin evaluation error assumes input is after logistic transformation
|
||||
# the builtin evaluation error assumes input is after logistic transformation
|
||||
# Take this in mind when you use the customization, and maybe you need write customized evaluation function
|
||||
evalerror <- function(preds, dtrain) {
|
||||
labels <- getinfo(dtrain, "label")
|
||||
|
||||
@@ -11,7 +11,7 @@ param <- list(max_depth = 2, eta = 1, nthread = 2, verbosity = 0)
|
||||
watchlist <- list(eval = dtest)
|
||||
num_round <- 20
|
||||
# user define objective function, given prediction, return gradient and second order gradient
|
||||
# this is loglikelihood loss
|
||||
# this is log likelihood loss
|
||||
logregobj <- function(preds, dtrain) {
|
||||
labels <- getinfo(dtrain, "label")
|
||||
preds <- 1 / (1 + exp(-preds))
|
||||
@@ -21,9 +21,9 @@ logregobj <- function(preds, dtrain) {
|
||||
}
|
||||
# user defined evaluation function, return a pair metric_name, result
|
||||
# NOTE: when you do customized loss function, the default prediction value is margin
|
||||
# this may make buildin evalution metric not function properly
|
||||
# this may make builtin evaluation metric not function properly
|
||||
# for example, we are doing logistic loss, the prediction is score before logistic transformation
|
||||
# the buildin evaluation error assumes input is after logistic transformation
|
||||
# the builtin evaluation error assumes input is after logistic transformation
|
||||
# Take this in mind when you use the customization, and maybe you need write customized evaluation function
|
||||
evalerror <- function(preds, dtrain) {
|
||||
labels <- getinfo(dtrain, "label")
|
||||
|
||||
@@ -38,10 +38,7 @@ The following additional fields are assigned to the model's R object:
|
||||
\itemize{
|
||||
\item \code{best_score} the evaluation score at the best iteration
|
||||
\item \code{best_iteration} at which boosting iteration the best score has occurred (1-based index)
|
||||
\item \code{best_ntreelimit} to use with the \code{ntreelimit} parameter in \code{predict}.
|
||||
It differs from \code{best_iteration} in multiclass or random forest settings.
|
||||
}
|
||||
|
||||
The Same values are also stored as xgb-attributes:
|
||||
\itemize{
|
||||
\item \code{best_iteration} is stored as a 0-based iteration index (for interoperability of binary models)
|
||||
|
||||
@@ -8,16 +8,18 @@ during its training.}
|
||||
cb.gblinear.history(sparse = FALSE)
|
||||
}
|
||||
\arguments{
|
||||
\item{sparse}{when set to FALSE/TURE, a dense/sparse matrix is used to store the result.
|
||||
\item{sparse}{when set to FALSE/TRUE, a dense/sparse matrix is used to store the result.
|
||||
Sparse format is useful when one expects only a subset of coefficients to be non-zero,
|
||||
when using the "thrifty" feature selector with fairly small number of top features
|
||||
selected per iteration.}
|
||||
}
|
||||
\value{
|
||||
Results are stored in the \code{coefs} element of the closure.
|
||||
The \code{\link{xgb.gblinear.history}} convenience function provides an easy way to access it.
|
||||
The \code{\link{xgb.gblinear.history}} convenience function provides an easy
|
||||
way to access it.
|
||||
With \code{xgb.train}, it is either a dense of a sparse matrix.
|
||||
While with \code{xgb.cv}, it is a list (an element per each fold) of such matrices.
|
||||
While with \code{xgb.cv}, it is a list (an element per each fold) of such
|
||||
matrices.
|
||||
}
|
||||
\description{
|
||||
Callback closure for collecting the model coefficients history of a gblinear booster
|
||||
@@ -36,10 +38,9 @@ Callback function expects the following values to be set in its calling frame:
|
||||
#
|
||||
# In the iris dataset, it is hard to linearly separate Versicolor class from the rest
|
||||
# without considering the 2nd order interactions:
|
||||
require(magrittr)
|
||||
x <- model.matrix(Species ~ .^2, iris)[,-1]
|
||||
colnames(x)
|
||||
dtrain <- xgb.DMatrix(scale(x), label = 1*(iris$Species == "versicolor"))
|
||||
dtrain <- xgb.DMatrix(scale(x), label = 1*(iris$Species == "versicolor"), nthread = 2)
|
||||
param <- list(booster = "gblinear", objective = "reg:logistic", eval_metric = "auc",
|
||||
lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||
# For 'shotgun', which is a default linear updater, using high eta values may result in
|
||||
@@ -57,21 +58,21 @@ matplot(coef_path, type = 'l')
|
||||
bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 200, eta = 0.8,
|
||||
updater = 'coord_descent', feature_selector = 'thrifty', top_k = 1,
|
||||
callbacks = list(cb.gblinear.history()))
|
||||
xgb.gblinear.history(bst) \%>\% matplot(type = 'l')
|
||||
matplot(xgb.gblinear.history(bst), type = 'l')
|
||||
# Componentwise boosting is known to have similar effect to Lasso regularization.
|
||||
# Try experimenting with various values of top_k, eta, nrounds,
|
||||
# as well as different feature_selectors.
|
||||
|
||||
# For xgb.cv:
|
||||
bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 100, eta = 0.8,
|
||||
callbacks = list(cb.gblinear.history()))
|
||||
callbacks = list(cb.gblinear.history()))
|
||||
# coefficients in the CV fold #3
|
||||
xgb.gblinear.history(bst)[[3]] \%>\% matplot(type = 'l')
|
||||
matplot(xgb.gblinear.history(bst)[[3]], type = 'l')
|
||||
|
||||
|
||||
#### Multiclass classification:
|
||||
#
|
||||
dtrain <- xgb.DMatrix(scale(x), label = as.numeric(iris$Species) - 1)
|
||||
dtrain <- xgb.DMatrix(scale(x), label = as.numeric(iris$Species) - 1, nthread = 2)
|
||||
param <- list(booster = "gblinear", objective = "multi:softprob", num_class = 3,
|
||||
lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||
# For the default linear updater 'shotgun' it sometimes is helpful
|
||||
@@ -79,15 +80,15 @@ param <- list(booster = "gblinear", objective = "multi:softprob", num_class = 3,
|
||||
bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 70, eta = 0.5,
|
||||
callbacks = list(cb.gblinear.history()))
|
||||
# Will plot the coefficient paths separately for each class:
|
||||
xgb.gblinear.history(bst, class_index = 0) \%>\% matplot(type = 'l')
|
||||
xgb.gblinear.history(bst, class_index = 1) \%>\% matplot(type = 'l')
|
||||
xgb.gblinear.history(bst, class_index = 2) \%>\% matplot(type = 'l')
|
||||
matplot(xgb.gblinear.history(bst, class_index = 0), type = 'l')
|
||||
matplot(xgb.gblinear.history(bst, class_index = 1), type = 'l')
|
||||
matplot(xgb.gblinear.history(bst, class_index = 2), type = 'l')
|
||||
|
||||
# CV:
|
||||
bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 70, eta = 0.5,
|
||||
callbacks = list(cb.gblinear.history(FALSE)))
|
||||
# 1st forld of 1st class
|
||||
xgb.gblinear.history(bst, class_index = 0)[[1]] \%>\% matplot(type = 'l')
|
||||
# 1st fold of 1st class
|
||||
matplot(xgb.gblinear.history(bst, class_index = 0)[[1]], type = 'l')
|
||||
|
||||
}
|
||||
\seealso{
|
||||
|
||||
@@ -19,7 +19,7 @@ be directly used with an \code{xgb.DMatrix} object.
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label, nthread = 2)
|
||||
|
||||
stopifnot(nrow(dtrain) == nrow(train$data))
|
||||
stopifnot(ncol(dtrain) == ncol(train$data))
|
||||
|
||||
@@ -26,7 +26,7 @@ Since row names are irrelevant, it is recommended to use \code{colnames} directl
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label, nthread = 2)
|
||||
dimnames(dtrain)
|
||||
colnames(dtrain)
|
||||
colnames(dtrain) <- make.names(1:ncol(train$data))
|
||||
|
||||
@@ -23,9 +23,9 @@ Get information of an xgb.DMatrix object
|
||||
The \code{name} field can be one of the following:
|
||||
|
||||
\itemize{
|
||||
\item \code{label}: label Xgboost learn from ;
|
||||
\item \code{label}: label XGBoost learn from ;
|
||||
\item \code{weight}: to do a weight rescale ;
|
||||
\item \code{base_margin}: base margin is the base prediction Xgboost will boost from ;
|
||||
\item \code{base_margin}: base margin is the base prediction XGBoost will boost from ;
|
||||
\item \code{nrow}: number of rows of the \code{xgb.DMatrix}.
|
||||
|
||||
}
|
||||
@@ -34,8 +34,7 @@ The \code{name} field can be one of the following:
|
||||
}
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
|
||||
labels <- getinfo(dtrain, 'label')
|
||||
setinfo(dtrain, 'label', 1-labels)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
predinteraction = FALSE,
|
||||
reshape = FALSE,
|
||||
training = FALSE,
|
||||
iterationrange = NULL,
|
||||
strict_shape = FALSE,
|
||||
...
|
||||
)
|
||||
|
||||
@@ -25,7 +27,11 @@
|
||||
\arguments{
|
||||
\item{object}{Object of class \code{xgb.Booster} or \code{xgb.Booster.handle}}
|
||||
|
||||
\item{newdata}{takes \code{matrix}, \code{dgCMatrix}, local data file or \code{xgb.DMatrix}.}
|
||||
\item{newdata}{takes \code{matrix}, \code{dgCMatrix}, \code{dgRMatrix}, \code{dsparseVector},
|
||||
local data file or \code{xgb.DMatrix}.
|
||||
|
||||
For single-row predictions on sparse data, it's recommended to use CSR format. If passing
|
||||
a sparse vector, it will take it as a row vector.}
|
||||
|
||||
\item{missing}{Missing is only used when input is dense matrix. Pick a float value that represents
|
||||
missing values in data (e.g., sometimes 0 or some other extreme value is used).}
|
||||
@@ -34,8 +40,7 @@ missing values in data (e.g., sometimes 0 or some other extreme value is used).}
|
||||
sum of predictions from boosting iterations' results. E.g., setting \code{outputmargin=TRUE} for
|
||||
logistic regression would result in predictions for log-odds instead of probabilities.}
|
||||
|
||||
\item{ntreelimit}{limit the number of model's trees or boosting iterations used in prediction (see Details).
|
||||
It will use all the trees by default (\code{NULL} value).}
|
||||
\item{ntreelimit}{Deprecated, use \code{iterationrange} instead.}
|
||||
|
||||
\item{predleaf}{whether predict leaf index.}
|
||||
|
||||
@@ -52,10 +57,20 @@ or predinteraction flags is TRUE.}
|
||||
\item{training}{whether is the prediction result used for training. For dart booster,
|
||||
training predicting will perform dropout.}
|
||||
|
||||
\item{iterationrange}{Specifies which layer of trees are used in prediction. For
|
||||
example, if a random forest is trained with 100 rounds. Specifying
|
||||
`iterationrange=(1, 21)`, then only the forests built during [1, 21) (half open set)
|
||||
rounds are used in this prediction. It's 1-based index just like R vector. When set
|
||||
to \code{c(1, 1)} XGBoost will use all trees.}
|
||||
|
||||
\item{strict_shape}{Default is \code{FALSE}. When it's set to \code{TRUE}, output
|
||||
type and shape of prediction are invariant to model type.}
|
||||
|
||||
\item{...}{Parameters passed to \code{predict.xgb.Booster}}
|
||||
}
|
||||
\value{
|
||||
For regression or binary classification, it returns a vector of length \code{nrows(newdata)}.
|
||||
The return type is different depending whether \code{strict_shape} is set to \code{TRUE}. By default,
|
||||
for regression or binary classification, it returns a vector of length \code{nrows(newdata)}.
|
||||
For multiclass classification, either a \code{num_class * nrows(newdata)} vector or
|
||||
a \code{(nrows(newdata), num_class)} dimension matrix is returned, depending on
|
||||
the \code{reshape} value.
|
||||
@@ -76,18 +91,19 @@ two dimensions. The "+ 1" columns corresponds to bias. Summing this array along
|
||||
produce practically the same result as predict with \code{predcontrib = TRUE}.
|
||||
For a multiclass case, a list of \code{num_class} elements is returned, where each element is
|
||||
such an array.
|
||||
|
||||
When \code{strict_shape} is set to \code{TRUE}, the output is always an array. For
|
||||
normal prediction, the output is a 2-dimension array \code{(num_class, nrow(newdata))}.
|
||||
|
||||
For \code{predcontrib = TRUE}, output is \code{(ncol(newdata) + 1, num_class, nrow(newdata))}
|
||||
For \code{predinteraction = TRUE}, output is \code{(ncol(newdata) + 1, ncol(newdata) + 1, num_class, nrow(newdata))}
|
||||
For \code{predleaf = TRUE}, output is \code{(n_trees_in_forest, num_class, n_iterations, nrow(newdata))}
|
||||
}
|
||||
\description{
|
||||
Predicted values based on either xgboost model or model handle object.
|
||||
}
|
||||
\details{
|
||||
Note that \code{ntreelimit} is not necessarily equal to the number of boosting iterations
|
||||
and it is not necessarily equal to the number of trees in a model.
|
||||
E.g., in a random forest-like model, \code{ntreelimit} would limit the number of trees.
|
||||
But for multiclass classification, while there are multiple trees per iteration,
|
||||
\code{ntreelimit} limits the number of boosting iterations.
|
||||
|
||||
Also note that \code{ntreelimit} would currently do nothing for predictions from gblinear,
|
||||
Note that \code{iterationrange} would currently do nothing for predictions from gblinear,
|
||||
since gblinear doesn't keep its boosting history.
|
||||
|
||||
One possible practical applications of the \code{predleaf} option is to use the model
|
||||
@@ -120,7 +136,7 @@ bst <- xgboost(data = train$data, label = train$label, max_depth = 2,
|
||||
# use all trees by default
|
||||
pred <- predict(bst, test$data)
|
||||
# use only the 1st tree
|
||||
pred1 <- predict(bst, test$data, ntreelimit = 1)
|
||||
pred1 <- predict(bst, test$data, iterationrange = c(1, 2))
|
||||
|
||||
# Predicting tree leafs:
|
||||
# the result is an nsamples X ntrees matrix
|
||||
@@ -172,25 +188,9 @@ str(pred)
|
||||
all.equal(pred, pred_labels)
|
||||
# prediction from using only 5 iterations should result
|
||||
# in the same error as seen in iteration 5:
|
||||
pred5 <- predict(bst, as.matrix(iris[, -5]), ntreelimit=5)
|
||||
pred5 <- predict(bst, as.matrix(iris[, -5]), iterationrange=c(1, 6))
|
||||
sum(pred5 != lb)/length(lb)
|
||||
|
||||
|
||||
## random forest-like model of 25 trees for binary classification:
|
||||
|
||||
set.seed(11)
|
||||
bst <- xgboost(data = train$data, label = train$label, max_depth = 5,
|
||||
nthread = 2, nrounds = 1, objective = "binary:logistic",
|
||||
num_parallel_tree = 25, subsample = 0.6, colsample_bytree = 0.1)
|
||||
# Inspect the prediction error vs number of trees:
|
||||
lb <- test$label
|
||||
dtest <- xgb.DMatrix(test$data, label=lb)
|
||||
err <- sapply(1:25, function(n) {
|
||||
pred <- predict(bst, dtest, ntreelimit=n)
|
||||
sum((pred > 0.5) != lb)/length(lb)
|
||||
})
|
||||
plot(err, type='l', ylim=c(0,0.1), xlab='#trees')
|
||||
|
||||
}
|
||||
\references{
|
||||
Scott M. Lundberg, Su-In Lee, "A Unified Approach to Interpreting Model Predictions", NIPS Proceedings 2017, \url{https://arxiv.org/abs/1705.07874}
|
||||
|
||||
@@ -19,8 +19,7 @@ Currently it displays dimensions and presence of info-fields and colnames.
|
||||
}
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
|
||||
dtrain
|
||||
print(dtrain, verbose=TRUE)
|
||||
|
||||
@@ -25,16 +25,15 @@ Set information of an xgb.DMatrix object
|
||||
The \code{name} field can be one of the following:
|
||||
|
||||
\itemize{
|
||||
\item \code{label}: label Xgboost learn from ;
|
||||
\item \code{label}: label XGBoost learn from ;
|
||||
\item \code{weight}: to do a weight rescale ;
|
||||
\item \code{base_margin}: base margin is the base prediction Xgboost will boost from ;
|
||||
\item \code{base_margin}: base margin is the base prediction XGBoost will boost from ;
|
||||
\item \code{group}: number of rows in each group (to use with \code{rank:pairwise} objective).
|
||||
}
|
||||
}
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
|
||||
labels <- getinfo(dtrain, 'label')
|
||||
setinfo(dtrain, 'label', 1-labels)
|
||||
|
||||
@@ -28,8 +28,7 @@ original xgb.DMatrix object
|
||||
}
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
|
||||
dsub <- slice(dtrain, 1:42)
|
||||
labels1 <- getinfo(dsub, 'label')
|
||||
|
||||
@@ -4,11 +4,20 @@
|
||||
\alias{xgb.DMatrix}
|
||||
\title{Construct xgb.DMatrix object}
|
||||
\usage{
|
||||
xgb.DMatrix(data, info = list(), missing = NA, silent = FALSE, ...)
|
||||
xgb.DMatrix(
|
||||
data,
|
||||
info = list(),
|
||||
missing = NA,
|
||||
silent = FALSE,
|
||||
nthread = NULL,
|
||||
...
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
\item{data}{a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object, or a character
|
||||
string representing a filename.}
|
||||
\item{data}{a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object,
|
||||
a \code{dgRMatrix} object (only when making predictions from a fitted model),
|
||||
a \code{dsparseVector} object (only when making predictions from a fitted model, will be
|
||||
interpreted as a row vector), or a character string representing a filename.}
|
||||
|
||||
\item{info}{a named list of additional information to store in the \code{xgb.DMatrix} object.
|
||||
See \code{\link{setinfo}} for the specific allowed kinds of}
|
||||
@@ -18,17 +27,18 @@ It is useful when a 0 or some other extreme value represents missing values in d
|
||||
|
||||
\item{silent}{whether to suppress printing an informational message after loading from a file.}
|
||||
|
||||
\item{nthread}{Number of threads used for creating DMatrix.}
|
||||
|
||||
\item{...}{the \code{info} data could be passed directly as parameters, without creating an \code{info} list.}
|
||||
}
|
||||
\description{
|
||||
Construct xgb.DMatrix object from either a dense matrix, a sparse matrix, or a local file.
|
||||
Supported input file formats are either a libsvm text file or a binary file that was created previously by
|
||||
Supported input file formats are either a LIBSVM text file or a binary file that was created previously by
|
||||
\code{\link{xgb.DMatrix.save}}).
|
||||
}
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||
dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||
if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
||||
|
||||
@@ -16,8 +16,7 @@ Save xgb.DMatrix object to binary file
|
||||
}
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
train <- agaricus.train
|
||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||
dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||
if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
||||
|
||||
@@ -29,7 +29,7 @@ Joaquin Quinonero Candela)}
|
||||
|
||||
International Workshop on Data Mining for Online Advertising (ADKDD) - August 24, 2014
|
||||
|
||||
\url{https://research.fb.com/publications/practical-lessons-from-predicting-clicks-on-ads-at-facebook/}.
|
||||
\url{https://research.facebook.com/publications/practical-lessons-from-predicting-clicks-on-ads-at-facebook/}.
|
||||
|
||||
Extract explaining the method:
|
||||
|
||||
@@ -59,8 +59,8 @@ a rule on certain features."
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
data(agaricus.test, package='xgboost')
|
||||
dtrain <- xgb.DMatrix(data = agaricus.train$data, label = agaricus.train$label)
|
||||
dtest <- xgb.DMatrix(data = agaricus.test$data, label = agaricus.test$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
|
||||
param <- list(max_depth=2, eta=1, silent=1, objective='binary:logistic')
|
||||
nrounds = 4
|
||||
@@ -76,8 +76,12 @@ new.features.train <- xgb.create.features(model = bst, agaricus.train$data)
|
||||
new.features.test <- xgb.create.features(model = bst, agaricus.test$data)
|
||||
|
||||
# learning with new features
|
||||
new.dtrain <- xgb.DMatrix(data = new.features.train, label = agaricus.train$label)
|
||||
new.dtest <- xgb.DMatrix(data = new.features.test, label = agaricus.test$label)
|
||||
new.dtrain <- xgb.DMatrix(
|
||||
data = new.features.train, label = agaricus.train$label, nthread = 2
|
||||
)
|
||||
new.dtest <- xgb.DMatrix(
|
||||
data = new.features.test, label = agaricus.test$label, nthread = 2
|
||||
)
|
||||
watchlist <- list(train = new.dtrain)
|
||||
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
||||
|
||||
|
||||
@@ -135,9 +135,7 @@ An object of class \code{xgb.cv.synchronous} with the following elements:
|
||||
parameter or randomly generated.
|
||||
\item \code{best_iteration} iteration number with the best evaluation metric value
|
||||
(only available with early stopping).
|
||||
\item \code{best_ntreelimit} the \code{ntreelimit} value corresponding to the best iteration,
|
||||
which could further be used in \code{predict} method
|
||||
(only available with early stopping).
|
||||
\item \code{best_ntreelimit} and the \code{ntreelimit} Deprecated attributes, use \code{best_iteration} instead.
|
||||
\item \code{pred} CV prediction values available when \code{prediction} is set.
|
||||
It is either vector or matrix (see \code{\link{cb.cv.predict}}).
|
||||
\item \code{models} a list of the CV folds' models. It is only available with the explicit
|
||||
@@ -160,9 +158,9 @@ Adapted from \url{https://en.wikipedia.org/wiki/Cross-validation_\%28statistics\
|
||||
}
|
||||
\examples{
|
||||
data(agaricus.train, package='xgboost')
|
||||
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
cv <- xgb.cv(data = dtrain, nrounds = 3, nthread = 2, nfold = 5, metrics = list("rmse","auc"),
|
||||
max_depth = 3, eta = 1, objective = "binary:logistic")
|
||||
max_depth = 3, eta = 1, objective = "binary:logistic")
|
||||
print(cv)
|
||||
print(cv, verbose=TRUE)
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ xgb.dump(
|
||||
If not provided or set to \code{NULL}, the model is returned as a \code{character} vector.}
|
||||
|
||||
\item{fmap}{feature map file representing feature types.
|
||||
Detailed description could be found at
|
||||
\url{https://github.com/dmlc/xgboost/wiki/Binary-Classification#dump-model}.
|
||||
See demo/ for walkthrough example in R, and
|
||||
\url{https://github.com/dmlc/xgboost/blob/master/demo/data/featmap.txt}
|
||||
for example Format.}
|
||||
|
||||
@@ -16,7 +16,7 @@ An object of \code{xgb.Booster} class.
|
||||
Load xgboost model from the binary model file.
|
||||
}
|
||||
\details{
|
||||
The input file is expected to contain a model saved in an xgboost-internal binary format
|
||||
The input file is expected to contain a model saved in an xgboost model format
|
||||
using either \code{\link{xgb.save}} or \code{\link{cb.save.model}} in R, or using some
|
||||
appropriate methods from other xgboost interfaces. E.g., a model trained in Python and
|
||||
saved from there in xgboost format, could be loaded from R.
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
\alias{xgb.load.raw}
|
||||
\title{Load serialised xgboost model from R's raw vector}
|
||||
\usage{
|
||||
xgb.load.raw(buffer)
|
||||
xgb.load.raw(buffer, as_booster = FALSE)
|
||||
}
|
||||
\arguments{
|
||||
\item{buffer}{the buffer returned by xgb.save.raw}
|
||||
|
||||
\item{as_booster}{Return the loaded model as xgb.Booster instead of xgb.Booster.handle.}
|
||||
}
|
||||
\description{
|
||||
User can generate raw memory buffer by calling xgb.save.raw
|
||||
|
||||
@@ -87,7 +87,7 @@ more than 5 distinct values.}
|
||||
|
||||
\item{which}{whether to do univariate or bivariate plotting. NOTE: only 1D is implemented so far.}
|
||||
|
||||
\item{plot}{whether a plot should be drawn. If FALSE, only a lits of matrices is returned.}
|
||||
\item{plot}{whether a plot should be drawn. If FALSE, only a list of matrices is returned.}
|
||||
|
||||
\item{...}{other parameters passed to \code{plot}.}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,19 @@
|
||||
\title{Save xgboost model to R's raw vector,
|
||||
user can call xgb.load.raw to load the model back from raw vector}
|
||||
\usage{
|
||||
xgb.save.raw(model)
|
||||
xgb.save.raw(model, raw_format = "deprecated")
|
||||
}
|
||||
\arguments{
|
||||
\item{model}{the model object.}
|
||||
|
||||
\item{raw_format}{The format for encoding the booster. Available options are
|
||||
\itemize{
|
||||
\item \code{json}: Encode the booster into JSON text document.
|
||||
\item \code{ubj}: Encode the booster into Universal Binary JSON.
|
||||
\item \code{deprecated}: Encode the booster into old customized binary format.
|
||||
}
|
||||
|
||||
Right now the default is \code{deprecated} but will be changed to \code{ubj} in upcoming release.}
|
||||
}
|
||||
\description{
|
||||
Save xgboost model from xgboost or xgb.train
|
||||
|
||||
@@ -54,7 +54,7 @@ xgboost(
|
||||
|
||||
2. Booster Parameters
|
||||
|
||||
2.1. Parameter for Tree Booster
|
||||
2.1. Parameters for Tree Booster
|
||||
|
||||
\itemize{
|
||||
\item \code{eta} control the learning rate: scale the contribution of each tree by a factor of \code{0 < eta < 1} when it is added to the current approximation. Used to prevent overfitting by making the boosting process more conservative. Lower value for \code{eta} implies larger value for \code{nrounds}: low \code{eta} value means model more robust to overfitting but slower to compute. Default: 0.3
|
||||
@@ -63,12 +63,14 @@ xgboost(
|
||||
\item \code{min_child_weight} minimum sum of instance weight (hessian) needed in a child. If the tree partition step results in a leaf node with the sum of instance weight less than min_child_weight, then the building process will give up further partitioning. In linear regression mode, this simply corresponds to minimum number of instances needed to be in each node. The larger, the more conservative the algorithm will be. Default: 1
|
||||
\item \code{subsample} subsample ratio of the training instance. Setting it to 0.5 means that xgboost randomly collected half of the data instances to grow trees and this will prevent overfitting. It makes computation shorter (because less data to analyse). It is advised to use this parameter with \code{eta} and increase \code{nrounds}. Default: 1
|
||||
\item \code{colsample_bytree} subsample ratio of columns when constructing each tree. Default: 1
|
||||
\item \code{num_parallel_tree} Experimental parameter. number of trees to grow per round. Useful to test Random Forest through Xgboost (set \code{colsample_bytree < 1}, \code{subsample < 1} and \code{round = 1}) accordingly. Default: 1
|
||||
\item \code{lambda} L2 regularization term on weights. Default: 1
|
||||
\item \code{alpha} L1 regularization term on weights. (there is no L1 reg on bias because it is not important). Default: 0
|
||||
\item \code{num_parallel_tree} Experimental parameter. number of trees to grow per round. Useful to test Random Forest through XGBoost (set \code{colsample_bytree < 1}, \code{subsample < 1} and \code{round = 1}) accordingly. Default: 1
|
||||
\item \code{monotone_constraints} A numerical vector consists of \code{1}, \code{0} and \code{-1} with its length equals to the number of features in the training data. \code{1} is increasing, \code{-1} is decreasing and \code{0} is no constraint.
|
||||
\item \code{interaction_constraints} A list of vectors specifying feature indices of permitted interactions. Each item of the list represents one permitted interaction where specified features are allowed to interact with each other. Feature index values should start from \code{0} (\code{0} references the first column). Leave argument unspecified for no interaction constraints.
|
||||
}
|
||||
|
||||
2.2. Parameter for Linear Booster
|
||||
2.2. Parameters for Linear Booster
|
||||
|
||||
\itemize{
|
||||
\item \code{lambda} L2 regularization term on weights. Default: 0
|
||||
@@ -88,10 +90,10 @@ xgboost(
|
||||
\item \code{binary:logistic} logistic regression for binary classification. Output probability.
|
||||
\item \code{binary:logitraw} logistic regression for binary classification, output score before logistic transformation.
|
||||
\item \code{binary:hinge}: hinge loss for binary classification. This makes predictions of 0 or 1, rather than producing probabilities.
|
||||
\item \code{count:poisson}: poisson regression for count data, output mean of poisson distribution. \code{max_delta_step} is set to 0.7 by default in poisson regression (used to safeguard optimization).
|
||||
\item \code{count:poisson}: Poisson regression for count data, output mean of Poisson distribution. \code{max_delta_step} is set to 0.7 by default in poisson regression (used to safeguard optimization).
|
||||
\item \code{survival:cox}: Cox regression for right censored survival time data (negative values are considered right censored). Note that predictions are returned on the hazard ratio scale (i.e., as HR = exp(marginal_prediction) in the proportional hazard function \code{h(t) = h0(t) * HR)}.
|
||||
\item \code{survival:aft}: Accelerated failure time model for censored survival time data. See \href{https://xgboost.readthedocs.io/en/latest/tutorials/aft_survival_analysis.html}{Survival Analysis with Accelerated Failure Time} for details.
|
||||
\item \code{aft_loss_distribution}: Probabilty Density Function used by \code{survival:aft} and \code{aft-nloglik} metric.
|
||||
\item \code{aft_loss_distribution}: Probability Density Function used by \code{survival:aft} and \code{aft-nloglik} metric.
|
||||
\item \code{multi:softmax} set xgboost to do multiclass classification using the softmax objective. Class is represented by a number and should be from 0 to \code{num_class - 1}.
|
||||
\item \code{multi:softprob} same as softmax, but prediction outputs a vector of ndata * nclass elements, which can be further reshaped to ndata, nclass matrix. The result contains predicted probabilities of each data point belonging to each class.
|
||||
\item \code{rank:pairwise} set xgboost to do ranking task by minimizing the pairwise loss.
|
||||
@@ -185,9 +187,6 @@ An object of class \code{xgb.Booster} with the following elements:
|
||||
explicitly passed.
|
||||
\item \code{best_iteration} iteration number with the best evaluation metric value
|
||||
(only available with early stopping).
|
||||
\item \code{best_ntreelimit} the \code{ntreelimit} value corresponding to the best iteration,
|
||||
which could further be used in \code{predict} method
|
||||
(only available with early stopping).
|
||||
\item \code{best_score} the best evaluation metric value during early stopping.
|
||||
(only available with early stopping).
|
||||
\item \code{feature_names} names of the training dataset features
|
||||
@@ -209,11 +208,11 @@ than the \code{xgboost} interface.
|
||||
Parallelization is automatically enabled if \code{OpenMP} is present.
|
||||
Number of threads can also be manually specified via \code{nthread} parameter.
|
||||
|
||||
The evaluation metric is chosen automatically by Xgboost (according to the objective)
|
||||
The evaluation metric is chosen automatically by XGBoost (according to the objective)
|
||||
when the \code{eval_metric} parameter is not provided.
|
||||
User may set one or several \code{eval_metric} parameters.
|
||||
Note that when using a customized metric, only this single metric can be used.
|
||||
The following is the list of built-in metrics for which Xgboost provides optimized implementation:
|
||||
The following is the list of built-in metrics for which XGBoost provides optimized implementation:
|
||||
\itemize{
|
||||
\item \code{rmse} root mean square error. \url{https://en.wikipedia.org/wiki/Root_mean_square_error}
|
||||
\item \code{logloss} negative log-likelihood. \url{https://en.wikipedia.org/wiki/Log-likelihood}
|
||||
@@ -242,8 +241,8 @@ The following callbacks are automatically created when certain parameters are se
|
||||
data(agaricus.train, package='xgboost')
|
||||
data(agaricus.test, package='xgboost')
|
||||
|
||||
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
||||
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
||||
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||
watchlist <- list(train = dtrain, eval = dtest)
|
||||
|
||||
## A simple xgb.train example:
|
||||
|
||||
@@ -4,10 +4,17 @@
|
||||
\alias{xgb.unserialize}
|
||||
\title{Load the instance back from \code{\link{xgb.serialize}}}
|
||||
\usage{
|
||||
xgb.unserialize(buffer)
|
||||
xgb.unserialize(buffer, handle = NULL)
|
||||
}
|
||||
\arguments{
|
||||
\item{buffer}{the buffer containing booster instance saved by \code{\link{xgb.serialize}}}
|
||||
|
||||
\item{handle}{An \code{xgb.Booster.handle} object which will be overwritten with
|
||||
the new deserialized object. Must be a null handle (e.g. when loading the model through
|
||||
`readRDS`). If not provided, a new handle will be created.}
|
||||
}
|
||||
\value{
|
||||
An \code{xgb.Booster.handle} object.
|
||||
}
|
||||
\description{
|
||||
Load the instance back from \code{\link{xgb.serialize}}
|
||||
|
||||
@@ -17,9 +17,79 @@ endif
|
||||
$(foreach v, $(XGB_RFLAGS), $(warning $(v)))
|
||||
|
||||
PKG_CPPFLAGS= -I$(PKGROOT)/include -I$(PKGROOT)/dmlc-core/include -I$(PKGROOT)/rabit/include -I$(PKGROOT) $(XGB_RFLAGS)
|
||||
PKG_CXXFLAGS= @OPENMP_CXXFLAGS@ @ENDIAN_FLAG@ -pthread
|
||||
PKG_CXXFLAGS= @OPENMP_CXXFLAGS@ @ENDIAN_FLAG@ -pthread $(CXX_VISIBILITY)
|
||||
PKG_LIBS = @OPENMP_CXXFLAGS@ @OPENMP_LIB@ @ENDIAN_FLAG@ @BACKTRACE_LIB@ -pthread
|
||||
OBJECTS= ./xgboost_R.o ./xgboost_custom.o ./xgboost_assert.o ./init.o \
|
||||
$(PKGROOT)/amalgamation/xgboost-all0.o $(PKGROOT)/amalgamation/dmlc-minimum0.o \
|
||||
$(PKGROOT)/rabit/src/engine.o $(PKGROOT)/rabit/src/c_api.o \
|
||||
$(PKGROOT)/rabit/src/allreduce_base.o
|
||||
|
||||
OBJECTS= \
|
||||
./xgboost_R.o \
|
||||
./xgboost_custom.o \
|
||||
./init.o \
|
||||
$(PKGROOT)/src/metric/metric.o \
|
||||
$(PKGROOT)/src/metric/elementwise_metric.o \
|
||||
$(PKGROOT)/src/metric/multiclass_metric.o \
|
||||
$(PKGROOT)/src/metric/rank_metric.o \
|
||||
$(PKGROOT)/src/metric/auc.o \
|
||||
$(PKGROOT)/src/metric/survival_metric.o \
|
||||
$(PKGROOT)/src/objective/objective.o \
|
||||
$(PKGROOT)/src/objective/regression_obj.o \
|
||||
$(PKGROOT)/src/objective/multiclass_obj.o \
|
||||
$(PKGROOT)/src/objective/rank_obj.o \
|
||||
$(PKGROOT)/src/objective/hinge.o \
|
||||
$(PKGROOT)/src/objective/aft_obj.o \
|
||||
$(PKGROOT)/src/objective/adaptive.o \
|
||||
$(PKGROOT)/src/gbm/gbm.o \
|
||||
$(PKGROOT)/src/gbm/gbtree.o \
|
||||
$(PKGROOT)/src/gbm/gbtree_model.o \
|
||||
$(PKGROOT)/src/gbm/gblinear.o \
|
||||
$(PKGROOT)/src/gbm/gblinear_model.o \
|
||||
$(PKGROOT)/src/data/simple_dmatrix.o \
|
||||
$(PKGROOT)/src/data/data.o \
|
||||
$(PKGROOT)/src/data/sparse_page_raw_format.o \
|
||||
$(PKGROOT)/src/data/ellpack_page.o \
|
||||
$(PKGROOT)/src/data/gradient_index.o \
|
||||
$(PKGROOT)/src/data/gradient_index_page_source.o \
|
||||
$(PKGROOT)/src/data/gradient_index_format.o \
|
||||
$(PKGROOT)/src/data/sparse_page_dmatrix.o \
|
||||
$(PKGROOT)/src/data/proxy_dmatrix.o \
|
||||
$(PKGROOT)/src/data/iterative_dmatrix.o \
|
||||
$(PKGROOT)/src/predictor/predictor.o \
|
||||
$(PKGROOT)/src/predictor/cpu_predictor.o \
|
||||
$(PKGROOT)/src/tree/constraints.o \
|
||||
$(PKGROOT)/src/tree/param.o \
|
||||
$(PKGROOT)/src/tree/tree_model.o \
|
||||
$(PKGROOT)/src/tree/tree_updater.o \
|
||||
$(PKGROOT)/src/tree/updater_approx.o \
|
||||
$(PKGROOT)/src/tree/updater_colmaker.o \
|
||||
$(PKGROOT)/src/tree/updater_prune.o \
|
||||
$(PKGROOT)/src/tree/updater_quantile_hist.o \
|
||||
$(PKGROOT)/src/tree/updater_refresh.o \
|
||||
$(PKGROOT)/src/tree/updater_sync.o \
|
||||
$(PKGROOT)/src/linear/linear_updater.o \
|
||||
$(PKGROOT)/src/linear/updater_coordinate.o \
|
||||
$(PKGROOT)/src/linear/updater_shotgun.o \
|
||||
$(PKGROOT)/src/learner.o \
|
||||
$(PKGROOT)/src/logging.o \
|
||||
$(PKGROOT)/src/global_config.o \
|
||||
$(PKGROOT)/src/collective/communicator.o \
|
||||
$(PKGROOT)/src/collective/socket.o \
|
||||
$(PKGROOT)/src/common/charconv.o \
|
||||
$(PKGROOT)/src/common/column_matrix.o \
|
||||
$(PKGROOT)/src/common/common.o \
|
||||
$(PKGROOT)/src/common/hist_util.o \
|
||||
$(PKGROOT)/src/common/host_device_vector.o \
|
||||
$(PKGROOT)/src/common/io.o \
|
||||
$(PKGROOT)/src/common/json.o \
|
||||
$(PKGROOT)/src/common/numeric.o \
|
||||
$(PKGROOT)/src/common/pseudo_huber.o \
|
||||
$(PKGROOT)/src/common/quantile.o \
|
||||
$(PKGROOT)/src/common/random.o \
|
||||
$(PKGROOT)/src/common/survival_util.o \
|
||||
$(PKGROOT)/src/common/threading_utils.o \
|
||||
$(PKGROOT)/src/common/timer.o \
|
||||
$(PKGROOT)/src/common/version.o \
|
||||
$(PKGROOT)/src/c_api/c_api.o \
|
||||
$(PKGROOT)/src/c_api/c_api_error.o \
|
||||
$(PKGROOT)/amalgamation/dmlc-minimum0.o \
|
||||
$(PKGROOT)/rabit/src/engine.o \
|
||||
$(PKGROOT)/rabit/src/rabit_c_api.o \
|
||||
$(PKGROOT)/rabit/src/allreduce_base.o
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
# package root
|
||||
PKGROOT=./
|
||||
PKGROOT=../../
|
||||
ENABLE_STD_THREAD=0
|
||||
# _*_ mode: Makefile; _*_
|
||||
|
||||
# This file is only used for windows compilation from github
|
||||
# It will be replaced with Makevars.in for the CRAN version
|
||||
.PHONY: all xgblib
|
||||
all: $(SHLIB)
|
||||
$(SHLIB): xgblib
|
||||
xgblib:
|
||||
cp -r ../../src .
|
||||
cp -r ../../rabit .
|
||||
cp -r ../../dmlc-core .
|
||||
cp -r ../../include .
|
||||
cp -r ../../amalgamation .
|
||||
|
||||
CXX_STD = CXX14
|
||||
|
||||
XGB_RFLAGS = -DXGBOOST_STRICT_R_MODE=1 -DDMLC_LOG_BEFORE_THROW=0\
|
||||
@@ -29,11 +17,79 @@ endif
|
||||
$(foreach v, $(XGB_RFLAGS), $(warning $(v)))
|
||||
|
||||
PKG_CPPFLAGS= -I$(PKGROOT)/include -I$(PKGROOT)/dmlc-core/include -I$(PKGROOT)/rabit/include -I$(PKGROOT) $(XGB_RFLAGS)
|
||||
PKG_CXXFLAGS= $(SHLIB_OPENMP_CXXFLAGS) $(SHLIB_PTHREAD_FLAGS)
|
||||
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(SHLIB_PTHREAD_FLAGS)
|
||||
OBJECTS= ./xgboost_R.o ./xgboost_custom.o ./xgboost_assert.o ./init.o \
|
||||
$(PKGROOT)/amalgamation/xgboost-all0.o $(PKGROOT)/amalgamation/dmlc-minimum0.o \
|
||||
$(PKGROOT)/rabit/src/engine.o $(PKGROOT)/rabit/src/c_api.o \
|
||||
$(PKGROOT)/rabit/src/allreduce_base.o
|
||||
PKG_CXXFLAGS= $(SHLIB_OPENMP_CXXFLAGS) -DDMLC_CMAKE_LITTLE_ENDIAN=1 $(SHLIB_PTHREAD_FLAGS) $(CXX_VISIBILITY)
|
||||
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) -DDMLC_CMAKE_LITTLE_ENDIAN=1 $(SHLIB_PTHREAD_FLAGS) -lwsock32 -lws2_32
|
||||
|
||||
$(OBJECTS) : xgblib
|
||||
OBJECTS= \
|
||||
./xgboost_R.o \
|
||||
./xgboost_custom.o \
|
||||
./init.o \
|
||||
$(PKGROOT)/src/metric/metric.o \
|
||||
$(PKGROOT)/src/metric/elementwise_metric.o \
|
||||
$(PKGROOT)/src/metric/multiclass_metric.o \
|
||||
$(PKGROOT)/src/metric/rank_metric.o \
|
||||
$(PKGROOT)/src/metric/auc.o \
|
||||
$(PKGROOT)/src/metric/survival_metric.o \
|
||||
$(PKGROOT)/src/objective/objective.o \
|
||||
$(PKGROOT)/src/objective/regression_obj.o \
|
||||
$(PKGROOT)/src/objective/multiclass_obj.o \
|
||||
$(PKGROOT)/src/objective/rank_obj.o \
|
||||
$(PKGROOT)/src/objective/hinge.o \
|
||||
$(PKGROOT)/src/objective/aft_obj.o \
|
||||
$(PKGROOT)/src/objective/adaptive.o \
|
||||
$(PKGROOT)/src/gbm/gbm.o \
|
||||
$(PKGROOT)/src/gbm/gbtree.o \
|
||||
$(PKGROOT)/src/gbm/gbtree_model.o \
|
||||
$(PKGROOT)/src/gbm/gblinear.o \
|
||||
$(PKGROOT)/src/gbm/gblinear_model.o \
|
||||
$(PKGROOT)/src/data/simple_dmatrix.o \
|
||||
$(PKGROOT)/src/data/data.o \
|
||||
$(PKGROOT)/src/data/sparse_page_raw_format.o \
|
||||
$(PKGROOT)/src/data/ellpack_page.o \
|
||||
$(PKGROOT)/src/data/gradient_index.o \
|
||||
$(PKGROOT)/src/data/gradient_index_page_source.o \
|
||||
$(PKGROOT)/src/data/gradient_index_format.o \
|
||||
$(PKGROOT)/src/data/sparse_page_dmatrix.o \
|
||||
$(PKGROOT)/src/data/proxy_dmatrix.o \
|
||||
$(PKGROOT)/src/data/iterative_dmatrix.o \
|
||||
$(PKGROOT)/src/predictor/predictor.o \
|
||||
$(PKGROOT)/src/predictor/cpu_predictor.o \
|
||||
$(PKGROOT)/src/tree/constraints.o \
|
||||
$(PKGROOT)/src/tree/param.o \
|
||||
$(PKGROOT)/src/tree/tree_model.o \
|
||||
$(PKGROOT)/src/tree/tree_updater.o \
|
||||
$(PKGROOT)/src/tree/updater_approx.o \
|
||||
$(PKGROOT)/src/tree/updater_colmaker.o \
|
||||
$(PKGROOT)/src/tree/updater_prune.o \
|
||||
$(PKGROOT)/src/tree/updater_quantile_hist.o \
|
||||
$(PKGROOT)/src/tree/updater_refresh.o \
|
||||
$(PKGROOT)/src/tree/updater_sync.o \
|
||||
$(PKGROOT)/src/linear/linear_updater.o \
|
||||
$(PKGROOT)/src/linear/updater_coordinate.o \
|
||||
$(PKGROOT)/src/linear/updater_shotgun.o \
|
||||
$(PKGROOT)/src/learner.o \
|
||||
$(PKGROOT)/src/logging.o \
|
||||
$(PKGROOT)/src/global_config.o \
|
||||
$(PKGROOT)/src/collective/communicator.o \
|
||||
$(PKGROOT)/src/collective/socket.o \
|
||||
$(PKGROOT)/src/common/charconv.o \
|
||||
$(PKGROOT)/src/common/column_matrix.o \
|
||||
$(PKGROOT)/src/common/common.o \
|
||||
$(PKGROOT)/src/common/hist_util.o \
|
||||
$(PKGROOT)/src/common/host_device_vector.o \
|
||||
$(PKGROOT)/src/common/io.o \
|
||||
$(PKGROOT)/src/common/json.o \
|
||||
$(PKGROOT)/src/common/numeric.o \
|
||||
$(PKGROOT)/src/common/pseudo_huber.o \
|
||||
$(PKGROOT)/src/common/quantile.o \
|
||||
$(PKGROOT)/src/common/random.o \
|
||||
$(PKGROOT)/src/common/survival_util.o \
|
||||
$(PKGROOT)/src/common/threading_utils.o \
|
||||
$(PKGROOT)/src/common/timer.o \
|
||||
$(PKGROOT)/src/common/version.o \
|
||||
$(PKGROOT)/src/c_api/c_api.o \
|
||||
$(PKGROOT)/src/c_api/c_api_error.o \
|
||||
$(PKGROOT)/amalgamation/dmlc-minimum0.o \
|
||||
$(PKGROOT)/rabit/src/engine.o \
|
||||
$(PKGROOT)/rabit/src/rabit_c_api.o \
|
||||
$(PKGROOT)/rabit/src/allreduce_base.o
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <Rinternals.h>
|
||||
#include <stdlib.h>
|
||||
#include <R_ext/Rdynload.h>
|
||||
#include <R_ext/Visibility.h>
|
||||
|
||||
/* FIXME:
|
||||
Check these declarations against the C/Fortran source code.
|
||||
@@ -17,73 +18,85 @@ Check these declarations against the C/Fortran source code.
|
||||
/* .Call calls */
|
||||
extern SEXP XGBoosterBoostOneIter_R(SEXP, SEXP, SEXP, SEXP);
|
||||
extern SEXP XGBoosterCreate_R(SEXP);
|
||||
extern SEXP XGBoosterCreateInEmptyObj_R(SEXP, SEXP);
|
||||
extern SEXP XGBoosterDumpModel_R(SEXP, SEXP, SEXP, SEXP);
|
||||
extern SEXP XGBoosterEvalOneIter_R(SEXP, SEXP, SEXP, SEXP);
|
||||
extern SEXP XGBoosterGetAttrNames_R(SEXP);
|
||||
extern SEXP XGBoosterGetAttr_R(SEXP, SEXP);
|
||||
extern SEXP XGBoosterLoadModelFromRaw_R(SEXP, SEXP);
|
||||
extern SEXP XGBoosterSaveModelToRaw_R(SEXP handle, SEXP config);
|
||||
extern SEXP XGBoosterLoadModel_R(SEXP, SEXP);
|
||||
extern SEXP XGBoosterSaveJsonConfig_R(SEXP handle);
|
||||
extern SEXP XGBoosterLoadJsonConfig_R(SEXP handle, SEXP value);
|
||||
extern SEXP XGBoosterSerializeToBuffer_R(SEXP handle);
|
||||
extern SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw);
|
||||
extern SEXP XGBoosterModelToRaw_R(SEXP);
|
||||
extern SEXP XGBoosterPredict_R(SEXP, SEXP, SEXP, SEXP, SEXP);
|
||||
extern SEXP XGBoosterPredictFromDMatrix_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGBoosterSaveModel_R(SEXP, SEXP);
|
||||
extern SEXP XGBoosterSetAttr_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGBoosterSetParam_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGBoosterUpdateOneIter_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGCheckNullPtr_R(SEXP);
|
||||
extern SEXP XGDMatrixCreateFromCSC_R(SEXP, SEXP, SEXP, SEXP);
|
||||
extern SEXP XGDMatrixCreateFromCSC_R(SEXP, SEXP, SEXP, SEXP, SEXP);
|
||||
extern SEXP XGDMatrixCreateFromCSR_R(SEXP, SEXP, SEXP, SEXP, SEXP);
|
||||
extern SEXP XGDMatrixCreateFromFile_R(SEXP, SEXP);
|
||||
extern SEXP XGDMatrixCreateFromMat_R(SEXP, SEXP);
|
||||
extern SEXP XGDMatrixCreateFromMat_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGDMatrixGetInfo_R(SEXP, SEXP);
|
||||
extern SEXP XGDMatrixGetStrFeatureInfo_R(SEXP, SEXP);
|
||||
extern SEXP XGDMatrixNumCol_R(SEXP);
|
||||
extern SEXP XGDMatrixNumRow_R(SEXP);
|
||||
extern SEXP XGDMatrixSaveBinary_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGDMatrixSetInfo_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGDMatrixSetStrFeatureInfo_R(SEXP, SEXP, SEXP);
|
||||
extern SEXP XGDMatrixSliceDMatrix_R(SEXP, SEXP);
|
||||
extern SEXP XGBSetGlobalConfig_R(SEXP);
|
||||
extern SEXP XGBGetGlobalConfig_R();
|
||||
extern SEXP XGBGetGlobalConfig_R(void);
|
||||
extern SEXP XGBoosterFeatureScore_R(SEXP, SEXP);
|
||||
|
||||
static const R_CallMethodDef CallEntries[] = {
|
||||
{"XGBoosterBoostOneIter_R", (DL_FUNC) &XGBoosterBoostOneIter_R, 4},
|
||||
{"XGBoosterCreate_R", (DL_FUNC) &XGBoosterCreate_R, 1},
|
||||
{"XGBoosterCreateInEmptyObj_R", (DL_FUNC) &XGBoosterCreateInEmptyObj_R, 2},
|
||||
{"XGBoosterDumpModel_R", (DL_FUNC) &XGBoosterDumpModel_R, 4},
|
||||
{"XGBoosterEvalOneIter_R", (DL_FUNC) &XGBoosterEvalOneIter_R, 4},
|
||||
{"XGBoosterGetAttrNames_R", (DL_FUNC) &XGBoosterGetAttrNames_R, 1},
|
||||
{"XGBoosterGetAttr_R", (DL_FUNC) &XGBoosterGetAttr_R, 2},
|
||||
{"XGBoosterLoadModelFromRaw_R", (DL_FUNC) &XGBoosterLoadModelFromRaw_R, 2},
|
||||
{"XGBoosterSaveModelToRaw_R", (DL_FUNC) &XGBoosterSaveModelToRaw_R, 2},
|
||||
{"XGBoosterLoadModel_R", (DL_FUNC) &XGBoosterLoadModel_R, 2},
|
||||
{"XGBoosterSaveJsonConfig_R", (DL_FUNC) &XGBoosterSaveJsonConfig_R, 1},
|
||||
{"XGBoosterLoadJsonConfig_R", (DL_FUNC) &XGBoosterLoadJsonConfig_R, 2},
|
||||
{"XGBoosterSerializeToBuffer_R", (DL_FUNC) &XGBoosterSerializeToBuffer_R, 1},
|
||||
{"XGBoosterUnserializeFromBuffer_R", (DL_FUNC) &XGBoosterUnserializeFromBuffer_R, 2},
|
||||
{"XGBoosterModelToRaw_R", (DL_FUNC) &XGBoosterModelToRaw_R, 1},
|
||||
{"XGBoosterPredict_R", (DL_FUNC) &XGBoosterPredict_R, 5},
|
||||
{"XGBoosterPredictFromDMatrix_R", (DL_FUNC) &XGBoosterPredictFromDMatrix_R, 3},
|
||||
{"XGBoosterSaveModel_R", (DL_FUNC) &XGBoosterSaveModel_R, 2},
|
||||
{"XGBoosterSetAttr_R", (DL_FUNC) &XGBoosterSetAttr_R, 3},
|
||||
{"XGBoosterSetParam_R", (DL_FUNC) &XGBoosterSetParam_R, 3},
|
||||
{"XGBoosterUpdateOneIter_R", (DL_FUNC) &XGBoosterUpdateOneIter_R, 3},
|
||||
{"XGCheckNullPtr_R", (DL_FUNC) &XGCheckNullPtr_R, 1},
|
||||
{"XGDMatrixCreateFromCSC_R", (DL_FUNC) &XGDMatrixCreateFromCSC_R, 4},
|
||||
{"XGDMatrixCreateFromCSC_R", (DL_FUNC) &XGDMatrixCreateFromCSC_R, 5},
|
||||
{"XGDMatrixCreateFromCSR_R", (DL_FUNC) &XGDMatrixCreateFromCSR_R, 5},
|
||||
{"XGDMatrixCreateFromFile_R", (DL_FUNC) &XGDMatrixCreateFromFile_R, 2},
|
||||
{"XGDMatrixCreateFromMat_R", (DL_FUNC) &XGDMatrixCreateFromMat_R, 2},
|
||||
{"XGDMatrixCreateFromMat_R", (DL_FUNC) &XGDMatrixCreateFromMat_R, 3},
|
||||
{"XGDMatrixGetInfo_R", (DL_FUNC) &XGDMatrixGetInfo_R, 2},
|
||||
{"XGDMatrixGetStrFeatureInfo_R", (DL_FUNC) &XGDMatrixGetStrFeatureInfo_R, 2},
|
||||
{"XGDMatrixNumCol_R", (DL_FUNC) &XGDMatrixNumCol_R, 1},
|
||||
{"XGDMatrixNumRow_R", (DL_FUNC) &XGDMatrixNumRow_R, 1},
|
||||
{"XGDMatrixSaveBinary_R", (DL_FUNC) &XGDMatrixSaveBinary_R, 3},
|
||||
{"XGDMatrixSetInfo_R", (DL_FUNC) &XGDMatrixSetInfo_R, 3},
|
||||
{"XGDMatrixSetStrFeatureInfo_R", (DL_FUNC) &XGDMatrixSetStrFeatureInfo_R, 3},
|
||||
{"XGDMatrixSliceDMatrix_R", (DL_FUNC) &XGDMatrixSliceDMatrix_R, 2},
|
||||
{"XGBSetGlobalConfig_R", (DL_FUNC) &XGBSetGlobalConfig_R, 1},
|
||||
{"XGBGetGlobalConfig_R", (DL_FUNC) &XGBGetGlobalConfig_R, 0},
|
||||
{"XGBoosterFeatureScore_R", (DL_FUNC) &XGBoosterFeatureScore_R, 2},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
__declspec(dllexport)
|
||||
#endif // defined(_WIN32)
|
||||
void R_init_xgboost(DllInfo *dll) {
|
||||
void attribute_visible R_init_xgboost(DllInfo *dll) {
|
||||
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
|
||||
R_useDynamicSymbols(dll, FALSE);
|
||||
}
|
||||
|
||||
3
R-package/src/xgboost-win.def
Normal file
3
R-package/src/xgboost-win.def
Normal file
@@ -0,0 +1,3 @@
|
||||
LIBRARY xgboost.dll
|
||||
EXPORTS
|
||||
R_init_xgboost
|
||||
@@ -1,14 +1,23 @@
|
||||
// Copyright (c) 2014 by Contributors
|
||||
#include <dmlc/logging.h>
|
||||
#include <dmlc/omp.h>
|
||||
/**
|
||||
* Copyright 2014-2022 by XGBoost Contributors
|
||||
*/
|
||||
#include <dmlc/common.h>
|
||||
#include <dmlc/omp.h>
|
||||
#include <xgboost/c_api.h>
|
||||
#include <vector>
|
||||
#include <xgboost/data.h>
|
||||
#include <xgboost/generic_parameters.h>
|
||||
#include <xgboost/logging.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "../../src/c_api/c_api_error.h"
|
||||
#include "../../src/common/threading_utils.h"
|
||||
|
||||
#include "./xgboost_R.h"
|
||||
|
||||
/*!
|
||||
@@ -35,14 +44,27 @@
|
||||
error(XGBGetLastError()); \
|
||||
}
|
||||
|
||||
using dmlc::BeginPtr;
|
||||
|
||||
using namespace dmlc;
|
||||
xgboost::GenericParameter const *BoosterCtx(BoosterHandle handle) {
|
||||
CHECK_HANDLE();
|
||||
auto *learner = static_cast<xgboost::Learner *>(handle);
|
||||
CHECK(learner);
|
||||
return learner->Ctx();
|
||||
}
|
||||
|
||||
SEXP XGCheckNullPtr_R(SEXP handle) {
|
||||
xgboost::GenericParameter const *DMatrixCtx(DMatrixHandle handle) {
|
||||
CHECK_HANDLE();
|
||||
auto p_m = static_cast<std::shared_ptr<xgboost::DMatrix> *>(handle);
|
||||
CHECK(p_m);
|
||||
return p_m->get()->Ctx();
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGCheckNullPtr_R(SEXP handle) {
|
||||
return ScalarLogical(R_ExternalPtrAddr(handle) == NULL);
|
||||
}
|
||||
|
||||
void _DMatrixFinalizer(SEXP ext) {
|
||||
XGB_DLL void _DMatrixFinalizer(SEXP ext) {
|
||||
R_API_BEGIN();
|
||||
if (R_ExternalPtrAddr(ext) == NULL) return;
|
||||
CHECK_CALL(XGDMatrixFree(R_ExternalPtrAddr(ext)));
|
||||
@@ -50,14 +72,14 @@ void _DMatrixFinalizer(SEXP ext) {
|
||||
R_API_END();
|
||||
}
|
||||
|
||||
SEXP XGBSetGlobalConfig_R(SEXP json_str) {
|
||||
XGB_DLL SEXP XGBSetGlobalConfig_R(SEXP json_str) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBSetGlobalConfig(CHAR(asChar(json_str))));
|
||||
R_API_END();
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBGetGlobalConfig_R() {
|
||||
XGB_DLL SEXP XGBGetGlobalConfig_R() {
|
||||
const char* json_str;
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBGetGlobalConfig(&json_str));
|
||||
@@ -65,7 +87,7 @@ SEXP XGBGetGlobalConfig_R() {
|
||||
return mkString(json_str);
|
||||
}
|
||||
|
||||
SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) {
|
||||
XGB_DLL SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
DMatrixHandle handle;
|
||||
@@ -77,8 +99,7 @@ SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
||||
SEXP missing) {
|
||||
XGB_DLL SEXP XGDMatrixCreateFromMat_R(SEXP mat, SEXP missing, SEXP n_threads) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
SEXP dim = getAttrib(mat, R_DimSymbol);
|
||||
@@ -93,18 +114,16 @@ SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
||||
din = REAL(mat);
|
||||
}
|
||||
std::vector<float> data(nrow * ncol);
|
||||
dmlc::OMPException exc;
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (omp_ulong i = 0; i < nrow; ++i) {
|
||||
exc.Run([&]() {
|
||||
for (size_t j = 0; j < ncol; ++j) {
|
||||
data[i * ncol +j] = is_int ? static_cast<float>(iin[i + nrow * j]) : din[i + nrow * j];
|
||||
}
|
||||
});
|
||||
}
|
||||
exc.Rethrow();
|
||||
int32_t threads = xgboost::common::OmpGetNumThreads(asInteger(n_threads));
|
||||
|
||||
xgboost::common::ParallelFor(nrow, threads, [&](xgboost::omp_ulong i) {
|
||||
for (size_t j = 0; j < ncol; ++j) {
|
||||
data[i * ncol + j] = is_int ? static_cast<float>(iin[i + nrow * j]) : din[i + nrow * j];
|
||||
}
|
||||
});
|
||||
DMatrixHandle handle;
|
||||
CHECK_CALL(XGDMatrixCreateFromMat(BeginPtr(data), nrow, ncol, asReal(missing), &handle));
|
||||
CHECK_CALL(XGDMatrixCreateFromMat_omp(BeginPtr(data), nrow, ncol,
|
||||
asReal(missing), &handle, threads));
|
||||
ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue));
|
||||
R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE);
|
||||
R_API_END();
|
||||
@@ -112,10 +131,8 @@ SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
||||
SEXP indices,
|
||||
SEXP data,
|
||||
SEXP num_row) {
|
||||
XGB_DLL SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, SEXP indices, SEXP data,
|
||||
SEXP num_row, SEXP n_threads) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
const int *p_indptr = INTEGER(indptr);
|
||||
@@ -131,15 +148,11 @@ SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
||||
for (size_t i = 0; i < nindptr; ++i) {
|
||||
col_ptr_[i] = static_cast<size_t>(p_indptr[i]);
|
||||
}
|
||||
dmlc::OMPException exc;
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (int64_t i = 0; i < static_cast<int64_t>(ndata); ++i) {
|
||||
exc.Run([&]() {
|
||||
indices_[i] = static_cast<unsigned>(p_indices[i]);
|
||||
data_[i] = static_cast<float>(p_data[i]);
|
||||
});
|
||||
}
|
||||
exc.Rethrow();
|
||||
int32_t threads = xgboost::common::OmpGetNumThreads(asInteger(n_threads));
|
||||
xgboost::common::ParallelFor(ndata, threads, [&](xgboost::omp_ulong i) {
|
||||
indices_[i] = static_cast<unsigned>(p_indices[i]);
|
||||
data_[i] = static_cast<float>(p_data[i]);
|
||||
});
|
||||
DMatrixHandle handle;
|
||||
CHECK_CALL(XGDMatrixCreateFromCSCEx(BeginPtr(col_ptr_), BeginPtr(indices_),
|
||||
BeginPtr(data_), nindptr, ndata,
|
||||
@@ -151,7 +164,40 @@ SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset) {
|
||||
XGB_DLL SEXP XGDMatrixCreateFromCSR_R(SEXP indptr, SEXP indices, SEXP data,
|
||||
SEXP num_col, SEXP n_threads) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
const int *p_indptr = INTEGER(indptr);
|
||||
const int *p_indices = INTEGER(indices);
|
||||
const double *p_data = REAL(data);
|
||||
size_t nindptr = static_cast<size_t>(length(indptr));
|
||||
size_t ndata = static_cast<size_t>(length(data));
|
||||
size_t ncol = static_cast<size_t>(INTEGER(num_col)[0]);
|
||||
std::vector<size_t> row_ptr_(nindptr);
|
||||
std::vector<unsigned> indices_(ndata);
|
||||
std::vector<float> data_(ndata);
|
||||
|
||||
for (size_t i = 0; i < nindptr; ++i) {
|
||||
row_ptr_[i] = static_cast<size_t>(p_indptr[i]);
|
||||
}
|
||||
int32_t threads = xgboost::common::OmpGetNumThreads(asInteger(n_threads));
|
||||
xgboost::common::ParallelFor(ndata, threads, [&](xgboost::omp_ulong i) {
|
||||
indices_[i] = static_cast<unsigned>(p_indices[i]);
|
||||
data_[i] = static_cast<float>(p_data[i]);
|
||||
});
|
||||
DMatrixHandle handle;
|
||||
CHECK_CALL(XGDMatrixCreateFromCSREx(BeginPtr(row_ptr_), BeginPtr(indices_),
|
||||
BeginPtr(data_), nindptr, ndata,
|
||||
ncol, &handle));
|
||||
ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue));
|
||||
R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE);
|
||||
R_API_END();
|
||||
UNPROTECT(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
int len = length(idxset);
|
||||
@@ -171,7 +217,7 @@ SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent) {
|
||||
XGB_DLL SEXP XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGDMatrixSaveBinary(R_ExternalPtrAddr(handle),
|
||||
CHAR(asChar(fname)),
|
||||
@@ -180,49 +226,76 @@ SEXP XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent) {
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGDMatrixSetInfo_R(SEXP handle, SEXP field, SEXP array) {
|
||||
XGB_DLL SEXP XGDMatrixSetInfo_R(SEXP handle, SEXP field, SEXP array) {
|
||||
R_API_BEGIN();
|
||||
int len = length(array);
|
||||
const char *name = CHAR(asChar(field));
|
||||
dmlc::OMPException exc;
|
||||
auto ctx = DMatrixCtx(R_ExternalPtrAddr(handle));
|
||||
if (!strcmp("group", name)) {
|
||||
std::vector<unsigned> vec(len);
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (int i = 0; i < len; ++i) {
|
||||
exc.Run([&]() {
|
||||
vec[i] = static_cast<unsigned>(INTEGER(array)[i]);
|
||||
});
|
||||
}
|
||||
exc.Rethrow();
|
||||
CHECK_CALL(XGDMatrixSetUIntInfo(R_ExternalPtrAddr(handle),
|
||||
CHAR(asChar(field)),
|
||||
BeginPtr(vec), len));
|
||||
xgboost::common::ParallelFor(len, ctx->Threads(), [&](xgboost::omp_ulong i) {
|
||||
vec[i] = static_cast<unsigned>(INTEGER(array)[i]);
|
||||
});
|
||||
CHECK_CALL(
|
||||
XGDMatrixSetUIntInfo(R_ExternalPtrAddr(handle), CHAR(asChar(field)), BeginPtr(vec), len));
|
||||
} else {
|
||||
std::vector<float> vec(len);
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (int i = 0; i < len; ++i) {
|
||||
exc.Run([&]() {
|
||||
vec[i] = REAL(array)[i];
|
||||
});
|
||||
}
|
||||
exc.Rethrow();
|
||||
CHECK_CALL(XGDMatrixSetFloatInfo(R_ExternalPtrAddr(handle),
|
||||
CHAR(asChar(field)),
|
||||
BeginPtr(vec), len));
|
||||
xgboost::common::ParallelFor(len, ctx->Threads(),
|
||||
[&](xgboost::omp_ulong i) { vec[i] = REAL(array)[i]; });
|
||||
CHECK_CALL(
|
||||
XGDMatrixSetFloatInfo(R_ExternalPtrAddr(handle), CHAR(asChar(field)), BeginPtr(vec), len));
|
||||
}
|
||||
R_API_END();
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field) {
|
||||
XGB_DLL SEXP XGDMatrixSetStrFeatureInfo_R(SEXP handle, SEXP field, SEXP array) {
|
||||
R_API_BEGIN();
|
||||
size_t len{0};
|
||||
if (!isNull(array)) {
|
||||
len = length(array);
|
||||
}
|
||||
|
||||
const char *name = CHAR(asChar(field));
|
||||
std::vector<std::string> str_info;
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
str_info.emplace_back(CHAR(asChar(VECTOR_ELT(array, i))));
|
||||
}
|
||||
std::vector<char const*> vec(len);
|
||||
std::transform(str_info.cbegin(), str_info.cend(), vec.begin(),
|
||||
[](std::string const &str) { return str.c_str(); });
|
||||
CHECK_CALL(XGDMatrixSetStrFeatureInfo(R_ExternalPtrAddr(handle), name, vec.data(), len));
|
||||
R_API_END();
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGDMatrixGetStrFeatureInfo_R(SEXP handle, SEXP field) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
char const **out_features{nullptr};
|
||||
bst_ulong len{0};
|
||||
const char *name = CHAR(asChar(field));
|
||||
XGDMatrixGetStrFeatureInfo(R_ExternalPtrAddr(handle), name, &len, &out_features);
|
||||
|
||||
if (len > 0) {
|
||||
ret = PROTECT(allocVector(STRSXP, len));
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
SET_STRING_ELT(ret, i, mkChar(out_features[i]));
|
||||
}
|
||||
} else {
|
||||
ret = PROTECT(R_NilValue);
|
||||
}
|
||||
R_API_END();
|
||||
UNPROTECT(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
bst_ulong olen;
|
||||
const float *res;
|
||||
CHECK_CALL(XGDMatrixGetFloatInfo(R_ExternalPtrAddr(handle),
|
||||
CHAR(asChar(field)),
|
||||
&olen,
|
||||
&res));
|
||||
CHECK_CALL(XGDMatrixGetFloatInfo(R_ExternalPtrAddr(handle), CHAR(asChar(field)), &olen, &res));
|
||||
ret = PROTECT(allocVector(REALSXP, olen));
|
||||
for (size_t i = 0; i < olen; ++i) {
|
||||
REAL(ret)[i] = res[i];
|
||||
@@ -232,7 +305,7 @@ SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGDMatrixNumRow_R(SEXP handle) {
|
||||
XGB_DLL SEXP XGDMatrixNumRow_R(SEXP handle) {
|
||||
bst_ulong nrow;
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGDMatrixNumRow(R_ExternalPtrAddr(handle), &nrow));
|
||||
@@ -240,7 +313,7 @@ SEXP XGDMatrixNumRow_R(SEXP handle) {
|
||||
return ScalarInteger(static_cast<int>(nrow));
|
||||
}
|
||||
|
||||
SEXP XGDMatrixNumCol_R(SEXP handle) {
|
||||
XGB_DLL SEXP XGDMatrixNumCol_R(SEXP handle) {
|
||||
bst_ulong ncol;
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGDMatrixNumCol(R_ExternalPtrAddr(handle), &ncol));
|
||||
@@ -255,7 +328,7 @@ void _BoosterFinalizer(SEXP ext) {
|
||||
R_ClearExternalPtr(ext);
|
||||
}
|
||||
|
||||
SEXP XGBoosterCreate_R(SEXP dmats) {
|
||||
XGB_DLL SEXP XGBoosterCreate_R(SEXP dmats) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
int len = length(dmats);
|
||||
@@ -272,7 +345,22 @@ SEXP XGBoosterCreate_R(SEXP dmats) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val) {
|
||||
XGB_DLL SEXP XGBoosterCreateInEmptyObj_R(SEXP dmats, SEXP R_handle) {
|
||||
R_API_BEGIN();
|
||||
int len = length(dmats);
|
||||
std::vector<void*> dvec;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
dvec.push_back(R_ExternalPtrAddr(VECTOR_ELT(dmats, i)));
|
||||
}
|
||||
BoosterHandle handle;
|
||||
CHECK_CALL(XGBoosterCreate(BeginPtr(dvec), dvec.size(), &handle));
|
||||
R_SetExternalPtrAddr(R_handle, handle);
|
||||
R_RegisterCFinalizerEx(R_handle, _BoosterFinalizer, TRUE);
|
||||
R_API_END();
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBoosterSetParam(R_ExternalPtrAddr(handle),
|
||||
CHAR(asChar(name)),
|
||||
@@ -281,7 +369,7 @@ SEXP XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val) {
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterUpdateOneIter_R(SEXP handle, SEXP iter, SEXP dtrain) {
|
||||
XGB_DLL SEXP XGBoosterUpdateOneIter_R(SEXP handle, SEXP iter, SEXP dtrain) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBoosterUpdateOneIter(R_ExternalPtrAddr(handle),
|
||||
asInteger(iter),
|
||||
@@ -290,21 +378,17 @@ SEXP XGBoosterUpdateOneIter_R(SEXP handle, SEXP iter, SEXP dtrain) {
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess) {
|
||||
XGB_DLL SEXP XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess) {
|
||||
R_API_BEGIN();
|
||||
CHECK_EQ(length(grad), length(hess))
|
||||
<< "gradient and hess must have same length";
|
||||
int len = length(grad);
|
||||
std::vector<float> tgrad(len), thess(len);
|
||||
dmlc::OMPException exc;
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (int j = 0; j < len; ++j) {
|
||||
exc.Run([&]() {
|
||||
tgrad[j] = REAL(grad)[j];
|
||||
thess[j] = REAL(hess)[j];
|
||||
});
|
||||
}
|
||||
exc.Rethrow();
|
||||
auto ctx = BoosterCtx(R_ExternalPtrAddr(handle));
|
||||
xgboost::common::ParallelFor(len, ctx->Threads(), [&](xgboost::omp_ulong j) {
|
||||
tgrad[j] = REAL(grad)[j];
|
||||
thess[j] = REAL(hess)[j];
|
||||
});
|
||||
CHECK_CALL(XGBoosterBoostOneIter(R_ExternalPtrAddr(handle),
|
||||
R_ExternalPtrAddr(dtrain),
|
||||
BeginPtr(tgrad), BeginPtr(thess),
|
||||
@@ -313,7 +397,7 @@ SEXP XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess) {
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames) {
|
||||
XGB_DLL SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames) {
|
||||
const char *ret;
|
||||
R_API_BEGIN();
|
||||
CHECK_EQ(length(dmats), length(evnames))
|
||||
@@ -338,8 +422,8 @@ SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames) {
|
||||
return mkString(ret);
|
||||
}
|
||||
|
||||
SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
||||
SEXP ntree_limit, SEXP training) {
|
||||
XGB_DLL SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
||||
SEXP ntree_limit, SEXP training) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
bst_ulong olen;
|
||||
@@ -359,36 +443,59 @@ SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGBoosterLoadModel_R(SEXP handle, SEXP fname) {
|
||||
XGB_DLL SEXP XGBoosterPredictFromDMatrix_R(SEXP handle, SEXP dmat, SEXP json_config) {
|
||||
SEXP r_out_shape;
|
||||
SEXP r_out_result;
|
||||
SEXP r_out;
|
||||
|
||||
R_API_BEGIN();
|
||||
char const *c_json_config = CHAR(asChar(json_config));
|
||||
|
||||
bst_ulong out_dim;
|
||||
bst_ulong const *out_shape;
|
||||
float const *out_result;
|
||||
CHECK_CALL(XGBoosterPredictFromDMatrix(R_ExternalPtrAddr(handle),
|
||||
R_ExternalPtrAddr(dmat), c_json_config,
|
||||
&out_shape, &out_dim, &out_result));
|
||||
|
||||
r_out_shape = PROTECT(allocVector(INTSXP, out_dim));
|
||||
size_t len = 1;
|
||||
for (size_t i = 0; i < out_dim; ++i) {
|
||||
INTEGER(r_out_shape)[i] = out_shape[i];
|
||||
len *= out_shape[i];
|
||||
}
|
||||
r_out_result = PROTECT(allocVector(REALSXP, len));
|
||||
auto ctx = BoosterCtx(R_ExternalPtrAddr(handle));
|
||||
xgboost::common::ParallelFor(len, ctx->Threads(), [&](xgboost::omp_ulong i) {
|
||||
REAL(r_out_result)[i] = out_result[i];
|
||||
});
|
||||
|
||||
r_out = PROTECT(allocVector(VECSXP, 2));
|
||||
|
||||
SET_VECTOR_ELT(r_out, 0, r_out_shape);
|
||||
SET_VECTOR_ELT(r_out, 1, r_out_result);
|
||||
|
||||
R_API_END();
|
||||
UNPROTECT(3);
|
||||
|
||||
return r_out;
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGBoosterLoadModel_R(SEXP handle, SEXP fname) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBoosterLoadModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname))));
|
||||
R_API_END();
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterSaveModel_R(SEXP handle, SEXP fname) {
|
||||
XGB_DLL SEXP XGBoosterSaveModel_R(SEXP handle, SEXP fname) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBoosterSaveModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname))));
|
||||
R_API_END();
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterModelToRaw_R(SEXP handle) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
bst_ulong olen;
|
||||
const char *raw;
|
||||
CHECK_CALL(XGBoosterGetModelRaw(R_ExternalPtrAddr(handle), &olen, &raw));
|
||||
ret = PROTECT(allocVector(RAWSXP, olen));
|
||||
if (olen != 0) {
|
||||
memcpy(RAW(ret), raw, olen);
|
||||
}
|
||||
R_API_END();
|
||||
UNPROTECT(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw) {
|
||||
XGB_DLL SEXP XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBoosterLoadModelFromBuffer(R_ExternalPtrAddr(handle),
|
||||
RAW(raw),
|
||||
@@ -397,7 +504,23 @@ SEXP XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw) {
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterSaveJsonConfig_R(SEXP handle) {
|
||||
XGB_DLL SEXP XGBoosterSaveModelToRaw_R(SEXP handle, SEXP json_config) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
bst_ulong olen;
|
||||
char const *c_json_config = CHAR(asChar(json_config));
|
||||
char const *raw;
|
||||
CHECK_CALL(XGBoosterSaveModelToBuffer(R_ExternalPtrAddr(handle), c_json_config, &olen, &raw))
|
||||
ret = PROTECT(allocVector(RAWSXP, olen));
|
||||
if (olen != 0) {
|
||||
std::memcpy(RAW(ret), raw, olen);
|
||||
}
|
||||
R_API_END();
|
||||
UNPROTECT(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGBoosterSaveJsonConfig_R(SEXP handle) {
|
||||
const char* ret;
|
||||
R_API_BEGIN();
|
||||
bst_ulong len {0};
|
||||
@@ -408,14 +531,14 @@ SEXP XGBoosterSaveJsonConfig_R(SEXP handle) {
|
||||
return mkString(ret);
|
||||
}
|
||||
|
||||
SEXP XGBoosterLoadJsonConfig_R(SEXP handle, SEXP value) {
|
||||
XGB_DLL SEXP XGBoosterLoadJsonConfig_R(SEXP handle, SEXP value) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBoosterLoadJsonConfig(R_ExternalPtrAddr(handle), CHAR(asChar(value))));
|
||||
R_API_END();
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterSerializeToBuffer_R(SEXP handle) {
|
||||
XGB_DLL SEXP XGBoosterSerializeToBuffer_R(SEXP handle) {
|
||||
SEXP ret;
|
||||
R_API_BEGIN();
|
||||
bst_ulong out_len;
|
||||
@@ -430,7 +553,7 @@ SEXP XGBoosterSerializeToBuffer_R(SEXP handle) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw) {
|
||||
XGB_DLL SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw) {
|
||||
R_API_BEGIN();
|
||||
CHECK_CALL(XGBoosterUnserializeFromBuffer(R_ExternalPtrAddr(handle),
|
||||
RAW(raw),
|
||||
@@ -439,7 +562,7 @@ SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw) {
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats, SEXP dump_format) {
|
||||
XGB_DLL SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats, SEXP dump_format) {
|
||||
SEXP out;
|
||||
R_API_BEGIN();
|
||||
bst_ulong olen;
|
||||
@@ -476,7 +599,7 @@ SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats, SEXP dump_for
|
||||
return out;
|
||||
}
|
||||
|
||||
SEXP XGBoosterGetAttr_R(SEXP handle, SEXP name) {
|
||||
XGB_DLL SEXP XGBoosterGetAttr_R(SEXP handle, SEXP name) {
|
||||
SEXP out;
|
||||
R_API_BEGIN();
|
||||
int success;
|
||||
@@ -496,7 +619,7 @@ SEXP XGBoosterGetAttr_R(SEXP handle, SEXP name) {
|
||||
return out;
|
||||
}
|
||||
|
||||
SEXP XGBoosterSetAttr_R(SEXP handle, SEXP name, SEXP val) {
|
||||
XGB_DLL SEXP XGBoosterSetAttr_R(SEXP handle, SEXP name, SEXP val) {
|
||||
R_API_BEGIN();
|
||||
const char *v = isNull(val) ? nullptr : CHAR(asChar(val));
|
||||
CHECK_CALL(XGBoosterSetAttr(R_ExternalPtrAddr(handle),
|
||||
@@ -505,7 +628,7 @@ SEXP XGBoosterSetAttr_R(SEXP handle, SEXP name, SEXP val) {
|
||||
return R_NilValue;
|
||||
}
|
||||
|
||||
SEXP XGBoosterGetAttrNames_R(SEXP handle) {
|
||||
XGB_DLL SEXP XGBoosterGetAttrNames_R(SEXP handle) {
|
||||
SEXP out;
|
||||
R_API_BEGIN();
|
||||
bst_ulong len;
|
||||
@@ -524,3 +647,50 @@ SEXP XGBoosterGetAttrNames_R(SEXP handle) {
|
||||
UNPROTECT(1);
|
||||
return out;
|
||||
}
|
||||
|
||||
XGB_DLL SEXP XGBoosterFeatureScore_R(SEXP handle, SEXP json_config) {
|
||||
SEXP out_features_sexp;
|
||||
SEXP out_scores_sexp;
|
||||
SEXP out_shape_sexp;
|
||||
SEXP r_out;
|
||||
|
||||
R_API_BEGIN();
|
||||
char const *c_json_config = CHAR(asChar(json_config));
|
||||
bst_ulong out_n_features;
|
||||
char const **out_features;
|
||||
|
||||
bst_ulong out_dim;
|
||||
bst_ulong const *out_shape;
|
||||
float const *out_scores;
|
||||
|
||||
CHECK_CALL(XGBoosterFeatureScore(R_ExternalPtrAddr(handle), c_json_config,
|
||||
&out_n_features, &out_features,
|
||||
&out_dim, &out_shape, &out_scores));
|
||||
out_shape_sexp = PROTECT(allocVector(INTSXP, out_dim));
|
||||
size_t len = 1;
|
||||
for (size_t i = 0; i < out_dim; ++i) {
|
||||
INTEGER(out_shape_sexp)[i] = out_shape[i];
|
||||
len *= out_shape[i];
|
||||
}
|
||||
|
||||
out_scores_sexp = PROTECT(allocVector(REALSXP, len));
|
||||
auto ctx = BoosterCtx(R_ExternalPtrAddr(handle));
|
||||
xgboost::common::ParallelFor(len, ctx->Threads(), [&](xgboost::omp_ulong i) {
|
||||
REAL(out_scores_sexp)[i] = out_scores[i];
|
||||
});
|
||||
|
||||
out_features_sexp = PROTECT(allocVector(STRSXP, out_n_features));
|
||||
for (size_t i = 0; i < out_n_features; ++i) {
|
||||
SET_STRING_ELT(out_features_sexp, i, mkChar(out_features[i]));
|
||||
}
|
||||
|
||||
r_out = PROTECT(allocVector(VECSXP, 3));
|
||||
SET_VECTOR_ELT(r_out, 0, out_features_sexp);
|
||||
SET_VECTOR_ELT(r_out, 1, out_shape_sexp);
|
||||
SET_VECTOR_ELT(r_out, 2, out_scores_sexp);
|
||||
|
||||
R_API_END();
|
||||
UNPROTECT(4);
|
||||
|
||||
return r_out;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Copyright 2014 (c) by Contributors
|
||||
* Copyright 2014-2022 by XGBoost Contributors
|
||||
* \file xgboost_R.h
|
||||
* \author Tianqi Chen
|
||||
* \brief R wrapper of xgboost
|
||||
@@ -47,22 +47,35 @@ XGB_DLL SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent);
|
||||
* This assumes the matrix is stored in column major format
|
||||
* \param data R Matrix object
|
||||
* \param missing which value to represent missing value
|
||||
* \param n_threads Number of threads used to construct DMatrix from dense matrix.
|
||||
* \return created dmatrix
|
||||
*/
|
||||
XGB_DLL SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
||||
SEXP missing);
|
||||
SEXP missing,
|
||||
SEXP n_threads);
|
||||
/*!
|
||||
* \brief create a matrix content from CSC format
|
||||
* \param indptr pointer to column headers
|
||||
* \param indices row indices
|
||||
* \param data content of the data
|
||||
* \param num_row numer of rows (when it's set to 0, then guess from data)
|
||||
* \param n_threads Number of threads used to construct DMatrix from csc matrix.
|
||||
* \return created dmatrix
|
||||
*/
|
||||
XGB_DLL SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
||||
SEXP indices,
|
||||
SEXP data,
|
||||
SEXP num_row);
|
||||
XGB_DLL SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, SEXP indices, SEXP data, SEXP num_row,
|
||||
SEXP n_threads);
|
||||
|
||||
/*!
|
||||
* \brief create a matrix content from CSR format
|
||||
* \param indptr pointer to row headers
|
||||
* \param indices column indices
|
||||
* \param data content of the data
|
||||
* \param num_col numer of columns (when it's set to 0, then guess from data)
|
||||
* \param n_threads Number of threads used to construct DMatrix from csr matrix.
|
||||
* \return created dmatrix
|
||||
*/
|
||||
XGB_DLL SEXP XGDMatrixCreateFromCSR_R(SEXP indptr, SEXP indices, SEXP data, SEXP num_col,
|
||||
SEXP n_threads);
|
||||
|
||||
/*!
|
||||
* \brief create a new dmatrix from sliced content of existing matrix
|
||||
@@ -116,6 +129,14 @@ XGB_DLL SEXP XGDMatrixNumCol_R(SEXP handle);
|
||||
*/
|
||||
XGB_DLL SEXP XGBoosterCreate_R(SEXP dmats);
|
||||
|
||||
|
||||
/*!
|
||||
* \brief create xgboost learner, saving the pointer into an existing R object
|
||||
* \param dmats a list of dmatrix handles that will be cached
|
||||
* \param R_handle a clean R external pointer (not holding any object)
|
||||
*/
|
||||
XGB_DLL SEXP XGBoosterCreateInEmptyObj_R(SEXP dmats, SEXP R_handle);
|
||||
|
||||
/*!
|
||||
* \brief set parameters
|
||||
* \param handle handle
|
||||
@@ -156,7 +177,7 @@ XGB_DLL SEXP XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP h
|
||||
XGB_DLL SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames);
|
||||
|
||||
/*!
|
||||
* \brief make prediction based on dmat
|
||||
* \brief (Deprecated) make prediction based on dmat
|
||||
* \param handle handle
|
||||
* \param dmat data matrix
|
||||
* \param option_mask output_margin:1 predict_leaf:2
|
||||
@@ -165,6 +186,16 @@ XGB_DLL SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evn
|
||||
*/
|
||||
XGB_DLL SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
||||
SEXP ntree_limit, SEXP training);
|
||||
|
||||
/*!
|
||||
* \brief Run prediction on DMatrix, replacing `XGBoosterPredict_R`
|
||||
* \param handle handle
|
||||
* \param dmat data matrix
|
||||
* \param json_config See `XGBoosterPredictFromDMatrix` in xgboost c_api.h
|
||||
*
|
||||
* \return A list containing 2 vectors, first one for shape while second one for prediction result.
|
||||
*/
|
||||
XGB_DLL SEXP XGBoosterPredictFromDMatrix_R(SEXP handle, SEXP dmat, SEXP json_config);
|
||||
/*!
|
||||
* \brief load model from existing file
|
||||
* \param handle handle
|
||||
@@ -189,11 +220,21 @@ XGB_DLL SEXP XGBoosterSaveModel_R(SEXP handle, SEXP fname);
|
||||
XGB_DLL SEXP XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw);
|
||||
|
||||
/*!
|
||||
* \brief save model into R's raw array
|
||||
* \brief Save model into R's raw array
|
||||
*
|
||||
* \param handle handle
|
||||
* \return raw array
|
||||
* \param json_config JSON encoded string storing parameters for the function. Following
|
||||
* keys are expected in the JSON document:
|
||||
*
|
||||
* "format": str
|
||||
* - json: Output booster will be encoded as JSON.
|
||||
* - ubj: Output booster will be encoded as Univeral binary JSON.
|
||||
* - deprecated: Output booster will be encoded as old custom binary format. Do now use
|
||||
* this format except for compatibility reasons.
|
||||
*
|
||||
* \return Raw array
|
||||
*/
|
||||
XGB_DLL SEXP XGBoosterModelToRaw_R(SEXP handle);
|
||||
XGB_DLL SEXP XGBoosterSaveModelToRaw_R(SEXP handle, SEXP json_config);
|
||||
|
||||
/*!
|
||||
* \brief Save internal parameters as a JSON string
|
||||
@@ -257,4 +298,12 @@ XGB_DLL SEXP XGBoosterSetAttr_R(SEXP handle, SEXP name, SEXP val);
|
||||
*/
|
||||
XGB_DLL SEXP XGBoosterGetAttrNames_R(SEXP handle);
|
||||
|
||||
/*!
|
||||
* \brief Get feature scores from the model.
|
||||
* \param json_config See `XGBoosterFeatureScore` in xgboost c_api.h
|
||||
* \return A vector with the first element as feature names, second element as shape of
|
||||
* feature scores and thrid element as feature scores.
|
||||
*/
|
||||
XGB_DLL SEXP XGBoosterFeatureScore_R(SEXP handle, SEXP json_config);
|
||||
|
||||
#endif // XGBOOST_WRAPPER_R_H_ // NOLINT(*)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2014 by Contributors
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <Rinternals.h>
|
||||
|
||||
// implements error handling
|
||||
void XGBoostAssert_R(int exp, const char *fmt, ...) {
|
||||
char buf[1024];
|
||||
if (exp == 0) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
error("AssertError:%s\n", buf);
|
||||
}
|
||||
}
|
||||
void XGBoostCheck_R(int exp, const char *fmt, ...) {
|
||||
char buf[1024];
|
||||
if (exp == 0) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
error("%s\n", buf);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ my_linters <- list(
|
||||
object_usage_linter = lintr::object_usage_linter,
|
||||
object_length_linter = lintr::object_length_linter,
|
||||
open_curly_linter = lintr::open_curly_linter,
|
||||
semicolon = lintr::semicolon_terminator_linter,
|
||||
semicolon = lintr::semicolon_terminator_linter(semicolon = c("compound", "trailing")),
|
||||
seq = lintr::seq_linter,
|
||||
spaces_inside_linter = lintr::spaces_inside_linter,
|
||||
spaces_left_parentheses_linter = lintr::spaces_left_parentheses_linter,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require(xgboost)
|
||||
library(Matrix)
|
||||
|
||||
context("basic functions")
|
||||
|
||||
@@ -34,6 +35,10 @@ test_that("train and predict binary classification", {
|
||||
err_pred1 <- sum((pred1 > 0.5) != train$label) / length(train$label)
|
||||
err_log <- bst$evaluation_log[1, train_error]
|
||||
expect_lt(abs(err_pred1 - err_log), 10e-6)
|
||||
|
||||
pred2 <- predict(bst, train$data, iterationrange = c(1, 2))
|
||||
expect_length(pred1, 6513)
|
||||
expect_equal(pred1, pred2)
|
||||
})
|
||||
|
||||
test_that("parameter validation works", {
|
||||
@@ -143,6 +148,24 @@ test_that("train and predict softprob", {
|
||||
pred_labels <- max.col(mpred) - 1
|
||||
err <- sum(pred_labels != lb) / length(lb)
|
||||
expect_equal(bst$evaluation_log[1, train_merror], err, tolerance = 5e-6)
|
||||
|
||||
mpred1 <- predict(bst, as.matrix(iris[, -5]), reshape = TRUE, iterationrange = c(1, 2))
|
||||
expect_equal(mpred, mpred1)
|
||||
|
||||
d <- cbind(
|
||||
x1 = rnorm(100),
|
||||
x2 = rnorm(100),
|
||||
x3 = rnorm(100)
|
||||
)
|
||||
y <- sample.int(10, 100, replace = TRUE) - 1
|
||||
dtrain <- xgb.DMatrix(data = d, info = list(label = y))
|
||||
booster <- xgb.train(
|
||||
params = list(tree_method = "hist"), data = dtrain, nrounds = 4, num_class = 10,
|
||||
objective = "multi:softprob"
|
||||
)
|
||||
predt <- predict(booster, as.matrix(d), reshape = TRUE, strict_shape = FALSE)
|
||||
expect_equal(ncol(predt), 10)
|
||||
expect_equal(rowSums(predt), rep(1, 100), tolerance = 1e-7)
|
||||
})
|
||||
|
||||
test_that("train and predict softmax", {
|
||||
@@ -182,10 +205,8 @@ test_that("train and predict RF", {
|
||||
pred_err_20 <- sum((pred > 0.5) != lb) / length(lb)
|
||||
expect_equal(pred_err_20, pred_err)
|
||||
|
||||
#pred <- predict(bst, train$data, ntreelimit = 1)
|
||||
#pred_err_1 <- sum((pred > 0.5) != lb)/length(lb)
|
||||
#expect_lt(pred_err, pred_err_1)
|
||||
#expect_lt(pred_err, 0.08)
|
||||
pred1 <- predict(bst, train$data, iterationrange = c(1, 2))
|
||||
expect_equal(pred, pred1)
|
||||
})
|
||||
|
||||
test_that("train and predict RF with softprob", {
|
||||
@@ -331,7 +352,7 @@ test_that("train and predict with non-strict classes", {
|
||||
expect_error(pr <- predict(bst, train_dense), regexp = NA)
|
||||
expect_equal(pr0, pr)
|
||||
|
||||
# when someone inhertis from xgb.Booster, it should still be possible to use it as xgb.Booster
|
||||
# when someone inherits from xgb.Booster, it should still be possible to use it as xgb.Booster
|
||||
class(bst) <- c('super.Booster', 'xgb.Booster')
|
||||
expect_error(pr <- predict(bst, train_dense), regexp = NA)
|
||||
expect_equal(pr0, pr)
|
||||
@@ -346,7 +367,7 @@ test_that("max_delta_step works", {
|
||||
bst1 <- xgb.train(param, dtrain, nrounds, watchlist, verbose = 1)
|
||||
# model with restricted max_delta_step
|
||||
bst2 <- xgb.train(param, dtrain, nrounds, watchlist, verbose = 1, max_delta_step = 1)
|
||||
# the no-restriction model is expected to have consistently lower loss during the initial interations
|
||||
# the no-restriction model is expected to have consistently lower loss during the initial iterations
|
||||
expect_true(all(bst1$evaluation_log$train_logloss < bst2$evaluation_log$train_logloss))
|
||||
expect_lt(mean(bst1$evaluation_log$train_logloss) / mean(bst2$evaluation_log$train_logloss), 0.8)
|
||||
})
|
||||
@@ -385,3 +406,72 @@ test_that("Configuration works", {
|
||||
reloaded_config <- xgb.config(bst)
|
||||
expect_equal(config, reloaded_config);
|
||||
})
|
||||
|
||||
test_that("strict_shape works", {
|
||||
n_rounds <- 2
|
||||
|
||||
test_strict_shape <- function(bst, X, n_groups) {
|
||||
predt <- predict(bst, X, strict_shape = TRUE)
|
||||
margin <- predict(bst, X, outputmargin = TRUE, strict_shape = TRUE)
|
||||
contri <- predict(bst, X, predcontrib = TRUE, strict_shape = TRUE)
|
||||
interact <- predict(bst, X, predinteraction = TRUE, strict_shape = TRUE)
|
||||
leaf <- predict(bst, X, predleaf = TRUE, strict_shape = TRUE)
|
||||
|
||||
n_rows <- nrow(X)
|
||||
n_cols <- ncol(X)
|
||||
|
||||
expect_equal(dim(predt), c(n_groups, n_rows))
|
||||
expect_equal(dim(margin), c(n_groups, n_rows))
|
||||
expect_equal(dim(contri), c(n_cols + 1, n_groups, n_rows))
|
||||
expect_equal(dim(interact), c(n_cols + 1, n_cols + 1, n_groups, n_rows))
|
||||
expect_equal(dim(leaf), c(1, n_groups, n_rounds, n_rows))
|
||||
|
||||
if (n_groups != 1) {
|
||||
for (g in seq_len(n_groups)) {
|
||||
expect_lt(max(abs(colSums(contri[, g, ]) - margin[g, ])), 1e-5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_iris <- function() {
|
||||
y <- as.numeric(iris$Species) - 1
|
||||
X <- as.matrix(iris[, -5])
|
||||
|
||||
bst <- xgboost(data = X, label = y,
|
||||
max_depth = 2, nrounds = n_rounds,
|
||||
objective = "multi:softprob", num_class = 3, eval_metric = "merror")
|
||||
|
||||
test_strict_shape(bst, X, 3)
|
||||
}
|
||||
|
||||
|
||||
test_agaricus <- function() {
|
||||
data(agaricus.train, package = 'xgboost')
|
||||
X <- agaricus.train$data
|
||||
y <- agaricus.train$label
|
||||
|
||||
bst <- xgboost(data = X, label = y, max_depth = 2,
|
||||
nrounds = n_rounds, objective = "binary:logistic",
|
||||
eval_metric = 'error', eval_metric = 'auc', eval_metric = "logloss")
|
||||
|
||||
test_strict_shape(bst, X, 1)
|
||||
}
|
||||
|
||||
test_iris()
|
||||
test_agaricus()
|
||||
})
|
||||
|
||||
test_that("'predict' accepts CSR data", {
|
||||
X <- agaricus.train$data
|
||||
y <- agaricus.train$label
|
||||
x_csc <- as(X[1L, , drop = FALSE], "CsparseMatrix")
|
||||
x_csr <- as(x_csc, "RsparseMatrix")
|
||||
x_spv <- as(x_csc, "sparseVector")
|
||||
bst <- xgboost(data = X, label = y, objective = "binary:logistic",
|
||||
nrounds = 5L, verbose = FALSE)
|
||||
p_csc <- predict(bst, x_csc)
|
||||
p_csr <- predict(bst, x_csr)
|
||||
p_spv <- predict(bst, x_spv)
|
||||
expect_equal(p_csc, p_csr)
|
||||
expect_equal(p_csc, p_spv)
|
||||
})
|
||||
|
||||
@@ -27,6 +27,7 @@ test_that("xgb.DMatrix: saving, loading", {
|
||||
# save to a local file
|
||||
dtest1 <- xgb.DMatrix(test_data, label = test_label)
|
||||
tmp_file <- tempfile('xgb.DMatrix_')
|
||||
on.exit(unlink(tmp_file))
|
||||
expect_true(xgb.DMatrix.save(dtest1, tmp_file))
|
||||
# read from a local file
|
||||
expect_output(dtest3 <- xgb.DMatrix(tmp_file), "entries loaded from")
|
||||
@@ -41,7 +42,20 @@ test_that("xgb.DMatrix: saving, loading", {
|
||||
dtest4 <- xgb.DMatrix(tmp_file, silent = TRUE)
|
||||
expect_equal(dim(dtest4), c(3, 4))
|
||||
expect_equal(getinfo(dtest4, 'label'), c(0, 1, 0))
|
||||
unlink(tmp_file)
|
||||
|
||||
# check that feature info is saved
|
||||
data(agaricus.train, package = 'xgboost')
|
||||
dtrain <- xgb.DMatrix(data = agaricus.train$data, label = agaricus.train$label)
|
||||
cnames <- colnames(dtrain)
|
||||
expect_equal(length(cnames), 126)
|
||||
tmp_file <- tempfile('xgb.DMatrix_')
|
||||
xgb.DMatrix.save(dtrain, tmp_file)
|
||||
dtrain <- xgb.DMatrix(tmp_file)
|
||||
expect_equal(colnames(dtrain), cnames)
|
||||
|
||||
ft <- rep(c("c", "q"), each=length(cnames)/2)
|
||||
setinfo(dtrain, "feature_type", ft)
|
||||
expect_equal(ft, getinfo(dtrain, "feature_type"))
|
||||
})
|
||||
|
||||
test_that("xgb.DMatrix: getinfo & setinfo", {
|
||||
|
||||
27
R-package/tests/testthat/test_feature_weights.R
Normal file
27
R-package/tests/testthat/test_feature_weights.R
Normal file
@@ -0,0 +1,27 @@
|
||||
library(xgboost)
|
||||
|
||||
context("feature weights")
|
||||
|
||||
test_that("training with feature weights works", {
|
||||
nrows <- 1000
|
||||
ncols <- 9
|
||||
set.seed(2022)
|
||||
x <- matrix(rnorm(nrows * ncols), nrow = nrows)
|
||||
y <- rowSums(x)
|
||||
weights <- seq(from = 1, to = ncols)
|
||||
|
||||
test <- function(tm) {
|
||||
names <- paste0("f", 1:ncols)
|
||||
xy <- xgb.DMatrix(data = x, label = y, feature_weights = weights)
|
||||
params <- list(colsample_bynode = 0.4, tree_method = tm, nthread = 1)
|
||||
model <- xgb.train(params = params, data = xy, nrounds = 32)
|
||||
importance <- xgb.importance(model = model, feature_names = names)
|
||||
expect_equal(dim(importance), c(ncols, 4))
|
||||
importance <- importance[order(importance$Feature)]
|
||||
expect_lt(importance[1, Frequency], importance[9, Frequency])
|
||||
}
|
||||
|
||||
for (tm in c("hist", "approx", "exact")) {
|
||||
test(tm)
|
||||
}
|
||||
})
|
||||
@@ -46,3 +46,31 @@ test_that("gblinear works", {
|
||||
expect_equal(dim(h), c(n, ncol(dtrain) + 1))
|
||||
expect_s4_class(h, "dgCMatrix")
|
||||
})
|
||||
|
||||
test_that("gblinear early stopping works", {
|
||||
data(agaricus.train, package = 'xgboost')
|
||||
data(agaricus.test, package = 'xgboost')
|
||||
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
||||
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
||||
|
||||
param <- list(
|
||||
objective = "binary:logistic", eval_metric = "error", booster = "gblinear",
|
||||
nthread = 2, eta = 0.8, alpha = 0.0001, lambda = 0.0001,
|
||||
updater = "coord_descent"
|
||||
)
|
||||
|
||||
es_round <- 1
|
||||
n <- 10
|
||||
booster <- xgb.train(
|
||||
param, dtrain, n, list(eval = dtest, train = dtrain), early_stopping_rounds = es_round
|
||||
)
|
||||
expect_equal(booster$best_iteration, 5)
|
||||
predt_es <- predict(booster, dtrain)
|
||||
|
||||
n <- booster$best_iteration + es_round
|
||||
booster <- xgb.train(
|
||||
param, dtrain, n, list(eval = dtest, train = dtrain), early_stopping_rounds = es_round
|
||||
)
|
||||
predt <- predict(booster, dtrain)
|
||||
expect_equal(predt_es, predt)
|
||||
})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
library(testthat)
|
||||
context('Test helper functions')
|
||||
|
||||
require(xgboost)
|
||||
@@ -110,7 +111,7 @@ test_that("predict feature contributions works", {
|
||||
pred <- predict(bst.GLM, sparse_matrix, outputmargin = TRUE)
|
||||
expect_lt(max(abs(rowSums(pred_contr) - pred)), 1e-5)
|
||||
# manual calculation of linear terms
|
||||
coefs <- xgb.dump(bst.GLM)[-c(1, 2, 4)] %>% as.numeric
|
||||
coefs <- as.numeric(xgb.dump(bst.GLM)[-c(1, 2, 4)])
|
||||
coefs <- c(coefs[-1], coefs[1]) # intercept must be the last
|
||||
pred_contr_manual <- sweep(cbind(sparse_matrix, 1), 2, coefs, FUN = "*")
|
||||
expect_equal(as.numeric(pred_contr), as.numeric(pred_contr_manual),
|
||||
@@ -130,7 +131,11 @@ test_that("predict feature contributions works", {
|
||||
pred <- predict(mbst.GLM, as.matrix(iris[, -5]), outputmargin = TRUE, reshape = TRUE)
|
||||
pred_contr <- predict(mbst.GLM, as.matrix(iris[, -5]), predcontrib = TRUE)
|
||||
expect_length(pred_contr, 3)
|
||||
coefs_all <- xgb.dump(mbst.GLM)[-c(1, 2, 6)] %>% as.numeric %>% matrix(ncol = 3, byrow = TRUE)
|
||||
coefs_all <- matrix(
|
||||
data = as.numeric(xgb.dump(mbst.GLM)[-c(1, 2, 6)]),
|
||||
ncol = 3,
|
||||
byrow = TRUE
|
||||
)
|
||||
for (g in seq_along(pred_contr)) {
|
||||
expect_equal(colnames(pred_contr[[g]]), c(colnames(iris[, -5]), "BIAS"))
|
||||
expect_lt(max(abs(rowSums(pred_contr[[g]]) - pred[, g])), float_tolerance)
|
||||
@@ -223,7 +228,7 @@ if (grepl('Windows', Sys.info()[['sysname']]) ||
|
||||
X <- 10^runif(100, -20, 20)
|
||||
if (capabilities('long.double')) {
|
||||
X2X <- as.numeric(format(X, digits = 17))
|
||||
expect_identical(X, X2X)
|
||||
expect_equal(X, X2X, tolerance = float_tolerance)
|
||||
}
|
||||
# retrieved attributes to be the same as written
|
||||
for (x in X) {
|
||||
@@ -238,12 +243,13 @@ if (grepl('Windows', Sys.info()[['sysname']]) ||
|
||||
test_that("xgb.Booster serializing as R object works", {
|
||||
saveRDS(bst.Tree, 'xgb.model.rds')
|
||||
bst <- readRDS('xgb.model.rds')
|
||||
if (file.exists('xgb.model.rds')) file.remove('xgb.model.rds')
|
||||
dtrain <- xgb.DMatrix(sparse_matrix, label = label)
|
||||
expect_equal(predict(bst.Tree, dtrain), predict(bst, dtrain), tolerance = float_tolerance)
|
||||
expect_equal(xgb.dump(bst.Tree), xgb.dump(bst))
|
||||
xgb.save(bst, 'xgb.model')
|
||||
if (file.exists('xgb.model')) file.remove('xgb.model')
|
||||
bst <- readRDS('xgb.model.rds')
|
||||
if (file.exists('xgb.model.rds')) file.remove('xgb.model.rds')
|
||||
nil_ptr <- new("externalptr")
|
||||
class(nil_ptr) <- "xgb.Booster.handle"
|
||||
expect_true(identical(bst$handle, nil_ptr))
|
||||
@@ -305,7 +311,45 @@ test_that("xgb.importance works with and without feature names", {
|
||||
# for multiclass
|
||||
imp.Tree <- xgb.importance(model = mbst.Tree)
|
||||
expect_equal(dim(imp.Tree), c(4, 4))
|
||||
xgb.importance(model = mbst.Tree, trees = seq(from = 0, by = nclass, length.out = nrounds))
|
||||
|
||||
trees <- seq(from = 0, by = 2, length.out = 2)
|
||||
importance <- xgb.importance(feature_names = feature.names, model = bst.Tree, trees = trees)
|
||||
|
||||
importance_from_dump <- function() {
|
||||
model_text_dump <- xgb.dump(model = bst.Tree, with_stats = TRUE, trees = trees)
|
||||
imp <- xgb.model.dt.tree(
|
||||
feature_names = feature.names,
|
||||
text = model_text_dump,
|
||||
trees = trees
|
||||
)[
|
||||
Feature != "Leaf", .(
|
||||
Gain = sum(Quality),
|
||||
Cover = sum(Cover),
|
||||
Frequency = .N
|
||||
),
|
||||
by = Feature
|
||||
][
|
||||
, `:=`(
|
||||
Gain = Gain / sum(Gain),
|
||||
Cover = Cover / sum(Cover),
|
||||
Frequency = Frequency / sum(Frequency)
|
||||
)
|
||||
][
|
||||
order(Gain, decreasing = TRUE)
|
||||
]
|
||||
imp
|
||||
}
|
||||
expect_equal(importance_from_dump(), importance, tolerance = 1e-6)
|
||||
|
||||
## decision stump
|
||||
m <- xgboost::xgboost(
|
||||
data = as.matrix(data.frame(x = c(0, 1))),
|
||||
label = c(1, 2),
|
||||
nrounds = 1
|
||||
)
|
||||
df <- xgb.model.dt.tree(model = m)
|
||||
expect_equal(df$Feature, "Leaf")
|
||||
expect_equal(df$Cover, 2)
|
||||
})
|
||||
|
||||
test_that("xgb.importance works with GLM model", {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
context('Test prediction of feature interactions')
|
||||
|
||||
require(xgboost)
|
||||
require(magrittr)
|
||||
|
||||
set.seed(123)
|
||||
|
||||
@@ -32,7 +31,7 @@ test_that("predict feature interactions works", {
|
||||
cont <- predict(b, dm, predcontrib = TRUE)
|
||||
expect_equal(dim(cont), c(N, P + 1))
|
||||
# make sure for each row they add up to marginal predictions
|
||||
max(abs(rowSums(cont) - pred)) %>% expect_lt(0.001)
|
||||
expect_lt(max(abs(rowSums(cont) - pred)), 0.001)
|
||||
# Hand-construct the 'ground truth' feature contributions:
|
||||
gt_cont <- cbind(
|
||||
2. * X[, 1],
|
||||
@@ -52,21 +51,24 @@ test_that("predict feature interactions works", {
|
||||
expect_equal(dimnames(intr), list(NULL, cn, cn))
|
||||
|
||||
# check the symmetry
|
||||
max(abs(aperm(intr, c(1, 3, 2)) - intr)) %>% expect_lt(0.00001)
|
||||
expect_lt(max(abs(aperm(intr, c(1, 3, 2)) - intr)), 0.00001)
|
||||
|
||||
# sums WRT columns must be close to feature contributions
|
||||
max(abs(apply(intr, c(1, 2), sum) - cont)) %>% expect_lt(0.00001)
|
||||
expect_lt(max(abs(apply(intr, c(1, 2), sum) - cont)), 0.00001)
|
||||
|
||||
# diagonal terms for features 3,4,5 must be close to zero
|
||||
Reduce(max, sapply(3:P, function(i) max(abs(intr[, i, i])))) %>% expect_lt(0.05)
|
||||
expect_lt(Reduce(max, sapply(3:P, function(i) max(abs(intr[, i, i])))), 0.05)
|
||||
|
||||
# BIAS must have no interactions
|
||||
max(abs(intr[, 1:P, P + 1])) %>% expect_lt(0.00001)
|
||||
expect_lt(max(abs(intr[, 1:P, P + 1])), 0.00001)
|
||||
|
||||
# interactions other than 2 x 3 must be close to zero
|
||||
intr23 <- intr
|
||||
intr23[, 2, 3] <- 0
|
||||
Reduce(max, sapply(1:P, function(i) max(abs(intr23[, i, (i + 1):(P + 1)])))) %>% expect_lt(0.05)
|
||||
expect_lt(
|
||||
Reduce(max, sapply(1:P, function(i) max(abs(intr23[, i, (i + 1):(P + 1)])))),
|
||||
0.05
|
||||
)
|
||||
|
||||
# Construct the 'ground truth' contributions of interactions directly from the linear terms:
|
||||
gt_intr <- array(0, c(N, P + 1, P + 1))
|
||||
@@ -119,23 +121,64 @@ test_that("multiclass feature interactions work", {
|
||||
dm <- xgb.DMatrix(as.matrix(iris[, -5]), label = as.numeric(iris$Species) - 1)
|
||||
param <- list(eta = 0.1, max_depth = 4, objective = 'multi:softprob', num_class = 3)
|
||||
b <- xgb.train(param, dm, 40)
|
||||
pred <- predict(b, dm, outputmargin = TRUE) %>% array(c(3, 150)) %>% t
|
||||
pred <- t(
|
||||
array(
|
||||
data = predict(b, dm, outputmargin = TRUE),
|
||||
dim = c(3, 150)
|
||||
)
|
||||
)
|
||||
|
||||
# SHAP contributions:
|
||||
cont <- predict(b, dm, predcontrib = TRUE)
|
||||
expect_length(cont, 3)
|
||||
# rewrap them as a 3d array
|
||||
cont <- unlist(cont) %>% array(c(150, 5, 3))
|
||||
cont <- array(
|
||||
data = unlist(cont),
|
||||
dim = c(150, 5, 3)
|
||||
)
|
||||
|
||||
# make sure for each row they add up to marginal predictions
|
||||
max(abs(apply(cont, c(1, 3), sum) - pred)) %>% expect_lt(0.001)
|
||||
expect_lt(max(abs(apply(cont, c(1, 3), sum) - pred)), 0.001)
|
||||
|
||||
# SHAP interaction contributions:
|
||||
intr <- predict(b, dm, predinteraction = TRUE)
|
||||
expect_length(intr, 3)
|
||||
# rewrap them as a 4d array
|
||||
intr <- unlist(intr) %>% array(c(150, 5, 5, 3)) %>% aperm(c(4, 1, 2, 3)) # [grp, row, col, col]
|
||||
intr <- aperm(
|
||||
a = array(
|
||||
data = unlist(intr),
|
||||
dim = c(150, 5, 5, 3)
|
||||
),
|
||||
perm = c(4, 1, 2, 3) # [grp, row, col, col]
|
||||
)
|
||||
|
||||
# check the symmetry
|
||||
max(abs(aperm(intr, c(1, 2, 4, 3)) - intr)) %>% expect_lt(0.00001)
|
||||
expect_lt(max(abs(aperm(intr, c(1, 2, 4, 3)) - intr)), 0.00001)
|
||||
# sums WRT columns must be close to feature contributions
|
||||
max(abs(apply(intr, c(1, 2, 3), sum) - aperm(cont, c(3, 1, 2)))) %>% expect_lt(0.00001)
|
||||
expect_lt(max(abs(apply(intr, c(1, 2, 3), sum) - aperm(cont, c(3, 1, 2)))), 0.00001)
|
||||
})
|
||||
|
||||
|
||||
test_that("SHAP single sample works", {
|
||||
train <- agaricus.train
|
||||
test <- agaricus.test
|
||||
booster <- xgboost(
|
||||
data = train$data,
|
||||
label = train$label,
|
||||
max_depth = 2,
|
||||
nrounds = 4,
|
||||
objective = "binary:logistic",
|
||||
)
|
||||
|
||||
predt <- predict(
|
||||
booster,
|
||||
newdata = train$data[1, , drop = FALSE], predcontrib = TRUE
|
||||
)
|
||||
expect_equal(dim(predt), c(1, dim(train$data)[2] + 1))
|
||||
|
||||
predt <- predict(
|
||||
booster,
|
||||
newdata = train$data[1, , drop = FALSE], predinteraction = TRUE
|
||||
)
|
||||
expect_equal(dim(predt), c(1, dim(train$data)[2] + 1, dim(train$data)[2] + 1))
|
||||
})
|
||||
|
||||
30
R-package/tests/testthat/test_io.R
Normal file
30
R-package/tests/testthat/test_io.R
Normal file
@@ -0,0 +1,30 @@
|
||||
context("Test model IO.")
|
||||
## some other tests are in test_basic.R
|
||||
require(xgboost)
|
||||
require(testthat)
|
||||
|
||||
data(agaricus.train, package = "xgboost")
|
||||
data(agaricus.test, package = "xgboost")
|
||||
train <- agaricus.train
|
||||
test <- agaricus.test
|
||||
|
||||
test_that("load/save raw works", {
|
||||
nrounds <- 8
|
||||
booster <- xgboost(
|
||||
data = train$data, label = train$label,
|
||||
nrounds = nrounds, objective = "binary:logistic"
|
||||
)
|
||||
|
||||
json_bytes <- xgb.save.raw(booster, raw_format = "json")
|
||||
ubj_bytes <- xgb.save.raw(booster, raw_format = "ubj")
|
||||
old_bytes <- xgb.save.raw(booster, raw_format = "deprecated")
|
||||
|
||||
from_json <- xgb.load.raw(json_bytes, as_booster = TRUE)
|
||||
from_ubj <- xgb.load.raw(ubj_bytes, as_booster = TRUE)
|
||||
|
||||
json2old <- xgb.save.raw(from_json, raw_format = "deprecated")
|
||||
ubj2old <- xgb.save.raw(from_ubj, raw_format = "deprecated")
|
||||
|
||||
expect_equal(json2old, ubj2old)
|
||||
expect_equal(json2old, old_bytes)
|
||||
})
|
||||
@@ -77,12 +77,14 @@ test_that("Models from previous versions of XGBoost can be loaded", {
|
||||
model_xgb_ver <- m[2]
|
||||
name <- m[3]
|
||||
is_rds <- endsWith(model_file, '.rds')
|
||||
is_json <- endsWith(model_file, '.json')
|
||||
|
||||
cpp_warning <- capture.output({
|
||||
# Expect an R warning when a model is loaded from RDS and it was generated by version < 1.1.x
|
||||
if (is_rds && compareVersion(model_xgb_ver, '1.1.1.1') < 0) {
|
||||
booster <- readRDS(model_file)
|
||||
expect_warning(predict(booster, newdata = pred_data))
|
||||
booster <- readRDS(model_file)
|
||||
expect_warning(run_booster_check(booster, name))
|
||||
} else {
|
||||
if (is_rds) {
|
||||
@@ -94,15 +96,13 @@ test_that("Models from previous versions of XGBoost can be loaded", {
|
||||
run_booster_check(booster, name)
|
||||
}
|
||||
})
|
||||
if (compareVersion(model_xgb_ver, '1.0.0.0') < 0) {
|
||||
# Expect a C++ warning when a model was generated in version < 1.0.x
|
||||
m <- grepl(paste0('.*Loading model from XGBoost < 1\\.0\\.0, consider saving it again for ',
|
||||
'improved compatibility.*'), cpp_warning, perl = TRUE)
|
||||
expect_true(length(m) > 0 && all(m))
|
||||
} else if (is_rds && model_xgb_ver == '1.1.1.1') {
|
||||
# Expect a C++ warning when a model is loaded from RDS and it was generated by version 1.1.x
|
||||
m <- grepl(paste0('.*Attempted to load internal configuration for a model file that was ',
|
||||
'generated by a previous version of XGBoost.*'), cpp_warning, perl = TRUE)
|
||||
cpp_warning <- paste0(cpp_warning, collapse = ' ')
|
||||
if (is_rds && compareVersion(model_xgb_ver, '1.1.1.1') >= 0) {
|
||||
# Expect a C++ warning when a model is loaded from RDS and it was generated by old XGBoost`
|
||||
m <- grepl(paste0('.*If you are loading a serialized model ',
|
||||
'\\(like pickle in Python, RDS in R\\).*',
|
||||
'for more details about differences between ',
|
||||
'saving model and serializing.*'), cpp_warning, perl = TRUE)
|
||||
expect_true(length(m) > 0 && all(m))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -19,5 +19,5 @@ test_that("monotone constraints for regression", {
|
||||
pred.ord <- pred[ind]
|
||||
expect_true({
|
||||
!any(diff(pred.ord) > 0)
|
||||
}, "Monotone Contraint Satisfied")
|
||||
}, "Monotone constraint satisfied")
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
context('Test poisson regression model')
|
||||
context('Test Poisson regression model')
|
||||
|
||||
require(xgboost)
|
||||
set.seed(1994)
|
||||
|
||||
test_that("poisson regression works", {
|
||||
test_that("Poisson regression works", {
|
||||
data(mtcars)
|
||||
bst <- xgboost(data = as.matrix(mtcars[, -11]), label = mtcars[, 11],
|
||||
objective = 'count:poisson', nrounds = 10, verbose = 0)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: "Understand your dataset with Xgboost"
|
||||
title: "Understand your dataset with XGBoost"
|
||||
output:
|
||||
rmarkdown::html_vignette:
|
||||
css: vignette.css
|
||||
@@ -18,9 +18,9 @@ Understand your dataset with XGBoost
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The purpose of this vignette is to show you how to use **Xgboost** to discover and understand your own dataset better.
|
||||
The purpose of this vignette is to show you how to use **XGBoost** to discover and understand your own dataset better.
|
||||
|
||||
This vignette is not about predicting anything (see [Xgboost presentation](https://github.com/dmlc/xgboost/blob/master/R-package/vignettes/xgboostPresentation.Rmd)). We will explain how to use **Xgboost** to highlight the *link* between the *features* of your data and the *outcome*.
|
||||
This vignette is not about predicting anything (see [XGBoost presentation](https://github.com/dmlc/xgboost/blob/master/R-package/vignettes/xgboostPresentation.Rmd)). We will explain how to use **XGBoost** to highlight the *link* between the *features* of your data and the *outcome*.
|
||||
|
||||
Package loading:
|
||||
|
||||
@@ -39,7 +39,7 @@ Preparation of the dataset
|
||||
### Numeric v.s. categorical variables
|
||||
|
||||
|
||||
**Xgboost** manages only `numeric` vectors.
|
||||
**XGBoost** manages only `numeric` vectors.
|
||||
|
||||
What to do when you have *categorical* data?
|
||||
|
||||
@@ -66,7 +66,7 @@ data(Arthritis)
|
||||
df <- data.table(Arthritis, keep.rownames = FALSE)
|
||||
```
|
||||
|
||||
> `data.table` is 100% compliant with **R** `data.frame` but its syntax is more consistent and its performance for large dataset is [best in class](https://stackoverflow.com/questions/21435339/data-table-vs-dplyr-can-one-do-something-well-the-other-cant-or-does-poorly) (`dplyr` from **R** and `Pandas` from **Python** [included](https://github.com/Rdatatable/data.table/wiki/Benchmarks-%3A-Grouping)). Some parts of **Xgboost** **R** package use `data.table`.
|
||||
> `data.table` is 100% compliant with **R** `data.frame` but its syntax is more consistent and its performance for large dataset is [best in class](https://stackoverflow.com/questions/21435339/data-table-vs-dplyr-can-one-do-something-well-the-other-cant-or-does-poorly) (`dplyr` from **R** and `Pandas` from **Python** [included](https://github.com/Rdatatable/data.table/wiki/Benchmarks-%3A-Grouping)). Some parts of **XGBoost** **R** package use `data.table`.
|
||||
|
||||
The first thing we want to do is to have a look to the first few lines of the `data.table`:
|
||||
|
||||
@@ -138,7 +138,7 @@ levels(df[,Treatment])
|
||||
|
||||
Next step, we will transform the categorical data to dummy variables.
|
||||
Several encoding methods exist, e.g., [one-hot encoding](https://en.wikipedia.org/wiki/One-hot) is a common approach.
|
||||
We will use the [dummy contrast coding](https://stats.idre.ucla.edu/r/library/r-library-contrast-coding-systems-for-categorical-variables/) which is popular because it produces "full rank" encoding (also see [this blog post by Max Kuhn](http://appliedpredictivemodeling.com/blog/2013/10/23/the-basics-of-encoding-categorical-data-for-predictive-models)).
|
||||
We will use the [dummy contrast coding](https://stats.oarc.ucla.edu/r/library/r-library-contrast-coding-systems-for-categorical-variables/) which is popular because it produces "full rank" encoding (also see [this blog post by Max Kuhn](http://appliedpredictivemodeling.com/blog/2013/10/23/the-basics-of-encoding-categorical-data-for-predictive-models)).
|
||||
|
||||
The purpose is to transform each value of each *categorical* feature into a *binary* feature `{0, 1}`.
|
||||
|
||||
@@ -166,7 +166,7 @@ output_vector = df[,Improved] == "Marked"
|
||||
Build the model
|
||||
---------------
|
||||
|
||||
The code below is very usual. For more information, you can look at the documentation of `xgboost` function (or at the vignette [Xgboost presentation](https://github.com/dmlc/xgboost/blob/master/R-package/vignettes/xgboostPresentation.Rmd)).
|
||||
The code below is very usual. For more information, you can look at the documentation of `xgboost` function (or at the vignette [XGBoost presentation](https://github.com/dmlc/xgboost/blob/master/R-package/vignettes/xgboostPresentation.Rmd)).
|
||||
|
||||
```{r}
|
||||
bst <- xgboost(data = sparse_matrix, label = output_vector, max_depth = 4,
|
||||
@@ -176,7 +176,7 @@ bst <- xgboost(data = sparse_matrix, label = output_vector, max_depth = 4,
|
||||
|
||||
You can see some `train-error: 0.XXXXX` lines followed by a number. It decreases. Each line shows how well the model explains your data. Lower is better.
|
||||
|
||||
A model which fits too well may [overfit](https://en.wikipedia.org/wiki/Overfitting) (meaning it copy/paste too much the past, and won't be that good to predict the future).
|
||||
A small value for training error may be a symptom of [overfitting](https://en.wikipedia.org/wiki/Overfitting), meaning the model will not accurately predict the future values.
|
||||
|
||||
> Here you can see the numbers decrease until line 7 and then increase.
|
||||
>
|
||||
@@ -304,19 +304,19 @@ Linear model may not be that smart in this scenario.
|
||||
Special Note: What about Random Forests™?
|
||||
-----------------------------------------
|
||||
|
||||
As you may know, [Random Forests™](https://en.wikipedia.org/wiki/Random_forest) algorithm is cousin with boosting and both are part of the [ensemble learning](https://en.wikipedia.org/wiki/Ensemble_learning) family.
|
||||
As you may know, [Random Forests](https://en.wikipedia.org/wiki/Random_forest) algorithm is cousin with boosting and both are part of the [ensemble learning](https://en.wikipedia.org/wiki/Ensemble_learning) family.
|
||||
|
||||
Both trains several decision trees for one dataset. The *main* difference is that in Random Forests™, trees are independent and in boosting, the tree `N+1` focus its learning on the loss (<=> what has not been well modeled by the tree `N`).
|
||||
Both trains several decision trees for one dataset. The *main* difference is that in Random Forests, trees are independent and in boosting, the tree `N+1` focus its learning on the loss (<=> what has not been well modeled by the tree `N`).
|
||||
|
||||
This difference have an impact on a corner case in feature importance analysis: the *correlated features*.
|
||||
|
||||
Imagine two features perfectly correlated, feature `A` and feature `B`. For one specific tree, if the algorithm needs one of them, it will choose randomly (true in both boosting and Random Forests™).
|
||||
Imagine two features perfectly correlated, feature `A` and feature `B`. For one specific tree, if the algorithm needs one of them, it will choose randomly (true in both boosting and Random Forests).
|
||||
|
||||
However, in Random Forests™ this random choice will be done for each tree, because each tree is independent from the others. Therefore, approximatively, depending of your parameters, 50% of the trees will choose feature `A` and the other 50% will choose feature `B`. So the *importance* of the information contained in `A` and `B` (which is the same, because they are perfectly correlated) is diluted in `A` and `B`. So you won't easily know this information is important to predict what you want to predict! It is even worse when you have 10 correlated features...
|
||||
However, in Random Forests this random choice will be done for each tree, because each tree is independent from the others. Therefore, approximatively, depending of your parameters, 50% of the trees will choose feature `A` and the other 50% will choose feature `B`. So the *importance* of the information contained in `A` and `B` (which is the same, because they are perfectly correlated) is diluted in `A` and `B`. So you won't easily know this information is important to predict what you want to predict! It is even worse when you have 10 correlated features...
|
||||
|
||||
In boosting, when a specific link between feature and outcome have been learned by the algorithm, it will try to not refocus on it (in theory it is what happens, reality is not always that simple). Therefore, all the importance will be on feature `A` or on feature `B` (but not both). You will know that one feature have an important role in the link between the observations and the label. It is still up to you to search for the correlated features to the one detected as important if you need to know all of them.
|
||||
|
||||
If you want to try Random Forests™ algorithm, you can tweak Xgboost parameters!
|
||||
If you want to try Random Forests algorithm, you can tweak XGBoost parameters!
|
||||
|
||||
For instance, to compute a model with 1000 trees, with a 0.5 factor on sampling rows and columns:
|
||||
|
||||
@@ -326,7 +326,7 @@ data(agaricus.test, package='xgboost')
|
||||
train <- agaricus.train
|
||||
test <- agaricus.test
|
||||
|
||||
#Random Forest™ - 1000 trees
|
||||
#Random Forest - 1000 trees
|
||||
bst <- xgboost(data = train$data, label = train$label, max_depth = 4, num_parallel_tree = 1000, subsample = 0.5, colsample_bytree =0.5, nrounds = 1, objective = "binary:logistic")
|
||||
|
||||
#Boosting - 3 rounds
|
||||
@@ -335,4 +335,4 @@ bst <- xgboost(data = train$data, label = train$label, max_depth = 4, nrounds =
|
||||
|
||||
> Note that the parameter `round` is set to `1`.
|
||||
|
||||
> [**Random Forests™**](https://www.stat.berkeley.edu/~breiman/RandomForests/cc_papers.htm) is a trademark of Leo Breiman and Adele Cutler and is licensed exclusively to Salford Systems for the commercial release of the software.
|
||||
> [**Random Forests**](https://www.stat.berkeley.edu/~breiman/RandomForests/cc_papers.htm) is a trademark of Leo Breiman and Adele Cutler and is licensed exclusively to Salford Systems for the commercial release of the software.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: "Xgboost presentation"
|
||||
title: "XGBoost presentation"
|
||||
output:
|
||||
rmarkdown::html_vignette:
|
||||
css: vignette.css
|
||||
@@ -8,7 +8,7 @@ output:
|
||||
bibliography: xgboost.bib
|
||||
author: Tianqi Chen, Tong He, Michaël Benesty
|
||||
vignette: >
|
||||
%\VignetteIndexEntry{Xgboost presentation}
|
||||
%\VignetteIndexEntry{XGBoost presentation}
|
||||
%\VignetteEngine{knitr::rmarkdown}
|
||||
\usepackage[utf8]{inputenc}
|
||||
---
|
||||
@@ -19,9 +19,9 @@ XGBoost R Tutorial
|
||||
## Introduction
|
||||
|
||||
|
||||
**Xgboost** is short for e**X**treme **G**radient **Boost**ing package.
|
||||
**XGBoost** is short for e**X**treme **G**radient **Boost**ing package.
|
||||
|
||||
The purpose of this Vignette is to show you how to use **Xgboost** to build a model and make predictions.
|
||||
The purpose of this Vignette is to show you how to use **XGBoost** to build a model and make predictions.
|
||||
|
||||
It is an efficient and scalable implementation of gradient boosting framework by @friedman2000additive and @friedman2001greedy. Two solvers are included:
|
||||
|
||||
@@ -46,10 +46,10 @@ It has several features:
|
||||
## Installation
|
||||
|
||||
|
||||
### Github version
|
||||
### GitHub version
|
||||
|
||||
|
||||
For weekly updated version (highly recommended), install from *Github*:
|
||||
For weekly updated version (highly recommended), install from *GitHub*:
|
||||
|
||||
```{r installGithub, eval=FALSE}
|
||||
install.packages("drat", repos="https://cran.rstudio.com")
|
||||
@@ -82,7 +82,7 @@ require(xgboost)
|
||||
### Dataset presentation
|
||||
|
||||
|
||||
In this example, we are aiming to predict whether a mushroom can be eaten or not (like in many tutorials, example data are the the same as you will use on in your every day life :-).
|
||||
In this example, we are aiming to predict whether a mushroom can be eaten or not (like in many tutorials, example data are the same as you will use on in your every day life :-).
|
||||
|
||||
Mushroom data is cited from UCI Machine Learning Repository. @Bache+Lichman:2013.
|
||||
|
||||
@@ -148,7 +148,7 @@ We will train decision tree model using the following parameters:
|
||||
|
||||
* `objective = "binary:logistic"`: we will train a binary classification model ;
|
||||
* `max_depth = 2`: the trees won't be deep, because our case is very simple ;
|
||||
* `nthread = 2`: the number of cpu threads we are going to use;
|
||||
* `nthread = 2`: the number of CPU threads we are going to use;
|
||||
* `nrounds = 2`: there will be two passes on the data, the second one will enhance the model by further reducing the difference between ground truth and prediction.
|
||||
|
||||
```{r trainingSparse, message=F, warning=F}
|
||||
@@ -180,7 +180,7 @@ bstDMatrix <- xgboost(data = dtrain, max_depth = 2, eta = 1, nthread = 2, nround
|
||||
|
||||
**XGBoost** has several features to help you to view how the learning progress internally. The purpose is to help you to set the best parameters, which is the key of your model quality.
|
||||
|
||||
One of the simplest way to see the training progress is to set the `verbose` option (see below for more advanced technics).
|
||||
One of the simplest way to see the training progress is to set the `verbose` option (see below for more advanced techniques).
|
||||
|
||||
```{r trainingVerbose0, message=T, warning=F}
|
||||
# verbose = 0, no message
|
||||
@@ -253,7 +253,7 @@ The most important thing to remember is that **to do a classification, you just
|
||||
|
||||
*Multiclass* classification works in a similar way.
|
||||
|
||||
This metric is **`r round(err, 2)`** and is pretty low: our yummly mushroom model works well!
|
||||
This metric is **`r round(err, 2)`** and is pretty low: our yummy mushroom model works well!
|
||||
|
||||
## Advanced features
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ XGBoost from JSON
|
||||
|
||||
## Introduction
|
||||
|
||||
The purpose of this Vignette is to show you how to correctly load and work with an **Xgboost** model that has been dumped to JSON. **Xgboost** internally converts all data to [32-bit floats](https://en.wikipedia.org/wiki/Single-precision_floating-point_format), and the values dumped to JSON are decimal representations of these values. When working with a model that has been parsed from a JSON file, care must be taken to correctly treat:
|
||||
The purpose of this Vignette is to show you how to correctly load and work with an **XGBoost** model that has been dumped to JSON. **XGBoost** internally converts all data to [32-bit floats](https://en.wikipedia.org/wiki/Single-precision_floating-point_format), and the values dumped to JSON are decimal representations of these values. When working with a model that has been parsed from a JSON file, care must be taken to correctly treat:
|
||||
|
||||
- the input data, which should be converted to 32-bit floats
|
||||
- any 32-bit floats that were stored in JSON as decimal representations
|
||||
@@ -172,9 +172,9 @@ bst_from_json_preds <- ifelse(fl(data$dates)<fl(node$split_condition),
|
||||
bst_preds == bst_from_json_preds
|
||||
```
|
||||
|
||||
None are exactly equal again. What is going on here? Well, since we are using the value `1` in the calcuations, we have introduced a double into the calculation. Because of this, all float values are promoted to 64-bit doubles and the 64-bit version of the exponentiation operator `exp` is also used. On the other hand, xgboost uses the 32-bit version of the exponentation operator in its [sigmoid function](https://github.com/dmlc/xgboost/blob/54980b8959680a0da06a3fc0ec776e47c8cbb0a1/src/common/math.h#L25-L27).
|
||||
None are exactly equal again. What is going on here? Well, since we are using the value `1` in the calculations, we have introduced a double into the calculation. Because of this, all float values are promoted to 64-bit doubles and the 64-bit version of the exponentiation operator `exp` is also used. On the other hand, xgboost uses the 32-bit version of the exponentiation operator in its [sigmoid function](https://github.com/dmlc/xgboost/blob/54980b8959680a0da06a3fc0ec776e47c8cbb0a1/src/common/math.h#L25-L27).
|
||||
|
||||
How do we fix this? We have to ensure we use the correct datatypes everywhere and the correct operators. If we use only floats, the float library that we have loaded will ensure the 32-bit float exponention operator is applied.
|
||||
How do we fix this? We have to ensure we use the correct data types everywhere and the correct operators. If we use only floats, the float library that we have loaded will ensure the 32-bit float exponentiation operator is applied.
|
||||
```{r}
|
||||
# calculate the predictions casting doubles to floats
|
||||
bst_from_json_preds <- ifelse(fl(data$dates)<fl(node$split_condition),
|
||||
|
||||
21
README.md
21
README.md
@@ -2,7 +2,6 @@
|
||||
===========
|
||||
[](https://xgboost-ci.net/blue/organizations/jenkins/xgboost/activity)
|
||||
[](https://travis-ci.org/dmlc/xgboost)
|
||||
[](https://ci.appveyor.com/project/tqchen/xgboost)
|
||||
[](https://github.com/dmlc/xgboost/actions)
|
||||
[](https://xgboost.readthedocs.org)
|
||||
[](./LICENSE)
|
||||
@@ -11,6 +10,7 @@
|
||||
[](https://anaconda.org/conda-forge/py-xgboost)
|
||||
[](https://optuna.org)
|
||||
[](https://twitter.com/XGBoostProject)
|
||||
[](https://api.securityscorecards.dev/projects/github.com/dmlc/xgboost)
|
||||
|
||||
[Community](https://xgboost.ai/community) |
|
||||
[Documentation](https://xgboost.readthedocs.org) |
|
||||
@@ -25,7 +25,7 @@ The same code runs on major distributed environment (Kubernetes, Hadoop, SGE, MP
|
||||
|
||||
License
|
||||
-------
|
||||
© Contributors, 2019. Licensed under an [Apache-2](https://github.com/dmlc/xgboost/blob/master/LICENSE) license.
|
||||
© Contributors, 2021. Licensed under an [Apache-2](https://github.com/dmlc/xgboost/blob/master/LICENSE) license.
|
||||
|
||||
Contribute to XGBoost
|
||||
---------------------
|
||||
@@ -47,24 +47,11 @@ Become a sponsor and get a logo here. See details at [Sponsoring the XGBoost Pro
|
||||
### Sponsors
|
||||
[[Become a sponsor](https://opencollective.com/xgboost#sponsor)]
|
||||
|
||||
<!--<a href="https://opencollective.com/xgboost/sponsor/0/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/0/avatar.svg"></a>-->
|
||||
<a href="https://www.nvidia.com/en-us/" target="_blank"><img src="https://raw.githubusercontent.com/xgboost-ai/xgboost-ai.github.io/master/images/sponsors/nvidia.jpg" alt="NVIDIA" width="72" height="72"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/1/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/2/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/3/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/4/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/5/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/6/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/7/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/8/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/xgboost/sponsor/9/website" target="_blank"><img src="https://opencollective.com/xgboost/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://www.intel.com/" target="_blank"><img src="https://images.opencollective.com/intel-corporation/2fa85c1/logo/256.png" width="72" height="72"></a>
|
||||
<a href="https://getkoffie.com/?utm_source=opencollective&utm_medium=github&utm_campaign=xgboost" target="_blank"><img src="https://images.opencollective.com/koffielabs/f391ab8/logo/256.png" width="72" height="72"></a>
|
||||
|
||||
### Backers
|
||||
[[Become a backer](https://opencollective.com/xgboost#backer)]
|
||||
|
||||
<a href="https://opencollective.com/xgboost#backers" target="_blank"><img src="https://opencollective.com/xgboost/backers.svg?width=890"></a>
|
||||
|
||||
## Other sponsors
|
||||
The sponsors in this list are donating cloud hours in lieu of cash donation.
|
||||
|
||||
<a href="https://aws.amazon.com/" target="_blank"><img src="https://raw.githubusercontent.com/xgboost-ai/xgboost-ai.github.io/master/images/sponsors/aws.png" alt="Amazon Web Services" width="72" height="72"></a>
|
||||
|
||||
22
SECURITY.md
Normal file
22
SECURITY.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
<!-- Use this section to tell people about which versions of your project are
|
||||
currently being supported with security updates. -->
|
||||
Security updates are applied only to the most recent release.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
<!-- Use this section to tell people how to report a vulnerability.
|
||||
|
||||
Tell them where to go, how often they can expect to get an update on a
|
||||
reported vulnerability, what to expect if the vulnerability is accepted or
|
||||
declined, etc. -->
|
||||
|
||||
To report a security issue, please email
|
||||
[security@xgboost-ci.net](mailto:security@xgboost-ci.net)
|
||||
with a description of the issue, the steps you took to create the issue,
|
||||
affected versions, and, if known, mitigations for the issue.
|
||||
|
||||
All support will be made on the best effort base, so please indicate the "urgency level" of the vulnerability as Critical, High, Medium or Low.
|
||||
@@ -1,86 +0,0 @@
|
||||
/*!
|
||||
* Copyright 2015-2019 by Contributors.
|
||||
* \brief XGBoost Amalgamation.
|
||||
* This offers an alternative way to compile the entire library from this single file.
|
||||
*
|
||||
* Example usage command.
|
||||
* - $(CXX) -std=c++0x -fopenmp -o -shared libxgboost.so xgboost-all0.cc -ldmlc -lrabit
|
||||
*
|
||||
* \author Tianqi Chen.
|
||||
*/
|
||||
|
||||
// metrics
|
||||
#include "../src/metric/metric.cc"
|
||||
#include "../src/metric/elementwise_metric.cc"
|
||||
#include "../src/metric/multiclass_metric.cc"
|
||||
#include "../src/metric/rank_metric.cc"
|
||||
#include "../src/metric/auc.cc"
|
||||
#include "../src/metric/survival_metric.cc"
|
||||
|
||||
// objectives
|
||||
#include "../src/objective/objective.cc"
|
||||
#include "../src/objective/regression_obj.cc"
|
||||
#include "../src/objective/multiclass_obj.cc"
|
||||
#include "../src/objective/rank_obj.cc"
|
||||
#include "../src/objective/hinge.cc"
|
||||
#include "../src/objective/aft_obj.cc"
|
||||
|
||||
// gbms
|
||||
#include "../src/gbm/gbm.cc"
|
||||
#include "../src/gbm/gbtree.cc"
|
||||
#include "../src/gbm/gbtree_model.cc"
|
||||
#include "../src/gbm/gblinear.cc"
|
||||
#include "../src/gbm/gblinear_model.cc"
|
||||
|
||||
// data
|
||||
#include "../src/data/data.cc"
|
||||
#include "../src/data/simple_dmatrix.cc"
|
||||
#include "../src/data/sparse_page_raw_format.cc"
|
||||
#include "../src/data/ellpack_page.cc"
|
||||
#include "../src/data/ellpack_page_source.cc"
|
||||
|
||||
// prediction
|
||||
#include "../src/predictor/predictor.cc"
|
||||
#include "../src/predictor/cpu_predictor.cc"
|
||||
|
||||
#if DMLC_ENABLE_STD_THREAD
|
||||
#include "../src/data/sparse_page_dmatrix.cc"
|
||||
#include "../src/data/sparse_page_source.cc"
|
||||
#endif
|
||||
|
||||
// trees
|
||||
#include "../src/tree/param.cc"
|
||||
#include "../src/tree/tree_model.cc"
|
||||
#include "../src/tree/tree_updater.cc"
|
||||
#include "../src/tree/updater_colmaker.cc"
|
||||
#include "../src/tree/updater_quantile_hist.cc"
|
||||
#include "../src/tree/updater_prune.cc"
|
||||
#include "../src/tree/updater_refresh.cc"
|
||||
#include "../src/tree/updater_sync.cc"
|
||||
#include "../src/tree/updater_histmaker.cc"
|
||||
#include "../src/tree/constraints.cc"
|
||||
|
||||
// linear
|
||||
#include "../src/linear/linear_updater.cc"
|
||||
#include "../src/linear/updater_coordinate.cc"
|
||||
#include "../src/linear/updater_shotgun.cc"
|
||||
|
||||
// global
|
||||
#include "../src/learner.cc"
|
||||
#include "../src/logging.cc"
|
||||
#include "../src/global_config.cc"
|
||||
#include "../src/common/common.cc"
|
||||
#include "../src/common/random.cc"
|
||||
#include "../src/common/charconv.cc"
|
||||
#include "../src/common/timer.cc"
|
||||
#include "../src/common/quantile.cc"
|
||||
#include "../src/common/host_device_vector.cc"
|
||||
#include "../src/common/hist_util.cc"
|
||||
#include "../src/common/json.cc"
|
||||
#include "../src/common/io.cc"
|
||||
#include "../src/common/survival_util.cc"
|
||||
#include "../src/common/version.cc"
|
||||
|
||||
// c_api
|
||||
#include "../src/c_api/c_api.cc"
|
||||
#include "../src/c_api/c_api_error.cc"
|
||||
71
appveyor.yml
71
appveyor.yml
@@ -1,71 +0,0 @@
|
||||
environment:
|
||||
matrix:
|
||||
- target: msvc
|
||||
ver: 2015
|
||||
generator: "Visual Studio 14 2015 Win64"
|
||||
configuration: Debug
|
||||
- target: msvc
|
||||
ver: 2015
|
||||
generator: "Visual Studio 14 2015 Win64"
|
||||
configuration: Release
|
||||
- target: mingw
|
||||
generator: "Unix Makefiles"
|
||||
|
||||
#matrix:
|
||||
# fast_finish: true
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
install:
|
||||
- git submodule update --init --recursive
|
||||
# MinGW
|
||||
- set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%
|
||||
- gcc -v
|
||||
- ls -l C:\
|
||||
# Miniconda3
|
||||
- call C:\Miniconda3-x64\Scripts\activate.bat
|
||||
- conda info
|
||||
- where python
|
||||
- python --version
|
||||
# do python build for mingw and one of the msvc jobs
|
||||
- set DO_PYTHON=off
|
||||
- if /i "%target%" == "mingw" set DO_PYTHON=on
|
||||
- if /i "%target%_%ver%_%configuration%" == "msvc_2015_Release" set DO_PYTHON=on
|
||||
- if /i "%DO_PYTHON%" == "on" (
|
||||
conda config --set always_yes true &&
|
||||
conda update -q conda &&
|
||||
conda install -y numpy scipy pandas matplotlib pytest scikit-learn graphviz python-graphviz hypothesis
|
||||
)
|
||||
- set PATH=C:\Miniconda3-x64\Library\bin\graphviz;%PATH%
|
||||
|
||||
build_script:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%
|
||||
- if /i "%target%" == "msvc" (
|
||||
mkdir build_msvc%ver% &&
|
||||
cd build_msvc%ver% &&
|
||||
cmake .. -G"%generator%" -DCMAKE_CONFIGURATION_TYPES="Release;Debug;" &&
|
||||
msbuild xgboost.sln
|
||||
)
|
||||
- if /i "%target%" == "mingw" (
|
||||
mkdir build_mingw &&
|
||||
cd build_mingw &&
|
||||
cmake .. -G"%generator%" &&
|
||||
make -j2
|
||||
)
|
||||
# Python package
|
||||
- if /i "%DO_PYTHON%" == "on" (
|
||||
cd %APPVEYOR_BUILD_FOLDER%\python-package &&
|
||||
python setup.py install &&
|
||||
mkdir wheel &&
|
||||
python setup.py bdist_wheel --universal --plat-name win-amd64 -d wheel
|
||||
)
|
||||
|
||||
test_script:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%
|
||||
- if /i "%DO_PYTHON%" == "on" python -m pytest tests/python
|
||||
|
||||
artifacts:
|
||||
# binary Python wheel package
|
||||
- path: '**\*.whl'
|
||||
name: Bits
|
||||
@@ -27,7 +27,7 @@ file(WRITE "${build_dir}/R-package/src/Makevars.win" "all:")
|
||||
|
||||
# Install dependencies
|
||||
set(XGB_DEPS_SCRIPT
|
||||
"deps = setdiff(c('data.table', 'magrittr', 'stringi'), rownames(installed.packages())); if(length(deps)>0) install.packages(deps, repo = 'https://cloud.r-project.org/')")
|
||||
"deps = setdiff(c('data.table', 'jsonlite', 'Matrix'), rownames(installed.packages())); if(length(deps)>0) install.packages(deps, repo = 'https://cloud.r-project.org/')")
|
||||
check_call(COMMAND "${LIBR_EXECUTABLE}" -q -e "${XGB_DEPS_SCRIPT}")
|
||||
|
||||
# Install the XGBoost R package
|
||||
|
||||
@@ -15,7 +15,7 @@ endfunction(auto_source_group)
|
||||
|
||||
# Force static runtime for MSVC
|
||||
function(msvc_use_static_runtime)
|
||||
if(MSVC)
|
||||
if(MSVC AND (NOT BUILD_SHARED_LIBS) AND (NOT FORCE_SHARED_CRT))
|
||||
set(variables
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
@@ -90,22 +90,25 @@ function(format_gencode_flags flags out)
|
||||
endif()
|
||||
# Set up architecture flags
|
||||
if(NOT flags)
|
||||
if (CUDA_VERSION VERSION_GREATER_EQUAL "11.0")
|
||||
set(flags "35;50;52;60;61;70;75;80")
|
||||
if (CUDA_VERSION VERSION_GREATER_EQUAL "11.1")
|
||||
set(flags "50;60;70;80")
|
||||
elseif (CUDA_VERSION VERSION_GREATER_EQUAL "11.0")
|
||||
set(flags "50;60;70;80")
|
||||
elseif(CUDA_VERSION VERSION_GREATER_EQUAL "10.0")
|
||||
set(flags "35;50;52;60;61;70;75")
|
||||
set(flags "35;50;60;70")
|
||||
elseif(CUDA_VERSION VERSION_GREATER_EQUAL "9.0")
|
||||
set(flags "35;50;52;60;61;70")
|
||||
set(flags "35;50;60;70")
|
||||
else()
|
||||
set(flags "35;50;52;60;61")
|
||||
set(flags "35;50;60")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.18")
|
||||
cmake_policy(SET CMP0104 NEW)
|
||||
foreach(ver ${flags})
|
||||
set(CMAKE_CUDA_ARCHITECTURES "${ver}-real;${ver}-virtual;${CMAKE_CUDA_ARCHITECTURES}")
|
||||
endforeach()
|
||||
list(GET flags -1 latest_arch)
|
||||
list(TRANSFORM flags APPEND "-real")
|
||||
list(APPEND flags ${latest_arch})
|
||||
set(CMAKE_CUDA_ARCHITECTURES ${flags})
|
||||
set(CMAKE_CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES}" PARENT_SCOPE)
|
||||
message(STATUS "CMAKE_CUDA_ARCHITECTURES: ${CMAKE_CUDA_ARCHITECTURES}")
|
||||
else()
|
||||
@@ -130,19 +133,26 @@ endmacro()
|
||||
|
||||
# Set CUDA related flags to target. Must be used after code `format_gencode_flags`.
|
||||
function(xgboost_set_cuda_flags target)
|
||||
find_package(OpenMP REQUIRED)
|
||||
target_link_libraries(${target} PUBLIC OpenMP::OpenMP_CXX)
|
||||
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:--expt-extended-lambda>
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:--expt-relaxed-constexpr>
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:${GEN_CODE}>
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${OpenMP_CXX_FLAGS}>)
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${OpenMP_CXX_FLAGS}>
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:-Xfatbin=-compress-all>)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.18")
|
||||
set_property(TARGET ${target} PROPERTY CUDA_ARCHITECTURES ${CMAKE_CUDA_ARCHITECTURES})
|
||||
endif (CMAKE_VERSION VERSION_GREATER_EQUAL "3.18")
|
||||
|
||||
if (FORCE_COLORED_OUTPUT)
|
||||
if (FORCE_COLORED_OUTPUT AND (CMAKE_GENERATOR STREQUAL "Ninja") AND
|
||||
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")))
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-fdiagnostics-color=always>)
|
||||
endif()
|
||||
endif (FORCE_COLORED_OUTPUT)
|
||||
|
||||
if (USE_DEVICE_DEBUG)
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<AND:$<CONFIG:DEBUG>,$<COMPILE_LANGUAGE:CUDA>>:-G;-src-in-ptx>)
|
||||
@@ -155,28 +165,157 @@ function(xgboost_set_cuda_flags target)
|
||||
enable_nvtx(${target})
|
||||
endif (USE_NVTX)
|
||||
|
||||
target_compile_definitions(${target} PRIVATE -DXGBOOST_USE_CUDA=1 -DTHRUST_IGNORE_CUB_VERSION_CHECK=1)
|
||||
target_include_directories(${target} PRIVATE ${xgboost_SOURCE_DIR}/cub/)
|
||||
if (NOT BUILD_WITH_CUDA_CUB)
|
||||
target_compile_definitions(${target} PRIVATE -DXGBOOST_USE_CUDA=1 -DTHRUST_IGNORE_CUB_VERSION_CHECK=1)
|
||||
target_include_directories(${target} PRIVATE ${xgboost_SOURCE_DIR}/cub/ ${xgboost_SOURCE_DIR}/gputreeshap)
|
||||
else ()
|
||||
target_compile_definitions(${target} PRIVATE -DXGBOOST_USE_CUDA=1)
|
||||
target_include_directories(${target} PRIVATE ${xgboost_SOURCE_DIR}/gputreeshap)
|
||||
endif (NOT BUILD_WITH_CUDA_CUB)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/utf-8>)
|
||||
endif (MSVC)
|
||||
|
||||
set_target_properties(${target} PROPERTIES
|
||||
CUDA_STANDARD 14
|
||||
CUDA_STANDARD_REQUIRED ON
|
||||
CUDA_SEPARABLE_COMPILATION OFF)
|
||||
if (PLUGIN_RMM)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
CUDA_STANDARD 17
|
||||
CUDA_STANDARD_REQUIRED ON
|
||||
CUDA_SEPARABLE_COMPILATION OFF)
|
||||
else ()
|
||||
set_target_properties(${target} PROPERTIES
|
||||
CUDA_STANDARD 14
|
||||
CUDA_STANDARD_REQUIRED ON
|
||||
CUDA_SEPARABLE_COMPILATION OFF)
|
||||
endif (PLUGIN_RMM)
|
||||
endfunction(xgboost_set_cuda_flags)
|
||||
|
||||
if (HIDE_CXX_SYMBOLS)
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-fvisibility=hidden>)
|
||||
endif (HIDE_CXX_SYMBOLS)
|
||||
|
||||
if (USE_NCCL)
|
||||
find_package(Nccl REQUIRED)
|
||||
macro(xgboost_link_nccl target)
|
||||
if (BUILD_STATIC_LIB)
|
||||
target_include_directories(${target} PUBLIC ${NCCL_INCLUDE_DIR})
|
||||
target_compile_definitions(${target} PUBLIC -DXGBOOST_USE_NCCL=1)
|
||||
target_link_libraries(${target} PUBLIC ${NCCL_LIBRARY})
|
||||
else ()
|
||||
target_include_directories(${target} PRIVATE ${NCCL_INCLUDE_DIR})
|
||||
target_compile_definitions(${target} PRIVATE -DXGBOOST_USE_NCCL=1)
|
||||
target_link_libraries(${target} PUBLIC ${NCCL_LIBRARY})
|
||||
target_link_libraries(${target} PRIVATE ${NCCL_LIBRARY})
|
||||
endif (BUILD_STATIC_LIB)
|
||||
endmacro(xgboost_link_nccl)
|
||||
|
||||
# compile options
|
||||
macro(xgboost_target_properties target)
|
||||
if (PLUGIN_RMM)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
else ()
|
||||
set_target_properties(${target} PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
endif (PLUGIN_RMM)
|
||||
|
||||
if (HIDE_CXX_SYMBOLS)
|
||||
#-- Hide all C++ symbols
|
||||
set_target_properties(${target} PROPERTIES
|
||||
C_VISIBILITY_PRESET hidden
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
CUDA_VISIBILITY_PRESET hidden
|
||||
)
|
||||
endif (HIDE_CXX_SYMBOLS)
|
||||
|
||||
if (ENABLE_ALL_WARNINGS)
|
||||
target_compile_options(${target} PUBLIC
|
||||
$<IF:$<COMPILE_LANGUAGE:CUDA>,
|
||||
-Xcompiler=-Wall -Xcompiler=-Wextra -Xcompiler=-Wno-expansion-to-defined,
|
||||
-Wall -Wextra -Wno-expansion-to-defined>
|
||||
)
|
||||
endif(ENABLE_ALL_WARNINGS)
|
||||
|
||||
target_compile_options(${target}
|
||||
PRIVATE
|
||||
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<COMPILE_LANGUAGE:CXX>>:/MP>
|
||||
$<$<AND:$<NOT:$<CXX_COMPILER_ID:MSVC>>,$<COMPILE_LANGUAGE:CXX>>:-funroll-loops>)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<NOT:$<COMPILE_LANGUAGE:CUDA>>:/utf-8>
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-D_CRT_SECURE_NO_DEPRECATE
|
||||
)
|
||||
endif (MSVC)
|
||||
|
||||
if (WIN32 AND MINGW)
|
||||
target_compile_options(${target} PUBLIC -static-libstdc++)
|
||||
endif (WIN32 AND MINGW)
|
||||
endmacro(xgboost_target_properties)
|
||||
|
||||
# Custom definitions used in xgboost.
|
||||
macro(xgboost_target_defs target)
|
||||
if (NOT ${target} STREQUAL "dmlc") # skip dmlc core for custom logging.
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE
|
||||
-DDMLC_LOG_CUSTOMIZE=1
|
||||
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:_MWAITXINTRIN_H_INCLUDED>)
|
||||
endif ()
|
||||
if (USE_DEBUG_OUTPUT)
|
||||
target_compile_definitions(${target} PRIVATE -DXGBOOST_USE_DEBUG_OUTPUT=1)
|
||||
endif (USE_DEBUG_OUTPUT)
|
||||
if (XGBOOST_MM_PREFETCH_PRESENT)
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE
|
||||
-DXGBOOST_MM_PREFETCH_PRESENT=1)
|
||||
endif(XGBOOST_MM_PREFETCH_PRESENT)
|
||||
if (XGBOOST_BUILTIN_PREFETCH_PRESENT)
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE
|
||||
-DXGBOOST_BUILTIN_PREFETCH_PRESENT=1)
|
||||
endif (XGBOOST_BUILTIN_PREFETCH_PRESENT)
|
||||
|
||||
if (PLUGIN_RMM)
|
||||
target_compile_definitions(objxgboost PUBLIC -DXGBOOST_USE_RMM=1)
|
||||
endif (PLUGIN_RMM)
|
||||
endmacro(xgboost_target_defs)
|
||||
|
||||
# handles dependencies
|
||||
macro(xgboost_target_link_libraries target)
|
||||
if (BUILD_STATIC_LIB)
|
||||
target_link_libraries(${target} PUBLIC Threads::Threads ${CMAKE_THREAD_LIBS_INIT})
|
||||
else()
|
||||
target_link_libraries(${target} PRIVATE Threads::Threads ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif (BUILD_STATIC_LIB)
|
||||
|
||||
if (USE_OPENMP)
|
||||
if (BUILD_STATIC_LIB)
|
||||
target_link_libraries(${target} PUBLIC OpenMP::OpenMP_CXX)
|
||||
else()
|
||||
target_link_libraries(${target} PRIVATE OpenMP::OpenMP_CXX)
|
||||
endif (BUILD_STATIC_LIB)
|
||||
endif (USE_OPENMP)
|
||||
|
||||
if (USE_CUDA)
|
||||
xgboost_set_cuda_flags(${target})
|
||||
endif (USE_CUDA)
|
||||
|
||||
if (PLUGIN_RMM)
|
||||
target_link_libraries(${target} PRIVATE rmm::rmm)
|
||||
endif (PLUGIN_RMM)
|
||||
|
||||
if (USE_NCCL)
|
||||
xgboost_link_nccl(${target})
|
||||
endif (USE_NCCL)
|
||||
endfunction(xgboost_set_cuda_flags)
|
||||
|
||||
if (USE_NVTX)
|
||||
enable_nvtx(${target})
|
||||
endif (USE_NVTX)
|
||||
|
||||
if (RABIT_BUILD_MPI)
|
||||
target_link_libraries(${target} PRIVATE MPI::MPI_CXX)
|
||||
endif (RABIT_BUILD_MPI)
|
||||
|
||||
if (MINGW)
|
||||
target_link_libraries(${target} PRIVATE wsock32 ws2_32)
|
||||
endif (MINGW)
|
||||
endmacro(xgboost_target_link_libraries)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
# NCCL_INCLUDE_DIR, directory containing header
|
||||
# NCCL_LIBRARY, directory containing nccl library
|
||||
# NCCL_LIB_NAME, nccl library name
|
||||
# USE_NCCL_LIB_PATH, when set, NCCL_LIBRARY path is also inspected for the
|
||||
# USE_NCCL_LIB_PATH, when set, NCCL_LIBRARY path is also inspected for the
|
||||
# location of the nccl library. This would disable
|
||||
# switching between static and shared.
|
||||
#
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
set(USE_OPENMP @USE_OPENMP@)
|
||||
set(USE_CUDA @USE_CUDA@)
|
||||
set(USE_NCCL @USE_NCCL@)
|
||||
set(XGBOOST_BUILD_STATIC_LIB @BUILD_STATIC_LIB@)
|
||||
|
||||
find_dependency(Threads)
|
||||
if(USE_OPENMP)
|
||||
find_dependency(OpenMP)
|
||||
endif()
|
||||
if(USE_CUDA)
|
||||
find_dependency(CUDA)
|
||||
endif()
|
||||
if(USE_NCCL)
|
||||
find_dependency(Nccl)
|
||||
endif()
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
if (XGBOOST_BUILD_STATIC_LIB)
|
||||
find_dependency(Threads)
|
||||
if(USE_OPENMP)
|
||||
find_dependency(OpenMP)
|
||||
endif()
|
||||
if(USE_CUDA)
|
||||
find_dependency(CUDA)
|
||||
endif()
|
||||
# nccl should be linked statically if xgboost is built as static library.
|
||||
endif (XGBOOST_BUILD_STATIC_LIB)
|
||||
|
||||
if(NOT TARGET xgboost::xgboost)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/XGBoostTargets.cmake)
|
||||
|
||||
@@ -6,7 +6,7 @@ The script 'runexp.sh' can be used to run the demo. Here we use [mushroom datase
|
||||
|
||||
### Tutorial
|
||||
#### Generate Input Data
|
||||
XGBoost takes LibSVM format. An example of faked input data is below:
|
||||
XGBoost takes LIBSVM format. An example of faked input data is below:
|
||||
```
|
||||
1 101:1.2 102:0.03
|
||||
0 1:2.1 10001:300 10002:400
|
||||
@@ -15,7 +15,7 @@ XGBoost takes LibSVM format. An example of faked input data is below:
|
||||
Each line represent a single instance, and in the first line '1' is the instance label,'101' and '102' are feature indices, '1.2' and '0.03' are feature values. In the binary classification case, '1' is used to indicate positive samples, and '0' is used to indicate negative samples. We also support probability values in [0,1] as label, to indicate the probability of the instance being positive.
|
||||
|
||||
|
||||
First we will transform the dataset into classic LibSVM format and split the data into training set and test set by running:
|
||||
First we will transform the dataset into classic LIBSVM format and split the data into training set and test set by running:
|
||||
```
|
||||
python mapfeat.py
|
||||
python mknfold.py agaricus.txt 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
def loadfmap( fname ):
|
||||
fmap = {}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user