Compare commits
1689 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
a59c7323b4 | ||
|
|
5c87c2bba8 | ||
|
|
8825670c9c | ||
|
|
744c46995c | ||
|
|
a7083d3c13 | ||
|
|
1d90577800 | ||
|
|
794fd6a46b | ||
|
|
bcc0277338 | ||
|
|
4ee8340e79 | ||
|
|
f6fe15d11f | ||
|
|
23b4165a6b | ||
|
|
c2b6b80600 | ||
|
|
642336add7 | ||
|
|
4230dcb614 | ||
|
|
e2d8a99413 | ||
|
|
4e00737c60 | ||
|
|
4f75f514ce | ||
|
|
1a73a28511 | ||
|
|
325bc93e16 | ||
|
|
19a2c54265 | ||
|
|
366f3cb9d8 | ||
|
|
e4894111ba | ||
|
|
49c22c23b4 | ||
|
|
5ae7f9944b | ||
|
|
f20074e826 | ||
|
|
a9b4a95225 | ||
|
|
9c8523432a | ||
|
|
1fa6793a4e | ||
|
|
9da2287ab8 | ||
|
|
b6167cd2ff | ||
|
|
9b530e5697 | ||
|
|
c375173dca | ||
|
|
17913713b5 | ||
|
|
872e559b91 | ||
|
|
25077564ab | ||
|
|
bdedaab8d1 | ||
|
|
9f15b9e322 | ||
|
|
dc97b5f19f | ||
|
|
4c5d2608e0 | ||
|
|
9a0399e898 | ||
|
|
9b267a435e | ||
|
|
e8c5c53e2f | ||
|
|
dbf7e9d3cb | ||
|
|
1335db6113 | ||
|
|
5d48d40d9a | ||
|
|
218a5fb6dd | ||
|
|
4656b09d5d | ||
|
|
dbb5208a0a | ||
|
|
1e949110da | ||
|
|
a4101de678 | ||
|
|
72892cc80d | ||
|
|
9d62b14591 | ||
|
|
411592a347 | ||
|
|
87ab1ad607 | ||
|
|
a9ec0ea6da | ||
|
|
d8ec7aad5a | ||
|
|
c3c8e66fc9 | ||
|
|
0f2ed21a9d | ||
|
|
d167892c7e | ||
|
|
0ad6e18a2a | ||
|
|
55ee2bd77f | ||
|
|
1b70a323a7 | ||
|
|
bc08e0c9d1 | ||
|
|
8968ca7c0a | ||
|
|
d19a0ddacf | ||
|
|
740d042255 | ||
|
|
4bf23c2391 | ||
|
|
8942c98054 | ||
|
|
561809200a | ||
|
|
fec66d033a | ||
|
|
a275f40267 | ||
|
|
7bc56fa0ed | ||
|
|
26982f9fce | ||
|
|
f0fd7629ae | ||
|
|
9d2832a3a3 | ||
|
|
f8bb678c67 | ||
|
|
d6d72de339 | ||
|
|
d132933550 | ||
|
|
d356b7a071 | ||
|
|
89a00a5866 | ||
|
|
0027220aa0 | ||
|
|
7f4d3a91b9 | ||
|
|
03cd087da1 | ||
|
|
c709f2aaaf | ||
|
|
f2f7dd87b8 | ||
|
|
78f2cd83d7 | ||
|
|
80065d571e | ||
|
|
96d3d32265 | ||
|
|
7c9dcbedbc | ||
|
|
f5ff90cd87 | ||
|
|
8747885a8b | ||
|
|
b2246ae7ef | ||
|
|
60cfd14349 | ||
|
|
516a93d25c | ||
|
|
195a41cef1 | ||
|
|
2b049b32e9 | ||
|
|
fa13992264 | ||
|
|
5e9e525223 | ||
|
|
8ad22bf4e7 | ||
|
|
de8fd852a5 | ||
|
|
610ee632cc | ||
|
|
cb207a355d | ||
|
|
2231940d1d | ||
|
|
95cbfad990 | ||
|
|
fbb980d9d3 | ||
|
|
cd0821500c | ||
|
|
380f6f4ab8 | ||
|
|
ca3da55de4 | ||
|
|
125b3c0f2d | ||
|
|
ad1a527709 | ||
|
|
bf6cfe3b99 | ||
|
|
d8d684538c | ||
|
|
c5876277a8 | ||
|
|
0e97d97d50 | ||
|
|
749364f25d | ||
|
|
347f593169 | ||
|
|
ef4a0e0aac | ||
|
|
886486a519 | ||
|
|
5c8ccf4455 | ||
|
|
3c3f026ec1 | ||
|
|
d45c0d843b | ||
|
|
1e2c3ade9e | ||
|
|
8139849ab6 | ||
|
|
9a194273cd | ||
|
|
aac4eba2ef | ||
|
|
afc4567268 | ||
|
|
a30461cf87 | ||
|
|
c31e3efa7c | ||
|
|
0d483cb7c1 | ||
|
|
b8044e6136 | ||
|
|
0ffaf0f5be | ||
|
|
47b86180f6 | ||
|
|
55bdf084cb | ||
|
|
703c2d06aa | ||
|
|
d6386e45e8 | ||
|
|
05e5563c2c | ||
|
|
84b726ef53 | ||
|
|
c103ec51d8 | ||
|
|
4f70e14031 | ||
|
|
fb56da5e8b | ||
|
|
c2ba4fb957 | ||
|
|
927c316aeb | ||
|
|
f4ff1c53fd | ||
|
|
b0036b339b | ||
|
|
956beead70 | ||
|
|
4dbbeb635d | ||
|
|
0c85b90671 | ||
|
|
42d31d9dcb | ||
|
|
2ce2a1a4d8 | ||
|
|
cc581b3b6b | ||
|
|
00218d065a | ||
|
|
c120822a24 | ||
|
|
a7b42adb74 | ||
|
|
44a9d69efb | ||
|
|
9c9070aea2 | ||
|
|
c763b50dd0 | ||
|
|
4d1d5d4010 | ||
|
|
e426b6e040 | ||
|
|
3cca1c5fa1 | ||
|
|
3ac173fc8b | ||
|
|
ae1662028a | ||
|
|
5cb24d0d39 | ||
|
|
512b464cfa | ||
|
|
fcd6fad822 | ||
|
|
4ccf92ea34 | ||
|
|
fcfeb4959c | ||
|
|
e5193c21a1 | ||
|
|
5a33c2f3a0 | ||
|
|
c1a62b5fa2 | ||
|
|
c90f968d92 | ||
|
|
c5645180a6 | ||
|
|
12d27f43ff | ||
|
|
d711d648cb | ||
|
|
debeae2509 | ||
|
|
6e12c2a6f8 | ||
|
|
8a17610666 | ||
|
|
7f101d1b33 | ||
|
|
a5cfa7841e | ||
|
|
43efadea2e | ||
|
|
9564886d9f | ||
|
|
e65e3cf36e | ||
|
|
184e2eac7d | ||
|
|
d411f98d26 | ||
|
|
519cee115a | ||
|
|
f3a4253984 | ||
|
|
51e6531315 | ||
|
|
2cc9662005 | ||
|
|
29745c6df2 | ||
|
|
7756192906 | ||
|
|
5a7b3592ed | ||
|
|
048acf81cd | ||
|
|
5e1e972aea | ||
|
|
f0fe18fc28 | ||
|
|
6ff331b705 | ||
|
|
b181a88f9f | ||
|
|
c80657b542 | ||
|
|
608bda7052 | ||
|
|
74ea82209b | ||
|
|
dfac5f89e9 | ||
|
|
6383757dca | ||
|
|
d261ba029a | ||
|
|
671971e12e | ||
|
|
e8884c4637 | ||
|
|
143b278267 | ||
|
|
c4da967b5c | ||
|
|
f6169c0b16 | ||
|
|
3310e208fd | ||
|
|
cc76724762 | ||
|
|
4e9c4f2d73 | ||
|
|
e1de390e6e | ||
|
|
f0c3ff313f | ||
|
|
b180223d18 | ||
|
|
8e0f5a6fc7 | ||
|
|
c8ec62103a | ||
|
|
bcfab4d726 | ||
|
|
d61b628bf5 | ||
|
|
2686d32a36 | ||
|
|
677f676172 | ||
|
|
1300467d36 | ||
|
|
b5c2a47b20 | ||
|
|
81c37c28d5 | ||
|
|
d1254808d5 | ||
|
|
ddf37cca30 | ||
|
|
7f6ed5780c | ||
|
|
5037abeb86 | ||
|
|
cdcdab98b8 | ||
|
|
65ea42bd42 | ||
|
|
549f361b71 | ||
|
|
6d293020fb | ||
|
|
52452bebb9 | ||
|
|
3098d7cee0 | ||
|
|
3da5a69dc9 | ||
|
|
06e453ddf4 | ||
|
|
b51a717deb | ||
|
|
bed7ae4083 | ||
|
|
734a911a26 | ||
|
|
0fc263ead5 | ||
|
|
b05073bda5 | ||
|
|
2443275891 | ||
|
|
70c2039748 | ||
|
|
2241563f23 | ||
|
|
ab5b35134f | ||
|
|
b5b24354b8 | ||
|
|
c991eb612d | ||
|
|
70ce5216b5 | ||
|
|
6bc9747df5 | ||
|
|
a4ce0eae43 | ||
|
|
4cfdcaaf7b | ||
|
|
ddc4f20e54 | ||
|
|
a2fea33103 | ||
|
|
5908598666 | ||
|
|
1013224888 | ||
|
|
f121f2738f | ||
|
|
fd58005edf | ||
|
|
750bd0ae9a | ||
|
|
cf4f019ed6 | ||
|
|
e0e4f15d0e | ||
|
|
eb7946ff25 | ||
|
|
6bc41df2fe | ||
|
|
f0c63902ff | ||
|
|
444131a2e6 | ||
|
|
798af22ff4 | ||
|
|
7622b8cdb8 | ||
|
|
52c0b3f100 | ||
|
|
dda9e1e487 | ||
|
|
434a3f35a3 | ||
|
|
07355599c2 | ||
|
|
e6a238c020 | ||
|
|
03b8fdec74 | ||
|
|
2c4dedb7a0 | ||
|
|
bd2b1eabd0 | ||
|
|
72ef553550 | ||
|
|
5b05f88ba9 | ||
|
|
14afdb4d92 | ||
|
|
78d72ef936 | ||
|
|
678ea40b24 | ||
|
|
c686bc0461 | ||
|
|
e033caa3ba | ||
|
|
452ac8ea62 | ||
|
|
33d80ffad0 | ||
|
|
7065779afa | ||
|
|
210c131ce7 | ||
|
|
c932fb50a1 | ||
|
|
a069a21e03 | ||
|
|
e319b63f9e | ||
|
|
cc82ca167a | ||
|
|
5384ed85c8 | ||
|
|
6bc9b9dc4f | ||
|
|
9e955fb9b0 | ||
|
|
33577ef5d3 | ||
|
|
47350f6acb | ||
|
|
b5f52f0b1b | ||
|
|
c6f2b8c841 | ||
|
|
1453bee3e7 | ||
|
|
07945290a2 | ||
|
|
c92d751ad1 | ||
|
|
08bdb2efc8 | ||
|
|
00b0ad1293 | ||
|
|
d0ccb13d09 | ||
|
|
9338582d79 | ||
|
|
3dcd85fab5 | ||
|
|
318bffaa10 | ||
|
|
b0001a6e29 | ||
|
|
da61d9460b | ||
|
|
93e9af43bb | ||
|
|
e5d40b39cd | ||
|
|
5994f3b14c | ||
|
|
974ba12f38 | ||
|
|
68c55a37d9 | ||
|
|
24ca9348f7 | ||
|
|
2e907abdb8 | ||
|
|
0e2d5669f6 | ||
|
|
3912f3de06 | ||
|
|
9be969cc7a | ||
|
|
ada964f16e | ||
|
|
c1ca872d1e | ||
|
|
3a990433f9 | ||
|
|
9bddecee05 | ||
|
|
2fcc4f2886 | ||
|
|
80c8547147 | ||
|
|
9c14e430af | ||
|
|
81d8dd79ca | ||
|
|
20c95be625 | ||
|
|
9a4e8b1d81 | ||
|
|
b3193052b3 | ||
|
|
4729458a36 | ||
|
|
cfced58c1c | ||
|
|
a144daf034 | ||
|
|
b9ebbffc57 | ||
|
|
7a46515d3d | ||
|
|
7be2e04bd4 | ||
|
|
1fd29edf66 | ||
|
|
24f2e6c97e | ||
|
|
29b7fea572 | ||
|
|
90355b4f00 | ||
|
|
f58e41bad8 | ||
|
|
e51cba6195 | ||
|
|
989ddd036f | ||
|
|
4d99c58a5f | ||
|
|
a418278064 | ||
|
|
14d5ce712c | ||
|
|
111968ca58 | ||
|
|
1c5904df3f | ||
|
|
d240463b38 | ||
|
|
511bb22ffd | ||
|
|
e3ec7b01df | ||
|
|
674c409e9d | ||
|
|
12e3fb6a6c | ||
|
|
9adb812a0a | ||
|
|
c3ea3b7e37 | ||
|
|
ee70a2380b | ||
|
|
bd6b7f4aa7 | ||
|
|
6f7112a848 | ||
|
|
f93f1c03fc | ||
|
|
0b2a26fa74 | ||
|
|
388f975cf5 | ||
|
|
7cf3e9be59 | ||
|
|
589b385ec6 | ||
|
|
801e6b6800 | ||
|
|
4acdd7c6f6 | ||
|
|
9c6e791e64 | ||
|
|
dde9c5aaff | ||
|
|
8599f87597 | ||
|
|
9c93531709 | ||
|
|
1149a7a292 | ||
|
|
b069431c28 | ||
|
|
e6cd74ead3 | ||
|
|
74bf00a5ab | ||
|
|
8fe7f5dc43 | ||
|
|
a6008d5d93 | ||
|
|
4fb34a008d | ||
|
|
2f7fcff4d7 | ||
|
|
6e563951af | ||
|
|
0d6a853212 | ||
|
|
493ad834a1 | ||
|
|
1907b25cd0 | ||
|
|
90e2239372 | ||
|
|
2f25347168 | ||
|
|
d22e0809a8 | ||
|
|
33dbc10aab | ||
|
|
8e2c201d23 | ||
|
|
ed9328ceae | ||
|
|
6dab74689c | ||
|
|
5d1b613910 | ||
|
|
af7281afe3 | ||
|
|
ddcc2d85da | ||
|
|
e92641887b | ||
|
|
d4ce6807c7 | ||
|
|
9a7ac85d7e | ||
|
|
5797dcb64e | ||
|
|
dba32d54d1 | ||
|
|
65b718a5e7 | ||
|
|
fc85f776f4 | ||
|
|
a429748e24 | ||
|
|
5c3b36f346 | ||
|
|
e3d51d3e62 | ||
|
|
ecd4bf7aae | ||
|
|
785d7e54d3 | ||
|
|
ed06e0c6af | ||
|
|
1cc34f01db | ||
|
|
0101a4719c | ||
|
|
05941a5f96 | ||
|
|
eb2590b774 | ||
|
|
3a35dabfae | ||
|
|
69cdfae22f | ||
|
|
785bde6f87 | ||
|
|
edc403fb2c | ||
|
|
87143deb4c | ||
|
|
fc5072b100 | ||
|
|
7bc46b8c75 | ||
|
|
440e81db0b | ||
|
|
0759d5ed2b | ||
|
|
2eb1a1a371 | ||
|
|
41c96a25a9 | ||
|
|
0b406754fa | ||
|
|
ab5f203b44 | ||
|
|
a1acf23b60 | ||
|
|
a764d45cfb | ||
|
|
21b5e12913 | ||
|
|
032152ad24 | ||
|
|
af1b7d6e7a | ||
|
|
a9a2a69dc1 | ||
|
|
cd1db1afaa | ||
|
|
1007a26641 | ||
|
|
7e15fdd9c6 | ||
|
|
2dd7476ad7 | ||
|
|
9d235c31a7 | ||
|
|
8f61535b83 | ||
|
|
b8aec1730c | ||
|
|
e19fced5cb | ||
|
|
849b20b7c8 | ||
|
|
be50e7b632 | ||
|
|
aeb4008606 | ||
|
|
1392e9f3da | ||
|
|
225f5258c7 | ||
|
|
56ec4263f9 | ||
|
|
e3188afbe8 | ||
|
|
c7d53aecc3 | ||
|
|
26c87ec6e7 | ||
|
|
f0f07ecd22 | ||
|
|
e814dc8a4b | ||
|
|
d45fca0298 | ||
|
|
7479791f6a | ||
|
|
73b6e9bbd0 | ||
|
|
112d866dc9 | ||
|
|
05b958c178 | ||
|
|
bed63208af | ||
|
|
291ab05023 | ||
|
|
de251635b1 | ||
|
|
3a6be65a20 | ||
|
|
e81a11dd7e | ||
|
|
35c3b371ea | ||
|
|
c71ed6fccb | ||
|
|
62e5647a33 | ||
|
|
732f1c634c | ||
|
|
2fa6e0245a | ||
|
|
053766503c | ||
|
|
7b59dcb8b8 | ||
|
|
5934950ce2 | ||
|
|
f5381871a3 | ||
|
|
44b60490f4 | ||
|
|
387339bf17 | ||
|
|
9d4397aa4a | ||
|
|
2879a4853b | ||
|
|
30e3110170 | ||
|
|
9ff0301515 | ||
|
|
6b629c2e81 | ||
|
|
32e19558e6 | ||
|
|
8f4839d1d9 | ||
|
|
93137b2e52 | ||
|
|
7eeeb79599 | ||
|
|
a8f00cc4a5 | ||
|
|
19b0f019c7 | ||
|
|
dd011849b7 | ||
|
|
c1cdc194e9 | ||
|
|
fcf0f4351a | ||
|
|
cbc21ae531 | ||
|
|
62ddfa7709 | ||
|
|
aefc05cb91 | ||
|
|
2aee9b4959 | ||
|
|
fe4e7c2b96 | ||
|
|
800198349f | ||
|
|
5ca33e48ea | ||
|
|
88f7d24de9 | ||
|
|
29d43ab52f | ||
|
|
fe8bb3b60e | ||
|
|
229c71d9b5 | ||
|
|
7424218392 | ||
|
|
d1d45bbdae | ||
|
|
1e8813f3bd | ||
|
|
1ccc9903a1 | ||
|
|
0323e0670e | ||
|
|
679a835d38 | ||
|
|
7ea5b7c209 | ||
|
|
b73e2be55e | ||
|
|
174228356d | ||
|
|
1838e25b8a | ||
|
|
bc4e957c39 | ||
|
|
fba6fc208c | ||
|
|
025110185e | ||
|
|
d50b905824 | ||
|
|
d4f2509178 | ||
|
|
cdf401a77c | ||
|
|
fef0ef26f1 | ||
|
|
cef360d782 | ||
|
|
c125d2a8bb | ||
|
|
270a49ee75 | ||
|
|
744f9015bb | ||
|
|
1cb5cad50c | ||
|
|
8cc07ba391 | ||
|
|
d74f126592 | ||
|
|
52b3dcdf07 | ||
|
|
099581b591 | ||
|
|
1258046f14 | ||
|
|
7addac910b | ||
|
|
0ea7adff92 | ||
|
|
f858856586 | ||
|
|
d8eac4ae27 | ||
|
|
3cc49ad0e8 | ||
|
|
ceedf4ea96 | ||
|
|
fd8920c71d | ||
|
|
8bbed35736 | ||
|
|
9520b90c4f | ||
|
|
df14bb1671 | ||
|
|
f441dc7ed8 | ||
|
|
2467942886 | ||
|
|
181ef47053 | ||
|
|
1582180e5b | ||
|
|
e0b7da0302 | ||
|
|
fa99857467 | ||
|
|
24f17df782 | ||
|
|
4fe8d1d66b | ||
|
|
a5d77ca08d | ||
|
|
d1d2ab4599 | ||
|
|
e1ddcc2eb7 | ||
|
|
6745667eb0 | ||
|
|
c5b4610cfe | ||
|
|
fed1683b9b | ||
|
|
c01520f173 | ||
|
|
27340f95e4 | ||
|
|
e03eabccda | ||
|
|
82ca10acb6 | ||
|
|
6601939588 | ||
|
|
df8f917463 | ||
|
|
c60b284e1f | ||
|
|
c67967161e | ||
|
|
f52daf9be1 | ||
|
|
7568f75f45 | ||
|
|
3bf8661ec1 | ||
|
|
18f4d6c0ba | ||
|
|
bcfbe51e7e | ||
|
|
ad383b084d | ||
|
|
3b8c04a902 | ||
|
|
9dd97cc141 | ||
|
|
ef13aaf379 | ||
|
|
50a66b3855 | ||
|
|
e08542c635 | ||
|
|
e95c96232a | ||
|
|
b15f6cd2ac | ||
|
|
5634ec3008 | ||
|
|
2dd6c2f0c9 | ||
|
|
38d7f999a7 | ||
|
|
8acb96a627 | ||
|
|
911a1f0ce2 | ||
|
|
732d8c33d1 | ||
|
|
684ea0ad26 | ||
|
|
8cb4c02165 | ||
|
|
be2ff703bc | ||
|
|
16975b447c | ||
|
|
eb1f4a4003 | ||
|
|
59e63bc135 | ||
|
|
62330505e1 | ||
|
|
14477f9f5a | ||
|
|
75a6d349c6 | ||
|
|
e3c76bfafb | ||
|
|
8b3c435241 | ||
|
|
2035799817 | ||
|
|
7751b2b320 | ||
|
|
769031375a | ||
|
|
bd346b4844 | ||
|
|
faba1dca6c | ||
|
|
6f7783e4f6 | ||
|
|
e5f034040e | ||
|
|
3ed9ec808f | ||
|
|
e552ac401e | ||
|
|
b2505e3d6f | ||
|
|
bc696c9273 | ||
|
|
f3e867ed97 | ||
|
|
5dc843cff3 | ||
|
|
cd9c81be91 | ||
|
|
1e23af2adc | ||
|
|
f165ffbc95 | ||
|
|
8cc650847a | ||
|
|
fad4d69ee4 | ||
|
|
0fd6197b8b | ||
|
|
7423837303 | ||
|
|
d25de54008 | ||
|
|
e5a9e31d13 | ||
|
|
ed3bee84c2 | ||
|
|
07740003b8 | ||
|
|
9b66e7edf2 | ||
|
|
6812f14886 | ||
|
|
08e1c16dd2 | ||
|
|
d6b68286ee | ||
|
|
146e069000 | ||
|
|
19cb685c40 | ||
|
|
4cf3c13750 | ||
|
|
20daddbeda | ||
|
|
c57dad8b17 | ||
|
|
295d8a12f1 | ||
|
|
994cb02a66 | ||
|
|
014c86603d | ||
|
|
091634b259 | ||
|
|
d558f6f550 | ||
|
|
c8efc01367 | ||
|
|
28ca7becbd | ||
|
|
ca4b20fad1 | ||
|
|
1133628c01 | ||
|
|
6a1167611c | ||
|
|
a607047aa1 | ||
|
|
2c1cfd8be6 | ||
|
|
4f28e32ebd | ||
|
|
2fbda812bc | ||
|
|
3258bcf531 | ||
|
|
67ebf81e7a | ||
|
|
9b6bf57e79 | ||
|
|
395d5c29d5 | ||
|
|
88ce76767e | ||
|
|
19be870562 | ||
|
|
a1bd3c64f0 | ||
|
|
1a573f987b | ||
|
|
29476f1c6b | ||
|
|
d4ec037f2e | ||
|
|
6612fcf36c | ||
|
|
d29892cb22 | ||
|
|
4fa054e26e | ||
|
|
75c647cd84 | ||
|
|
e4ce8efab5 | ||
|
|
76ecb4a031 | ||
|
|
2e1c4c945e | ||
|
|
4db0a62a06 | ||
|
|
87017bd4cd | ||
|
|
dc703e1b62 | ||
|
|
c171440324 | ||
|
|
7db2070598 | ||
|
|
581fe06a9b | ||
|
|
d2f252f87a | ||
|
|
4a5b9e5f78 | ||
|
|
12ee049a74 | ||
|
|
37a28376bb | ||
|
|
6ade7cba94 | ||
|
|
1bb8fe9615 | ||
|
|
fb13cab216 | ||
|
|
1479e370f8 | ||
|
|
0ca7a63670 | ||
|
|
5ef4830b55 | ||
|
|
93a13381c1 | ||
|
|
4ebe657dd7 | ||
|
|
85b746394e | ||
|
|
fe6366eb40 | ||
|
|
a98720ebc9 | ||
|
|
1db6449b01 | ||
|
|
c7282acb2a | ||
|
|
f332750359 | ||
|
|
9edb3b306f | ||
|
|
c46120a46b | ||
|
|
537497f520 | ||
|
|
56a80f431b | ||
|
|
774d501c1f | ||
|
|
7396c87249 | ||
|
|
c7533f92bb | ||
|
|
38b7fec37a | ||
|
|
c798fc2a29 | ||
|
|
f5245c615c | ||
|
|
aebb7998a3 | ||
|
|
b87da8fe9a | ||
|
|
1f35478b82 | ||
|
|
6d5ac6446c | ||
|
|
8f23eb11d7 | ||
|
|
0617281863 | ||
|
|
7d67f6f26d | ||
|
|
34c8253ad6 | ||
|
|
86e61ad6a5 | ||
|
|
6dbaddd2b9 | ||
|
|
a7faac2f09 | ||
|
|
f161d2f1e5 | ||
|
|
797fe27efe | ||
|
|
a57c5c5425 | ||
|
|
968b33ec79 | ||
|
|
87c7817124 | ||
|
|
bddfa2fc24 | ||
|
|
d05df9836b | ||
|
|
2f2e481fc3 | ||
|
|
1dda51f1fa | ||
|
|
348a1e7619 | ||
|
|
478d250818 | ||
|
|
532575b752 | ||
|
|
c127f9650c | ||
|
|
3419cf9aa7 | ||
|
|
877fc42e40 | ||
|
|
f79e5fc041 | ||
|
|
95c6d7398f | ||
|
|
5c7967e863 | ||
|
|
54e2f7e90d | ||
|
|
48c42bf189 | ||
|
|
92c94176c1 | ||
|
|
15e085cd32 | ||
|
|
2d72c853df | ||
|
|
9a4a81f100 | ||
|
|
61626aaf85 | ||
|
|
5a457d69fc | ||
|
|
7572794add | ||
|
|
60a10b3322 | ||
|
|
ec3fd9bd2a | ||
|
|
34cde09b2b | ||
|
|
8dd94461e1 | ||
|
|
9e04ab62fb | ||
|
|
9907bafa1d | ||
|
|
30f3971bee | ||
|
|
6b651176a3 | ||
|
|
a120edc56e | ||
|
|
5146409a1d | ||
|
|
db2ebf7410 | ||
|
|
bfc3f61010 | ||
|
|
78bfe867e6 | ||
|
|
03dca6d6b3 | ||
|
|
b2dec95862 | ||
|
|
26b5fdac40 | ||
|
|
00323f462a | ||
|
|
981f69ff55 | ||
|
|
5e843cfbbd | ||
|
|
b5ac85f103 | ||
|
|
d81fb6a9e6 | ||
|
|
d269cb9c50 | ||
|
|
2d97833f48 | ||
|
|
eef79067a8 | ||
|
|
aea4c10847 | ||
|
|
7eb4258951 | ||
|
|
c6d0be57d4 | ||
|
|
80b0d06b7e | ||
|
|
8685b740cc | ||
|
|
7fa23f2d2f | ||
|
|
ed264002a0 | ||
|
|
2e3361f0e0 | ||
|
|
363994f29d | ||
|
|
3f4bf96c5d | ||
|
|
0100fdd18d | ||
|
|
c0f85c681e | ||
|
|
43c129f431 | ||
|
|
500a57697d | ||
|
|
c2ab64afe3 | ||
|
|
6b30fb2bea | ||
|
|
9d34d2e036 | ||
|
|
76c15dffde | ||
|
|
d986693fbd | ||
|
|
7f5cb3aa0e | ||
|
|
697a01bfb4 | ||
|
|
1b4921977f | ||
|
|
be355c1e60 | ||
|
|
d10a435d64 | ||
|
|
eb2b086b65 | ||
|
|
08ca3b0849 | ||
|
|
61f21859d9 | ||
|
|
2bfbbfb381 | ||
|
|
31a3d22af4 | ||
|
|
90a8505208 | ||
|
|
06206e1d03 | ||
|
|
bfb9aa3d77 | ||
|
|
1bcea65117 | ||
|
|
bdfa1a0220 | ||
|
|
39504825d8 | ||
|
|
76abd80cb7 | ||
|
|
b1340bf310 | ||
|
|
c731e82fae | ||
|
|
491716c418 | ||
|
|
d64d0ef1dc | ||
|
|
27d6977a3e | ||
|
|
15836eb98e | ||
|
|
0dd51d5dd0 | ||
|
|
6e6031cbe9 | ||
|
|
d82a6ed811 | ||
|
|
ab7492dbc2 | ||
|
|
d3433c5946 | ||
|
|
975bcc8261 | ||
|
|
dd8d9646c4 | ||
|
|
bb2ecc6ad5 | ||
|
|
7a2ae105ea | ||
|
|
fd533d9a76 | ||
|
|
5fe3c58b4a | ||
|
|
dcb6e22a9e | ||
|
|
12399a1d42 | ||
|
|
a624051b85 | ||
|
|
cfea4dbe85 | ||
|
|
e40047f9c2 | ||
|
|
10bb407a2c | ||
|
|
ecf91ee081 | ||
|
|
925d014271 | ||
|
|
77d74f6c0d | ||
|
|
5570e7ceae | ||
|
|
e72a869fd1 | ||
|
|
2c0a0671ad | ||
|
|
6151899ce2 | ||
|
|
6bf282c6c2 | ||
|
|
8c35cff02c | ||
|
|
9f42b78a18 | ||
|
|
69d7f71ae8 | ||
|
|
1754fdbf4e | ||
|
|
58331067f8 | ||
|
|
aa2cb38543 | ||
|
|
6b18ee9edb | ||
|
|
c8faed0b54 | ||
|
|
dbd05a65b5 | ||
|
|
31403a41cd | ||
|
|
3f22596e3c | ||
|
|
cc5efb8d81 | ||
|
|
5aff7fab29 | ||
|
|
dfb3961eea | ||
|
|
39f2dcdfef | ||
|
|
2750679270 | ||
|
|
b38fa40fa6 | ||
|
|
8d570b54c7 | ||
|
|
e2adce1cc1 | ||
|
|
322e40c72e | ||
|
|
328cf187ba | ||
|
|
20b03e781c | ||
|
|
fcf2f0a03d | ||
|
|
cd8ab469ff | ||
|
|
659b9cd517 | ||
|
|
52d472c209 | ||
|
|
9ed59e71f6 | ||
|
|
e0053c62e1 | ||
|
|
8f0d7d1d3e | ||
|
|
771891491c | ||
|
|
f203d13efc | ||
|
|
14e400226a | ||
|
|
58f80c5675 | ||
|
|
4a7d84e861 | ||
|
|
1519f74f3c | ||
|
|
0e012cb05e | ||
|
|
19631ecef6 | ||
|
|
a569bf2698 | ||
|
|
dc12958fc7 | ||
|
|
67b68ceae6 | ||
|
|
54eb5623cb | ||
|
|
d9c22e54de | ||
|
|
7765e2dc55 | ||
|
|
ab278513ab | ||
|
|
e7a22792ac | ||
|
|
e05098cacb | ||
|
|
f9e95ab522 | ||
|
|
bb7d6814a7 | ||
|
|
e00fb99e7b | ||
|
|
e9a3f5169e | ||
|
|
1af3e81ada | ||
|
|
7cd5474f1a | ||
|
|
821eb21ae2 | ||
|
|
cc410b8c90 | ||
|
|
79e7862583 | ||
|
|
f9d634ce06 | ||
|
|
65a1cdf8e5 | ||
|
|
67229fd7a9 | ||
|
|
3033177e9e | ||
|
|
656a8fa3a2 | ||
|
|
0e9b64649a | ||
|
|
9da3c6c573 | ||
|
|
09a1305628 | ||
|
|
7d314fef78 | ||
|
|
dece767084 | ||
|
|
63bf9c7995 | ||
|
|
1c76483b4b | ||
|
|
9abe6ad4d8 | ||
|
|
8175df1002 | ||
|
|
a1a1a8895e | ||
|
|
69af79d45d | ||
|
|
e3a95b2d1a | ||
|
|
5c23b94069 | ||
|
|
85bb6cd027 | ||
|
|
90b9f1a98a | ||
|
|
55c2a5dc83 | ||
|
|
1d0d5bb141 | ||
|
|
7a983a4079 | ||
|
|
2523288509 | ||
|
|
8a6768763d | ||
|
|
a186f8c3aa | ||
|
|
ceeb6f0690 | ||
|
|
f3e5b6e13c | ||
|
|
34f2f887b1 | ||
|
|
20b51cc9ce | ||
|
|
56aad86231 | ||
|
|
ed1de6df80 | ||
|
|
8cb5b68cb6 | ||
|
|
e4abca9494 | ||
|
|
0a3300d773 | ||
|
|
2fab05c83e | ||
|
|
40f7ee1cab | ||
|
|
2c166d7a3a | ||
|
|
dcea64c838 | ||
|
|
255218a2f3 | ||
|
|
b76cd5858c | ||
|
|
46b5d46111 | ||
|
|
993ff8bb91 | ||
|
|
2cde04867f | ||
|
|
337840d29b | ||
|
|
fd2c57b8a4 | ||
|
|
1c5167d96e | ||
|
|
0d63646015 | ||
|
|
b5367f48f6 | ||
|
|
62c8ce9657 | ||
|
|
eb2ca06d67 | ||
|
|
16f729115e | ||
|
|
9355f5faf2 | ||
|
|
8cef2086f5 | ||
|
|
f7928c68a3 | ||
|
|
ecb09a23bc | ||
|
|
b9b58a1275 | ||
|
|
4a6c01c83c | ||
|
|
27f6f8ea9e | ||
|
|
d8d648549f | ||
|
|
38cd595235 | ||
|
|
7a60cb7f3e | ||
|
|
68f13cd739 | ||
|
|
d1ce3c697c | ||
|
|
2e536eda29 | ||
|
|
155ed3a814 | ||
|
|
5b0bb53184 | ||
|
|
42505f473d | ||
|
|
98756c068a | ||
|
|
aa54a038f2 | ||
|
|
a30075794b | ||
|
|
a8128493c2 | ||
|
|
faed8285cd | ||
|
|
21f3f3eec4 | ||
|
|
2f1ba40786 | ||
|
|
c565104491 | ||
|
|
54fcff189f | ||
|
|
d37f38c455 | ||
|
|
5e5bdda491 |
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
|
||||||
|
...
|
||||||
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1 +1,2 @@
|
|||||||
open_collective: xgboost
|
open_collective: xgboost
|
||||||
|
custom: https://xgboost.ai/sponsors
|
||||||
|
|||||||
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
|
||||||
281
.github/workflows/main.yml
vendored
281
.github/workflows/main.yml
vendored
@@ -6,133 +6,208 @@ name: XGBoost-CI
|
|||||||
# events but only for the master branch
|
# events but only for the master branch
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
env:
|
permissions:
|
||||||
R_PACKAGES: c('XML', 'igraph', 'data.table', 'magrittr', 'stringi', 'ggplot2', 'DiagrammeR', 'Ckmeans.1d.dp', 'vcd', 'testthat', 'lintr', 'knitr', 'rmarkdown', 'e1071', 'cplm', 'devtools')
|
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
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
jobs:
|
jobs:
|
||||||
test-with-jvm:
|
gtest-cpu:
|
||||||
name: Test JVM on OS ${{ matrix.os }}
|
name: Test Google C++ test (CPU)
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest, windows-2016, ubuntu-latest]
|
os: [macos-11]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
|
- name: Install system packages
|
||||||
- uses: actions/setup-java@v1
|
|
||||||
with:
|
|
||||||
java-version: 1.8
|
|
||||||
|
|
||||||
- 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 JVM packages
|
|
||||||
run: |
|
run: |
|
||||||
cd jvm-packages
|
brew install ninja libomp
|
||||||
mvn test -pl :xgboost4j_2.12
|
- name: Build gtest binary
|
||||||
|
|
||||||
|
|
||||||
lintr:
|
|
||||||
runs-on: ${{ matrix.config.os }}
|
|
||||||
|
|
||||||
name: Run R linters on OS ${{ matrix.config.os }}, R ${{ matrix.config.r }}, Compiler ${{ matrix.config.compiler }}, Build ${{ matrix.config.build }}
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
config:
|
|
||||||
- {os: windows-latest, r: 'release', compiler: 'mingw', build: 'autotools'}
|
|
||||||
env:
|
|
||||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
|
||||||
RSPM: ${{ matrix.config.rspm }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: 'true'
|
|
||||||
|
|
||||||
- uses: r-lib/actions/setup-r@master
|
|
||||||
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 }}-1-${{ hashFiles('R-package/DESCRIPTION') }}
|
|
||||||
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-2-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
shell: Rscript {0}
|
|
||||||
run: |
|
run: |
|
||||||
install.packages(${{ env.R_PACKAGES }},
|
mkdir build
|
||||||
repos = 'http://cloud.r-project.org',
|
cd build
|
||||||
dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
cmake .. -DGOOGLE_TEST=ON -DUSE_OPENMP=ON -DUSE_DMLC_GTEST=ON -DPLUGIN_DENSE_PARSER=ON -GNinja
|
||||||
|
ninja -v
|
||||||
- name: Run lintr
|
- name: Run gtest binary
|
||||||
run: |
|
run: |
|
||||||
cd R-package
|
cd build
|
||||||
R.exe CMD INSTALL .
|
./testxgboost
|
||||||
Rscript.exe tests/run_lint.R
|
ctest -R TestXGBoostCLI --extra-verbose
|
||||||
|
|
||||||
|
|
||||||
test-with-R:
|
|
||||||
runs-on: ${{ matrix.config.os }}
|
|
||||||
|
|
||||||
name: Test R on OS ${{ matrix.config.os }}, R ${{ matrix.config.r }}, Compiler ${{ matrix.config.compiler }}, Build ${{ matrix.config.build }}
|
|
||||||
|
|
||||||
|
gtest-cpu-nonomp:
|
||||||
|
name: Test Google C++ unittest (CPU Non-OMP)
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
config:
|
os: [ubuntu-latest]
|
||||||
- {os: windows-latest, r: 'release', compiler: 'msvc', build: 'autotools'}
|
|
||||||
- {os: windows-2016, r: 'release', compiler: 'msvc', build: 'autotools'}
|
|
||||||
- {os: windows-latest, r: 'release', compiler: 'msvc', build: 'cmake'}
|
|
||||||
- {os: windows-2016, r: 'release', compiler: 'msvc', build: 'cmake'}
|
|
||||||
- {os: windows-latest, r: 'release', compiler: 'mingw', build: 'autotools'}
|
|
||||||
- {os: windows-2016, r: 'release', compiler: 'mingw', build: 'autotools'}
|
|
||||||
- {os: windows-latest, r: 'release', compiler: 'mingw', build: 'cmake'}
|
|
||||||
- {os: windows-2016, r: 'release', compiler: 'mingw', build: 'cmake'}
|
|
||||||
env:
|
|
||||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
|
||||||
RSPM: ${{ matrix.config.rspm }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
|
- name: Install system packages
|
||||||
- uses: r-lib/actions/setup-r@master
|
|
||||||
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 }}-1-${{ hashFiles('R-package/DESCRIPTION') }}
|
|
||||||
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-2-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
shell: Rscript {0}
|
|
||||||
run: |
|
run: |
|
||||||
install.packages(${{ env.R_PACKAGES }},
|
sudo apt-get install -y --no-install-recommends ninja-build
|
||||||
repos = 'http://cloud.r-project.org',
|
- name: Build and install XGBoost
|
||||||
dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
shell: bash -l {0}
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -GNinja -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON -DUSE_OPENMP=OFF
|
||||||
|
ninja -v
|
||||||
|
- name: Run gtest binary
|
||||||
|
run: |
|
||||||
|
cd build
|
||||||
|
ctest --extra-verbose
|
||||||
|
|
||||||
|
c-api-demo:
|
||||||
|
name: Test installing XGBoost lib + building the C API demo
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: ["ubuntu-latest"]
|
||||||
|
python-version: ["3.8"]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
- uses: mamba-org/provision-with-micromamba@f347426e5745fe3dfc13ec5baf20496990d0281f # v14
|
||||||
|
with:
|
||||||
|
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 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
|
||||||
|
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 ..
|
||||||
|
rm -rf ./build
|
||||||
|
popd
|
||||||
|
|
||||||
|
- name: Build and install XGBoost shared library
|
||||||
|
shell: bash -l {0}
|
||||||
|
run: |
|
||||||
|
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: |
|
||||||
|
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 C++
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.6' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
python-version: "3.8"
|
||||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
architecture: 'x64'
|
||||||
|
- name: Install Python packages
|
||||||
- name: Test R
|
|
||||||
run: |
|
run: |
|
||||||
python tests/ci_build/test_r_package.py --compiler="${{ matrix.config.compiler }}" --build-tool="${{ matrix.config.build }}"
|
python -m pip install wheel setuptools cpplint pylint
|
||||||
|
- name: Run lint
|
||||||
|
run: |
|
||||||
|
LINT_LANG=cpp make lint
|
||||||
|
|
||||||
|
doxygen:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Generate C/C++ API doc using Doxygen
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: "3.8"
|
||||||
|
architecture: 'x64'
|
||||||
|
- name: Install system packages
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y --no-install-recommends doxygen graphviz ninja-build
|
||||||
|
python -m pip install wheel setuptools
|
||||||
|
python -m pip install awscli
|
||||||
|
- name: Run Doxygen
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -DBUILD_C_DOC=ON -GNinja
|
||||||
|
ninja -v doc_doxygen
|
||||||
|
- 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: Publish
|
||||||
|
run: |
|
||||||
|
cd build/
|
||||||
|
tar cvjf ${{ steps.extract_branch.outputs.branch }}.tar.bz2 doc_doxygen/
|
||||||
|
python -m awscli s3 cp ./${{ steps.extract_branch.outputs.branch }}.tar.bz2 s3://xgboost-docs/doxygen/ --acl public-read
|
||||||
|
if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
|
||||||
|
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 }}
|
||||||
|
|
||||||
|
sphinx:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Build docs using Sphinx
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: "3.8"
|
||||||
|
architecture: 'x64'
|
||||||
|
- name: Install system packages
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y --no-install-recommends graphviz
|
||||||
|
python -m pip install wheel setuptools
|
||||||
|
python -m pip install -r doc/requirements.txt
|
||||||
|
- 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: Run Sphinx
|
||||||
|
run: |
|
||||||
|
make -C doc html
|
||||||
|
env:
|
||||||
|
SPHINX_GIT_BRANCH: ${{ steps.extract_branch.outputs.branch }}
|
||||||
|
|||||||
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 }}
|
||||||
47
.github/workflows/r_nold.yml
vendored
Normal file
47
.github/workflows/r_nold.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Run R tests with noLD R. Only triggered by a pull request review
|
||||||
|
# See discussion at https://github.com/dmlc/xgboost/pull/6378
|
||||||
|
|
||||||
|
name: XGBoost-R-noLD
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_review_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
env:
|
||||||
|
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:
|
||||||
|
if: github.event.comment.body == '/gha run r-nold-test' && contains('OWNER,MEMBER,COLLABORATOR', github.event.comment.author_association)
|
||||||
|
timeout-minutes: 120
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: rhub/debian-gcc-devel-nold
|
||||||
|
steps:
|
||||||
|
- name: Install git and system packages
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
apt-get update && apt-get install -y git libcurl4-openssl-dev libssl-dev libssh2-1-dev libgit2-dev libxml2-dev
|
||||||
|
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cat > install_libs.R <<EOT
|
||||||
|
install.packages(${{ env.R_PACKAGES }},
|
||||||
|
repos = 'http://cloud.r-project.org',
|
||||||
|
dependencies = c('Depends', 'Imports', 'LinkingTo'))
|
||||||
|
EOT
|
||||||
|
/tmp/R-devel/bin/Rscript install_libs.R
|
||||||
|
|
||||||
|
- name: Run R tests
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd R-package && \
|
||||||
|
/tmp/R-devel/bin/R CMD INSTALL . && \
|
||||||
|
/tmp/R-devel/bin/R -q -e "library(testthat); setwd('tests'); source('testthat.R')"
|
||||||
164
.github/workflows/r_tests.yml
vendored
Normal file
164
.github/workflows/r_tests.yml
vendored
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
name: XGBoost-R-Tests
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
env:
|
||||||
|
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:
|
||||||
|
runs-on: ${{ matrix.config.os }}
|
||||||
|
name: Run R linters on OS ${{ matrix.config.os }}, R ${{ matrix.config.r }}, Compiler ${{ matrix.config.compiler }}, Build ${{ matrix.config.build }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- {os: ubuntu-latest, r: 'release'}
|
||||||
|
env:
|
||||||
|
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
||||||
|
RSPM: ${{ matrix.config.rspm }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- 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 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 }}
|
||||||
|
name: Test R on OS ${{ matrix.config.os }}, R ${{ matrix.config.r }}, Compiler ${{ matrix.config.compiler }}, Build ${{ matrix.config.build }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- {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:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- 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.8"
|
||||||
|
architecture: 'x64'
|
||||||
|
|
||||||
|
- name: Test R
|
||||||
|
run: |
|
||||||
|
python tests/ci_build/test_r_package.py --compiler='${{ matrix.config.compiler }}' --build-tool='${{ matrix.config.build }}'
|
||||||
|
|
||||||
|
test-R-CRAN:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
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@v2
|
||||||
|
with:
|
||||||
|
r-version: ${{ matrix.config.r }}
|
||||||
|
|
||||||
|
- 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 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}
|
||||||
|
run: |
|
||||||
|
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: |
|
||||||
|
# Print stacktrace upon success of failure
|
||||||
|
make Rcheck || tests/ci_build/print_r_stacktrace.sh fail
|
||||||
|
tests/ci_build/print_r_stacktrace.sh success
|
||||||
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
|
||||||
40
.gitignore
vendored
40
.gitignore
vendored
@@ -52,6 +52,8 @@ Debug
|
|||||||
R-package.Rproj
|
R-package.Rproj
|
||||||
*.cache*
|
*.cache*
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
|
doxygen
|
||||||
|
|
||||||
# java
|
# java
|
||||||
java/xgboost4j/target
|
java/xgboost4j/target
|
||||||
java/xgboost4j/tmp
|
java/xgboost4j/tmp
|
||||||
@@ -63,6 +65,7 @@ nb-configuration*
|
|||||||
# Eclipse
|
# Eclipse
|
||||||
.project
|
.project
|
||||||
.cproject
|
.cproject
|
||||||
|
.classpath
|
||||||
.pydevproject
|
.pydevproject
|
||||||
.settings/
|
.settings/
|
||||||
build
|
build
|
||||||
@@ -71,6 +74,7 @@ build
|
|||||||
build_plugin
|
build_plugin
|
||||||
recommonmark/
|
recommonmark/
|
||||||
tags
|
tags
|
||||||
|
TAGS
|
||||||
*.class
|
*.class
|
||||||
target
|
target
|
||||||
*.swp
|
*.swp
|
||||||
@@ -95,8 +99,11 @@ metastore_db
|
|||||||
R-package/src/Makevars
|
R-package/src/Makevars
|
||||||
*.lib
|
*.lib
|
||||||
|
|
||||||
# Visual Studio Code
|
# Visual Studio
|
||||||
/.vscode/
|
.vs/
|
||||||
|
CMakeSettings.json
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
|
||||||
# IntelliJ/CLion
|
# IntelliJ/CLion
|
||||||
.idea
|
.idea
|
||||||
@@ -104,4 +111,31 @@ R-package/src/Makevars
|
|||||||
/cmake-build-debug/
|
/cmake-build-debug/
|
||||||
|
|
||||||
# GDB
|
# GDB
|
||||||
.gdb_history
|
.gdb_history
|
||||||
|
|
||||||
|
# Python joblib.Memory used in pytest.
|
||||||
|
cachedir/
|
||||||
|
|
||||||
|
# Files from local Dask work
|
||||||
|
dask-worker-space/
|
||||||
|
|
||||||
|
# Jupyter notebook checkpoints
|
||||||
|
.ipynb_checkpoints/
|
||||||
|
|
||||||
|
# credentials and key material
|
||||||
|
config
|
||||||
|
credentials
|
||||||
|
credentials.csv
|
||||||
|
*.env
|
||||||
|
*.pem
|
||||||
|
*.pub
|
||||||
|
*.rdp
|
||||||
|
*_rsa
|
||||||
|
|
||||||
|
# Visual Studio code + extensions
|
||||||
|
.vscode
|
||||||
|
.metals
|
||||||
|
.bloop
|
||||||
|
|
||||||
|
# hypothesis python tests
|
||||||
|
.hypothesis
|
||||||
7
.gitmodules
vendored
7
.gitmodules
vendored
@@ -1,9 +1,10 @@
|
|||||||
[submodule "dmlc-core"]
|
[submodule "dmlc-core"]
|
||||||
path = dmlc-core
|
path = dmlc-core
|
||||||
url = https://github.com/dmlc/dmlc-core
|
url = https://github.com/dmlc/dmlc-core
|
||||||
[submodule "rabit"]
|
branch = main
|
||||||
path = rabit
|
|
||||||
url = https://github.com/dmlc/rabit
|
|
||||||
[submodule "cub"]
|
[submodule "cub"]
|
||||||
path = cub
|
path = cub
|
||||||
url = https://github.com/NVlabs/cub
|
url = https://github.com/NVlabs/cub
|
||||||
|
[submodule "gputreeshap"]
|
||||||
|
path = gputreeshap
|
||||||
|
url = https://github.com/rapidsai/gputreeshap.git
|
||||||
|
|||||||
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
|
||||||
49
.travis.yml
49
.travis.yml
@@ -1,57 +1,30 @@
|
|||||||
# disable sudo for container build.
|
|
||||||
sudo: required
|
sudo: required
|
||||||
|
|
||||||
# Enabling test OS X
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
|
|
||||||
osx_image: xcode10.1
|
|
||||||
dist: bionic
|
dist: bionic
|
||||||
|
|
||||||
# Use Build Matrix to do lint and build seperately
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
|
||||||
# python package test
|
|
||||||
- TASK=python_test
|
|
||||||
# test installation of Python source distribution
|
|
||||||
- TASK=python_sdist_test
|
|
||||||
# java package test
|
|
||||||
- TASK=java_test
|
|
||||||
# cmake test
|
|
||||||
- TASK=cmake_test
|
|
||||||
|
|
||||||
global:
|
global:
|
||||||
- secure: "PR16i9F8QtNwn99C5NDp8nptAS+97xwDtXEJJfEiEVhxPaaRkOp0MPWhogCaK0Eclxk1TqkgWbdXFknwGycX620AzZWa/A1K3gAs+GrpzqhnPMuoBJ0Z9qxXTbSJvCyvMbYwVrjaxc/zWqdMU8waWz8A7iqKGKs/SqbQ3rO6v7c="
|
- secure: "lqkL5SCM/CBwgVb1GWoOngpojsa0zCSGcvF0O3/45rBT1EpNYtQ4LRJ1+XcHi126vdfGoim/8i7AQhn5eOgmZI8yAPBeoUZ5zSrejD3RUpXr2rXocsvRRP25Z4mIuAGHD9VAHtvTdhBZRVV818W02pYduSzAeaY61q/lU3xmWsE="
|
||||||
- secure: "dAGAjBokqm/0nVoLMofQni/fWIBcYSmdq4XvCBX1ZAMDsWnuOfz/4XCY6h2lEI1rVHZQ+UdZkc9PioOHGPZh5BnvE49/xVVWr9c4/61lrDOlkD01ZjSAeoV0fAZq+93V/wPl4QV+MM+Sem9hNNzFSbN5VsQLAiWCSapWsLdKzqA="
|
- secure: "mzms6X8uvdhRWxkPBMwx+mDl3d+V1kUpZa7UgjT+dr4rvZMzvKtjKp/O0JZZVogdgZjUZf444B98/7AvWdSkGdkfz2QdmhWmXzNPfNuHtmfCYMdijsgFIGLuD3GviFL/rBiM2vgn32T3QqFiEJiC5StparnnXimPTc9TpXQRq5c="
|
||||||
|
|
||||||
matrix:
|
|
||||||
exclude:
|
jobs:
|
||||||
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
env: TASK=python_test
|
arch: s390x
|
||||||
- os: linux
|
env: TASK=s390x_test
|
||||||
env: TASK=java_test
|
|
||||||
- os: linux
|
|
||||||
env: TASK=cmake_test
|
|
||||||
|
|
||||||
# dependent brew packages
|
# dependent brew packages
|
||||||
|
# the dependencies from homebrew is installed manually from setup script due to outdated image from travis.
|
||||||
addons:
|
addons:
|
||||||
homebrew:
|
homebrew:
|
||||||
|
update: false
|
||||||
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- cmake
|
- unzip
|
||||||
- libomp
|
|
||||||
- graphviz
|
|
||||||
- openssl
|
|
||||||
- libgit2
|
|
||||||
- lz4
|
|
||||||
- wget
|
|
||||||
- r
|
|
||||||
update: true
|
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- source tests/travis/travis_setup_env.sh
|
- 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:
|
install:
|
||||||
- source tests/travis/setup.sh
|
- source tests/travis/setup.sh
|
||||||
|
|||||||
222
CMakeLists.txt
222
CMakeLists.txt
@@ -1,9 +1,11 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
||||||
project(xgboost LANGUAGES CXX C VERSION 1.2.0)
|
project(xgboost LANGUAGES CXX C VERSION 1.7.2)
|
||||||
include(cmake/Utils.cmake)
|
include(cmake/Utils.cmake)
|
||||||
list(APPEND CMAKE_MODULE_PATH "${xgboost_SOURCE_DIR}/cmake/modules")
|
list(APPEND CMAKE_MODULE_PATH "${xgboost_SOURCE_DIR}/cmake/modules")
|
||||||
cmake_policy(SET CMP0022 NEW)
|
cmake_policy(SET CMP0022 NEW)
|
||||||
cmake_policy(SET CMP0079 NEW)
|
cmake_policy(SET CMP0079 NEW)
|
||||||
|
cmake_policy(SET CMP0076 NEW)
|
||||||
|
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
|
||||||
if ((${CMAKE_VERSION} VERSION_GREATER 3.13) OR (${CMAKE_VERSION} VERSION_EQUAL 3.13))
|
if ((${CMAKE_VERSION} VERSION_GREATER 3.13) OR (${CMAKE_VERSION} VERSION_EQUAL 3.13))
|
||||||
@@ -23,9 +25,12 @@ write_version()
|
|||||||
set_default_configuration_release()
|
set_default_configuration_release()
|
||||||
|
|
||||||
#-- Options
|
#-- Options
|
||||||
|
## User options
|
||||||
option(BUILD_C_DOC "Build documentation for C APIs using Doxygen." OFF)
|
option(BUILD_C_DOC "Build documentation for C APIs using Doxygen." OFF)
|
||||||
option(USE_OPENMP "Build with OpenMP support." ON)
|
option(USE_OPENMP "Build with OpenMP support." ON)
|
||||||
option(BUILD_STATIC_LIB "Build static library" OFF)
|
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
|
## Bindings
|
||||||
option(JVM_BINDINGS "Build JVM bindings" OFF)
|
option(JVM_BINDINGS "Build JVM bindings" OFF)
|
||||||
option(R_LIB "Build shared library for R package" OFF)
|
option(R_LIB "Build shared library for R package" OFF)
|
||||||
@@ -37,6 +42,7 @@ option(ENABLE_ALL_WARNINGS "Enable all compiler warnings. Only effective for GCC
|
|||||||
option(LOG_CAPI_INVOCATION "Log all C API invocations for debugging" OFF)
|
option(LOG_CAPI_INVOCATION "Log all C API invocations for debugging" OFF)
|
||||||
option(GOOGLE_TEST "Build google tests" OFF)
|
option(GOOGLE_TEST "Build google tests" OFF)
|
||||||
option(USE_DMLC_GTEST "Use google tests bundled with dmlc-core submodule" OFF)
|
option(USE_DMLC_GTEST "Use google tests bundled with dmlc-core submodule" OFF)
|
||||||
|
option(USE_DEVICE_DEBUG "Generate CUDA device debug info." OFF)
|
||||||
option(USE_NVTX "Build with cuda profiling annotations. Developers only." OFF)
|
option(USE_NVTX "Build with cuda profiling annotations. Developers only." OFF)
|
||||||
set(NVTX_HEADER_DIR "" CACHE PATH "Path to the stand-alone nvtx header")
|
set(NVTX_HEADER_DIR "" CACHE PATH "Path to the stand-alone nvtx header")
|
||||||
option(RABIT_MOCK "Build rabit with mock" OFF)
|
option(RABIT_MOCK "Build rabit with mock" OFF)
|
||||||
@@ -45,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_CUDA "Build with GPU acceleration" OFF)
|
||||||
option(USE_NCCL "Build with NCCL to enable distributed GPU support." 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_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
|
set(GPU_COMPUTE_VER "" CACHE STRING
|
||||||
"Semicolon separated list of compute versions to be built against, e.g. '35;61'")
|
"Semicolon separated list of compute versions to be built against, e.g. '35;61'")
|
||||||
## Copied From dmlc
|
## Copied From dmlc
|
||||||
@@ -58,8 +65,11 @@ set(ENABLED_SANITIZERS "address" "leak" CACHE STRING
|
|||||||
"Semicolon separated list of sanitizer names. E.g 'address;leak'. Supported sanitizers are
|
"Semicolon separated list of sanitizer names. E.g 'address;leak'. Supported sanitizers are
|
||||||
address, leak, undefined and thread.")
|
address, leak, undefined and thread.")
|
||||||
## Plugins
|
## Plugins
|
||||||
option(PLUGIN_LZ4 "Build lz4 plugin" OFF)
|
|
||||||
option(PLUGIN_DENSE_PARSER "Build dense parser 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)
|
option(ADD_PKGCONFIG "Add xgboost.pc into system." ON)
|
||||||
|
|
||||||
#-- Checks for building XGBoost
|
#-- Checks for building XGBoost
|
||||||
@@ -69,6 +79,9 @@ endif (USE_DEBUG_OUTPUT AND (NOT (CMAKE_BUILD_TYPE MATCHES Debug)))
|
|||||||
if (USE_NCCL AND NOT (USE_CUDA))
|
if (USE_NCCL AND NOT (USE_CUDA))
|
||||||
message(SEND_ERROR "`USE_NCCL` must be enabled with `USE_CUDA` flag.")
|
message(SEND_ERROR "`USE_NCCL` must be enabled with `USE_CUDA` flag.")
|
||||||
endif (USE_NCCL AND NOT (USE_CUDA))
|
endif (USE_NCCL AND NOT (USE_CUDA))
|
||||||
|
if (USE_DEVICE_DEBUG AND NOT (USE_CUDA))
|
||||||
|
message(SEND_ERROR "`USE_DEVICE_DEBUG` must be enabled with `USE_CUDA` flag.")
|
||||||
|
endif (USE_DEVICE_DEBUG AND NOT (USE_CUDA))
|
||||||
if (BUILD_WITH_SHARED_NCCL AND (NOT USE_NCCL))
|
if (BUILD_WITH_SHARED_NCCL AND (NOT USE_NCCL))
|
||||||
message(SEND_ERROR "Build XGBoost with -DUSE_NCCL=ON to enable BUILD_WITH_SHARED_NCCL.")
|
message(SEND_ERROR "Build XGBoost with -DUSE_NCCL=ON to enable BUILD_WITH_SHARED_NCCL.")
|
||||||
endif (BUILD_WITH_SHARED_NCCL AND (NOT USE_NCCL))
|
endif (BUILD_WITH_SHARED_NCCL AND (NOT USE_NCCL))
|
||||||
@@ -82,11 +95,43 @@ endif (R_LIB AND GOOGLE_TEST)
|
|||||||
if (USE_AVX)
|
if (USE_AVX)
|
||||||
message(SEND_ERROR "The option 'USE_AVX' is deprecated as experimental AVX features have been removed from XGBoost.")
|
message(SEND_ERROR "The option 'USE_AVX' is deprecated as experimental AVX features have been removed from XGBoost.")
|
||||||
endif (USE_AVX)
|
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))
|
||||||
|
if (PLUGIN_RMM AND NOT ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
|
||||||
|
message(SEND_ERROR "`PLUGIN_RMM` must be used with GCC or Clang compiler.")
|
||||||
|
endif (PLUGIN_RMM AND NOT ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
|
||||||
|
if (PLUGIN_RMM AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
||||||
|
message(SEND_ERROR "`PLUGIN_RMM` must be used with Linux.")
|
||||||
|
endif (PLUGIN_RMM AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
||||||
if (ENABLE_ALL_WARNINGS)
|
if (ENABLE_ALL_WARNINGS)
|
||||||
if ((NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
|
if ((NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
|
||||||
message(SEND_ERROR "ENABLE_ALL_WARNINGS is only available for Clang and GCC.")
|
message(SEND_ERROR "ENABLE_ALL_WARNINGS is only available for Clang and GCC.")
|
||||||
endif ((NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
|
endif ((NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
|
||||||
endif (ENABLE_ALL_WARNINGS)
|
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
|
#-- Sanitizer
|
||||||
if (USE_SANITIZER)
|
if (USE_SANITIZER)
|
||||||
@@ -95,18 +140,22 @@ if (USE_SANITIZER)
|
|||||||
endif (USE_SANITIZER)
|
endif (USE_SANITIZER)
|
||||||
|
|
||||||
if (USE_CUDA)
|
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.
|
# `export CXX=' is ignored by CMake CUDA.
|
||||||
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER})
|
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER})
|
||||||
message(STATUS "Configured CUDA host compiler: ${CMAKE_CUDA_HOST_COMPILER}")
|
message(STATUS "Configured CUDA host compiler: ${CMAKE_CUDA_HOST_COMPILER}")
|
||||||
|
|
||||||
enable_language(CUDA)
|
enable_language(CUDA)
|
||||||
if (${CMAKE_CUDA_COMPILER_VERSION} VERSION_LESS 10.0)
|
if (${CMAKE_CUDA_COMPILER_VERSION} VERSION_LESS 11.0)
|
||||||
message(FATAL_ERROR "CUDA version must be at least 10.0!")
|
message(FATAL_ERROR "CUDA version must be at least 11.0!")
|
||||||
endif()
|
endif()
|
||||||
set(GEN_CODE "")
|
set(GEN_CODE "")
|
||||||
format_gencode_flags("${GPU_COMPUTE_VER}" GEN_CODE)
|
format_gencode_flags("${GPU_COMPUTE_VER}" GEN_CODE)
|
||||||
message(STATUS "CUDA GEN_CODE: ${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)
|
endif (USE_CUDA)
|
||||||
|
|
||||||
if (FORCE_COLORED_OUTPUT AND (CMAKE_GENERATOR STREQUAL "Ninja") AND
|
if (FORCE_COLORED_OUTPUT AND (CMAKE_GENERATOR STREQUAL "Ninja") AND
|
||||||
@@ -122,74 +171,76 @@ if (USE_OPENMP)
|
|||||||
# Require CMake 3.16+ on Mac OSX, as previous versions of CMake had trouble locating
|
# 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
|
# OpenMP on Mac. See https://github.com/dmlc/xgboost/pull/5146#issuecomment-568312706
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
endif (APPLE)
|
find_package(OpenMP)
|
||||||
find_package(OpenMP REQUIRED)
|
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)
|
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()
|
||||||
|
|
||||||
# core xgboost
|
if (USE_NCCL)
|
||||||
add_subdirectory(${xgboost_SOURCE_DIR}/src)
|
find_package(Nccl REQUIRED)
|
||||||
|
endif (USE_NCCL)
|
||||||
|
|
||||||
# dmlc-core
|
# dmlc-core
|
||||||
msvc_use_static_runtime()
|
msvc_use_static_runtime()
|
||||||
|
if (FORCE_SHARED_CRT)
|
||||||
|
set(DMLC_FORCE_SHARED_CRT ON)
|
||||||
|
endif ()
|
||||||
add_subdirectory(${xgboost_SOURCE_DIR}/dmlc-core)
|
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)
|
if (MSVC)
|
||||||
target_compile_options(dmlc PRIVATE
|
|
||||||
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
|
||||||
if (TARGET dmlc_unit_tests)
|
if (TARGET dmlc_unit_tests)
|
||||||
target_compile_options(dmlc_unit_tests PRIVATE
|
target_compile_options(dmlc_unit_tests PRIVATE
|
||||||
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
||||||
endif (TARGET dmlc_unit_tests)
|
endif (TARGET dmlc_unit_tests)
|
||||||
endif (MSVC)
|
endif (MSVC)
|
||||||
if (ENABLE_ALL_WARNINGS)
|
|
||||||
target_compile_options(dmlc PRIVATE -Wall -Wextra)
|
|
||||||
endif (ENABLE_ALL_WARNINGS)
|
|
||||||
target_link_libraries(objxgboost PUBLIC dmlc)
|
|
||||||
|
|
||||||
# rabit
|
# rabit
|
||||||
set(RABIT_BUILD_DMLC OFF)
|
|
||||||
set(DMLC_ROOT ${xgboost_SOURCE_DIR}/dmlc-core)
|
|
||||||
set(RABIT_WITH_R_LIB ${R_LIB})
|
|
||||||
add_subdirectory(rabit)
|
add_subdirectory(rabit)
|
||||||
|
if (RABIT_BUILD_MPI)
|
||||||
|
find_package(MPI REQUIRED)
|
||||||
|
endif (RABIT_BUILD_MPI)
|
||||||
|
|
||||||
if (RABIT_MOCK)
|
# core xgboost
|
||||||
target_link_libraries(objxgboost PUBLIC rabit_mock_static)
|
add_subdirectory(${xgboost_SOURCE_DIR}/src)
|
||||||
if (MSVC)
|
target_link_libraries(objxgboost PUBLIC dmlc)
|
||||||
target_compile_options(rabit_mock_static PRIVATE
|
|
||||||
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
|
||||||
endif (MSVC)
|
|
||||||
else()
|
|
||||||
target_link_libraries(objxgboost PUBLIC rabit)
|
|
||||||
if (MSVC)
|
|
||||||
target_compile_options(rabit PRIVATE
|
|
||||||
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
|
|
||||||
endif (MSVC)
|
|
||||||
endif(RABIT_MOCK)
|
|
||||||
foreach(lib rabit rabit_base rabit_empty rabit_mock rabit_mock_static)
|
|
||||||
# Explicitly link dmlc to rabit, so that configured header (build_config.h)
|
|
||||||
# from dmlc is correctly applied to rabit.
|
|
||||||
if (TARGET ${lib})
|
|
||||||
target_link_libraries(${lib} dmlc ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
if (HIDE_CXX_SYMBOLS) # Hide all C++ symbols from Rabit
|
|
||||||
set_target_properties(${lib} PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
|
||||||
endif (HIDE_CXX_SYMBOLS)
|
|
||||||
if (ENABLE_ALL_WARNINGS)
|
|
||||||
target_compile_options(${lib} PRIVATE -Wall -Wextra)
|
|
||||||
endif (ENABLE_ALL_WARNINGS)
|
|
||||||
endif (TARGET ${lib})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Exports some R specific definitions and objects
|
# Exports some R specific definitions and objects
|
||||||
if (R_LIB)
|
if (R_LIB)
|
||||||
add_subdirectory(${xgboost_SOURCE_DIR}/R-package)
|
add_subdirectory(${xgboost_SOURCE_DIR}/R-package)
|
||||||
endif (R_LIB)
|
endif (R_LIB)
|
||||||
|
|
||||||
|
# This creates its own shared library `xgboost4j'.
|
||||||
|
if (JVM_BINDINGS)
|
||||||
|
add_subdirectory(${xgboost_SOURCE_DIR}/jvm-packages)
|
||||||
|
endif (JVM_BINDINGS)
|
||||||
|
|
||||||
# Plugin
|
# Plugin
|
||||||
add_subdirectory(${xgboost_SOURCE_DIR}/plugin)
|
add_subdirectory(${xgboost_SOURCE_DIR}/plugin)
|
||||||
|
|
||||||
|
if (PLUGIN_RMM)
|
||||||
|
find_package(rmm REQUIRED)
|
||||||
|
endif (PLUGIN_RMM)
|
||||||
|
|
||||||
#-- library
|
#-- library
|
||||||
if (BUILD_STATIC_LIB)
|
if (BUILD_STATIC_LIB)
|
||||||
add_library(xgboost STATIC)
|
add_library(xgboost STATIC)
|
||||||
@@ -197,47 +248,37 @@ else (BUILD_STATIC_LIB)
|
|||||||
add_library(xgboost SHARED)
|
add_library(xgboost SHARED)
|
||||||
endif (BUILD_STATIC_LIB)
|
endif (BUILD_STATIC_LIB)
|
||||||
target_link_libraries(xgboost PRIVATE objxgboost)
|
target_link_libraries(xgboost PRIVATE objxgboost)
|
||||||
|
|
||||||
if (USE_NVTX)
|
|
||||||
enable_nvtx(xgboost)
|
|
||||||
endif (USE_NVTX)
|
|
||||||
|
|
||||||
#-- Hide all C++ symbols
|
|
||||||
if (HIDE_CXX_SYMBOLS)
|
|
||||||
set_target_properties(objxgboost PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
|
||||||
set_target_properties(xgboost PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
|
||||||
endif (HIDE_CXX_SYMBOLS)
|
|
||||||
|
|
||||||
target_include_directories(xgboost
|
target_include_directories(xgboost
|
||||||
INTERFACE
|
INTERFACE
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
|
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/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
|
#-- End shared library
|
||||||
|
|
||||||
#-- CLI for xgboost
|
#-- CLI for xgboost
|
||||||
add_executable(runxgboost ${xgboost_SOURCE_DIR}/src/cli_main.cc)
|
add_executable(runxgboost ${xgboost_SOURCE_DIR}/src/cli_main.cc)
|
||||||
target_link_libraries(runxgboost PRIVATE objxgboost)
|
target_link_libraries(runxgboost PRIVATE objxgboost)
|
||||||
if (USE_NVTX)
|
|
||||||
enable_nvtx(runxgboost)
|
|
||||||
endif (USE_NVTX)
|
|
||||||
|
|
||||||
target_include_directories(runxgboost
|
target_include_directories(runxgboost
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${xgboost_SOURCE_DIR}/include
|
${xgboost_SOURCE_DIR}/include
|
||||||
${xgboost_SOURCE_DIR}/dmlc-core/include
|
${xgboost_SOURCE_DIR}/dmlc-core/include
|
||||||
${xgboost_SOURCE_DIR}/rabit/include)
|
${xgboost_SOURCE_DIR}/rabit/include
|
||||||
set_target_properties(
|
)
|
||||||
runxgboost PROPERTIES
|
set_target_properties(runxgboost PROPERTIES OUTPUT_NAME xgboost)
|
||||||
OUTPUT_NAME xgboost
|
|
||||||
CXX_STANDARD 14
|
|
||||||
CXX_STANDARD_REQUIRED ON)
|
|
||||||
#-- End CLI for 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(runxgboost ${xgboost_SOURCE_DIR})
|
||||||
set_output_directory(xgboost ${xgboost_SOURCE_DIR}/lib)
|
set_output_directory(xgboost ${xgboost_SOURCE_DIR}/lib)
|
||||||
# Ensure these two targets do not build simultaneously, as they produce outputs with conflicting names
|
# Ensure these two targets do not build simultaneously, as they produce outputs with conflicting names
|
||||||
@@ -262,12 +303,27 @@ if (BUILD_C_DOC)
|
|||||||
run_doxygen()
|
run_doxygen()
|
||||||
endif (BUILD_C_DOC)
|
endif (BUILD_C_DOC)
|
||||||
|
|
||||||
|
include(CPack)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
# Install all headers. Please note that currently the C++ headers does not form an "API".
|
# Install all headers. Please note that currently the C++ headers does not form an "API".
|
||||||
install(DIRECTORY ${xgboost_SOURCE_DIR}/include/xgboost
|
install(DIRECTORY ${xgboost_SOURCE_DIR}/include/xgboost
|
||||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
install(TARGETS xgboost runxgboost
|
# Install libraries. If `xgboost` is a static lib, specify `objxgboost` also, to avoid the
|
||||||
|
# following error:
|
||||||
|
#
|
||||||
|
# > install(EXPORT ...) includes target "xgboost" which requires target "objxgboost" that is not
|
||||||
|
# > in any export set.
|
||||||
|
#
|
||||||
|
# https://github.com/dmlc/xgboost/issues/6085
|
||||||
|
if (BUILD_STATIC_LIB)
|
||||||
|
set(INSTALL_TARGETS xgboost runxgboost objxgboost dmlc)
|
||||||
|
else (BUILD_STATIC_LIB)
|
||||||
|
set(INSTALL_TARGETS xgboost runxgboost)
|
||||||
|
endif (BUILD_STATIC_LIB)
|
||||||
|
|
||||||
|
install(TARGETS ${INSTALL_TARGETS}
|
||||||
EXPORT XGBoostTargets
|
EXPORT XGBoostTargets
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
@@ -289,7 +345,7 @@ write_basic_package_version_file(
|
|||||||
COMPATIBILITY AnyNewerVersion)
|
COMPATIBILITY AnyNewerVersion)
|
||||||
install(
|
install(
|
||||||
FILES
|
FILES
|
||||||
${CMAKE_BINARY_DIR}/cmake/xgboost-config.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/cmake/xgboost-config.cmake
|
||||||
${CMAKE_BINARY_DIR}/cmake/xgboost-config-version.cmake
|
${CMAKE_BINARY_DIR}/cmake/xgboost-config-version.cmake
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/xgboost)
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/xgboost)
|
||||||
|
|
||||||
@@ -297,12 +353,18 @@ install(
|
|||||||
if (GOOGLE_TEST)
|
if (GOOGLE_TEST)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
# Unittests.
|
# 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_subdirectory(${xgboost_SOURCE_DIR}/tests/cpp)
|
||||||
|
|
||||||
add_test(
|
add_test(
|
||||||
NAME TestXGBoostLib
|
NAME TestXGBoostLib
|
||||||
COMMAND testxgboost
|
COMMAND testxgboost
|
||||||
WORKING_DIRECTORY ${xgboost_BINARY_DIR})
|
WORKING_DIRECTORY ${xgboost_BINARY_DIR})
|
||||||
|
|
||||||
# CLI tests
|
# CLI tests
|
||||||
configure_file(
|
configure_file(
|
||||||
${xgboost_SOURCE_DIR}/tests/cli/machine.conf.in
|
${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.
|
- 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 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.
|
- 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 Tang](https://github.com/terrytangyuan), Akuity
|
||||||
- Yuan is a software engineer in Ant Group. He contributed mostly in R and Python packages.
|
- Yuan is a founding engineer at Akuity. He contributed mostly in R and Python packages.
|
||||||
* [Nan Zhu](https://github.com/CodingCat), Uber
|
* [Nan Zhu](https://github.com/CodingCat), Uber
|
||||||
- Nan is a software engineer in Uber. He contributed mostly in JVM packages.
|
- Nan is a software engineer in Uber. He contributed mostly in JVM packages.
|
||||||
* [Jiaming Yuan](https://github.com/trivialfis)
|
* [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
|
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:
|
Committers comes from contributors who:
|
||||||
* Made substantial contribution to the project.
|
* Made substantial contribution to the project.
|
||||||
* Willing to spent time on maintaining and lead 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 Seabold](https://github.com/jseabold)
|
||||||
- Skipper is the major contributor to the scikit-learn module of XGBoost.
|
- Skipper is the major contributor to the scikit-learn module of XGBoost.
|
||||||
* [Zygmunt Zając](https://github.com/zygmuntz)
|
* [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)
|
* [Ajinkya Kale](https://github.com/ajkl)
|
||||||
* [Boliang Chen](https://github.com/cblsjtu)
|
* [Boliang Chen](https://github.com/cblsjtu)
|
||||||
* [Yangqing Men](https://github.com/yanqingmen)
|
* [Yangqing Men](https://github.com/yanqingmen)
|
||||||
@@ -91,7 +91,7 @@ List of Contributors
|
|||||||
* [Henry Gouk](https://github.com/henrygouk)
|
* [Henry Gouk](https://github.com/henrygouk)
|
||||||
* [Pierre de Sahb](https://github.com/pdesahb)
|
* [Pierre de Sahb](https://github.com/pdesahb)
|
||||||
* [liuliang01](https://github.com/liuliang01)
|
* [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](https://github.com/BlueTea88)
|
||||||
- Andrew Thia implemented feature interaction constraints
|
- Andrew Thia implemented feature interaction constraints
|
||||||
* [Wei Tian](https://github.com/weitian)
|
* [Wei Tian](https://github.com/weitian)
|
||||||
|
|||||||
484
Jenkinsfile
vendored
484
Jenkinsfile
vendored
@@ -1,484 +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 {
|
|
||||||
checkoutSrcs()
|
|
||||||
commit_id = "${GIT_COMMIT}"
|
|
||||||
}
|
|
||||||
sh 'python3 tests/jenkins_get_approval.py'
|
|
||||||
stash name: 'srcs'
|
|
||||||
milestone ordinal: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Jenkins Linux: Formatting Check') {
|
|
||||||
agent none
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
parallel ([
|
|
||||||
'clang-tidy': { ClangTidy() },
|
|
||||||
'lint': { Lint() },
|
|
||||||
'sphinx-doc': { SphinxDoc() },
|
|
||||||
'doxygen': { Doxygen() }
|
|
||||||
])
|
|
||||||
}
|
|
||||||
milestone ordinal: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Jenkins Linux: Build') {
|
|
||||||
agent none
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
parallel ([
|
|
||||||
'build-cpu': { BuildCPU() },
|
|
||||||
'build-cpu-rabit-mock': { BuildCPUMock() },
|
|
||||||
'build-cpu-non-omp': { BuildCPUNonOmp() },
|
|
||||||
// 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-gpu-cuda11.0': { BuildCUDA(cuda_version: '11.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() }
|
|
||||||
])
|
|
||||||
}
|
|
||||||
milestone ordinal: 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Jenkins Linux: Test') {
|
|
||||||
agent none
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
parallel ([
|
|
||||||
'test-python-cpu': { TestPythonCPU() },
|
|
||||||
'test-python-gpu-cuda10.2': { TestPythonGPU(host_cuda_version: '10.2') },
|
|
||||||
'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-cpp-gpu-cuda10.2': { TestCppGPU(artifact_cuda_version: '10.2', host_cuda_version: '10.2') },
|
|
||||||
'test-cpp-gpu-cuda11.0': { TestCppGPU(artifact_cuda_version: '11.0', host_cuda_version: '11.0') },
|
|
||||||
'test-jvm-jdk8-cuda10.0': { CrossTestJVMwithJDKGPU(artifact_cuda_version: '10.0', host_cuda_version: '10.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') },
|
|
||||||
'test-r-3.5.3': { TestR(use_r35: true) }
|
|
||||||
])
|
|
||||||
}
|
|
||||||
milestone ordinal: 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Jenkins Linux: Deploy') {
|
|
||||||
agent none
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
parallel ([
|
|
||||||
'deploy-jvm-packages': { DeployJVMPackages(spark_version: '3.0.0') }
|
|
||||||
])
|
|
||||||
}
|
|
||||||
milestone ordinal: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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=10.1"
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} ${dockerArgs} python3 tests/ci_build/tidy.py
|
|
||||||
"""
|
|
||||||
deleteDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def Lint() {
|
|
||||||
node('linux && cpu') {
|
|
||||||
unstash name: 'srcs'
|
|
||||||
echo "Running lint..."
|
|
||||||
def container_type = "cpu"
|
|
||||||
def docker_binary = "docker"
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} bash -c "source activate cpu_test && make lint"
|
|
||||||
"""
|
|
||||||
deleteDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def SphinxDoc() {
|
|
||||||
node('linux && cpu') {
|
|
||||||
unstash name: 'srcs'
|
|
||||||
echo "Running sphinx-doc..."
|
|
||||||
def container_type = "cpu"
|
|
||||||
def docker_binary = "docker"
|
|
||||||
def docker_extra_params = "CI_DOCKER_EXTRA_PARAMS_INIT='-e SPHINX_GIT_BRANCH=${BRANCH_NAME}'"
|
|
||||||
sh """#!/bin/bash
|
|
||||||
${docker_extra_params} ${dockerRun} ${container_type} ${docker_binary} bash -c "source activate cpu_test && make -C doc html"
|
|
||||||
"""
|
|
||||||
deleteDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def Doxygen() {
|
|
||||||
node('linux && cpu') {
|
|
||||||
unstash name: 'srcs'
|
|
||||||
echo "Running doxygen..."
|
|
||||||
def container_type = "cpu"
|
|
||||||
def docker_binary = "docker"
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/doxygen.sh ${BRANCH_NAME}
|
|
||||||
"""
|
|
||||||
if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('release')) {
|
|
||||||
echo 'Uploading doc...'
|
|
||||||
s3Upload file: "build/${BRANCH_NAME}.tar.bz2", bucket: 'xgboost-docs', acl: 'PublicRead', path: "doxygen/${BRANCH_NAME}.tar.bz2"
|
|
||||||
}
|
|
||||||
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} build/testxgboost
|
|
||||||
"""
|
|
||||||
// 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} build/testxgboost
|
|
||||||
"""
|
|
||||||
|
|
||||||
stash name: 'xgboost_cli', 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 BuildCPUNonOmp() {
|
|
||||||
node('linux && cpu') {
|
|
||||||
unstash name: 'srcs'
|
|
||||||
echo "Build CPU without OpenMP"
|
|
||||||
def container_type = "cpu"
|
|
||||||
def docker_binary = "docker"
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/build_via_cmake.sh -DUSE_OPENMP=OFF
|
|
||||||
"""
|
|
||||||
echo "Running Non-OpenMP C++ test..."
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} build/testxgboost
|
|
||||||
"""
|
|
||||||
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=${args.cuda_version}"
|
|
||||||
def arch_flag = ""
|
|
||||||
if (env.BRANCH_NAME != 'master' && !(env.BRANCH_NAME.startsWith('release'))) {
|
|
||||||
arch_flag = "-DGPU_COMPUTE_VER=75"
|
|
||||||
}
|
|
||||||
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} manylinux2010_x86_64
|
|
||||||
"""
|
|
||||||
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'
|
|
||||||
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=${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/target/*.jar,jvm-packages/xgboost4j-spark/target/*.jar,jvm-packages/xgboost4j-example/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 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=${args.host_cuda_version}"
|
|
||||||
if (args.multi_gpu) {
|
|
||||||
echo "Using multiple GPUs"
|
|
||||||
// Allocate extra space in /dev/shm to enable NCCL
|
|
||||||
def docker_extra_params = "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
|
|
||||||
"""
|
|
||||||
} else {
|
|
||||||
echo "Using a single GPU"
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_python.sh gpu
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
deleteDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def TestCppRabit() {
|
|
||||||
node(nodeReq) {
|
|
||||||
unstash name: 'xgboost_rabit_tests'
|
|
||||||
unstash name: 'srcs'
|
|
||||||
echo "Test C++, rabit mock on"
|
|
||||||
def container_type = "cpu"
|
|
||||||
def docker_binary = "docker"
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} tests/ci_build/runxgb.sh xgboost tests/ci_build/approx.conf.in
|
|
||||||
"""
|
|
||||||
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=${args.host_cuda_version}"
|
|
||||||
sh "${dockerRun} ${container_type} ${docker_binary} ${docker_args} build/testxgboost"
|
|
||||||
deleteDir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def CrossTestJVMwithJDKGPU(args) {
|
|
||||||
def nodeReq = 'linux && mgpu'
|
|
||||||
node(nodeReq) {
|
|
||||||
unstash name: "xgboost4j_jar_gpu"
|
|
||||||
unstash name: 'srcs'
|
|
||||||
if (args.spark_version != null) {
|
|
||||||
echo "Test XGBoost4J on a machine with JDK ${args.jdk_version}, Spark ${args.spark_version}, CUDA ${args.host_cuda_version}"
|
|
||||||
} else {
|
|
||||||
echo "Test XGBoost4J on a machine with JDK ${args.jdk_version}, CUDA ${args.host_cuda_version}"
|
|
||||||
}
|
|
||||||
def container_type = "gpu_jvm"
|
|
||||||
def docker_binary = "nvidia-docker"
|
|
||||||
def docker_args = "--build-arg CUDA_VERSION=${args.host_cuda_version}"
|
|
||||||
sh "${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/test_jvm_gpu_cross.sh"
|
|
||||||
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 TestR(args) {
|
|
||||||
node('linux && cpu') {
|
|
||||||
unstash name: 'srcs'
|
|
||||||
echo "Test R package"
|
|
||||||
def container_type = "rproject"
|
|
||||||
def docker_binary = "docker"
|
|
||||||
def use_r35_flag = (args.use_r35) ? "1" : "0"
|
|
||||||
def docker_args = "--build-arg USE_R35=${use_r35_flag}"
|
|
||||||
sh """
|
|
||||||
${dockerRun} ${container_type} ${docker_binary} ${docker_args} tests/ci_build/build_test_rpkg.sh || tests/ci_build/print_r_stacktrace.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 docker tests/ci_build/deploy_jvm_packages.sh ${args.spark_version} 0
|
|
||||||
"""
|
|
||||||
sh """
|
|
||||||
${dockerRun} jvm_gpu_build docker --build-arg CUDA_VERSION=10.0 tests/ci_build/deploy_jvm_packages.sh ${args.spark_version} 1
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
checkoutSrcs()
|
|
||||||
commit_id = "${GIT_COMMIT}"
|
|
||||||
}
|
|
||||||
sh 'python3 tests/jenkins_get_approval.py'
|
|
||||||
stash name: 'srcs'
|
|
||||||
milestone ordinal: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Jenkins Win64: Build') {
|
|
||||||
agent none
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
parallel ([
|
|
||||||
'build-win64-cuda10.1': { BuildWin64() }
|
|
||||||
])
|
|
||||||
}
|
|
||||||
milestone ordinal: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Jenkins Win64: Test') {
|
|
||||||
agent none
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
parallel ([
|
|
||||||
'test-win64-cuda10.1': { TestWin64() },
|
|
||||||
])
|
|
||||||
}
|
|
||||||
milestone ordinal: 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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}
|
|
||||||
"""
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
20
Makefile
20
Makefile
@@ -86,6 +86,7 @@ cover: check
|
|||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) -rf build lib bin *~ */*~ */*/*~ */*/*/*~ */*.o */*/*.o */*/*/*.o #xgboost
|
$(RM) -rf build lib bin *~ */*~ */*/*~ */*/*/*~ */*.o */*/*.o */*/*/*.o #xgboost
|
||||||
$(RM) -rf build_tests *.gcov tests/cpp/xgboost_test
|
$(RM) -rf build_tests *.gcov tests/cpp/xgboost_test
|
||||||
@@ -122,26 +123,23 @@ Rpack: clean_all
|
|||||||
cp -r dmlc-core/include xgboost/src/dmlc-core/include
|
cp -r dmlc-core/include xgboost/src/dmlc-core/include
|
||||||
cp -r dmlc-core/src xgboost/src/dmlc-core/src
|
cp -r dmlc-core/src xgboost/src/dmlc-core/src
|
||||||
cp ./LICENSE xgboost
|
cp ./LICENSE xgboost
|
||||||
# Modify PKGROOT in Makevars.in
|
|
||||||
cat R-package/src/Makevars.in|sed '2s/.*/PKGROOT=./' > xgboost/src/Makevars.in
|
cat R-package/src/Makevars.in|sed '2s/.*/PKGROOT=./' > xgboost/src/Makevars.in
|
||||||
# Configure Makevars.win (Windows-specific Makevars, likely using MinGW)
|
cat R-package/src/Makevars.win|sed '2s/.*/PKGROOT=./' > xgboost/src/Makevars.win
|
||||||
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
|
|
||||||
rm -f xgboost/src/Makevars.win-e # OSX sed create this extra file; remove it
|
rm -f xgboost/src/Makevars.win-e # OSX sed create this extra file; remove it
|
||||||
bash R-package/remove_warning_suppression_pragma.sh
|
bash R-package/remove_warning_suppression_pragma.sh
|
||||||
|
bash xgboost/remove_warning_suppression_pragma.sh
|
||||||
rm 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
|
||||||
|
|
||||||
Rbuild: Rpack
|
Rbuild: Rpack
|
||||||
R CMD build --no-build-vignettes xgboost
|
$(R) CMD build xgboost
|
||||||
rm -rf xgboost
|
rm -rf xgboost
|
||||||
|
|
||||||
Rcheck: Rbuild
|
Rcheck: Rbuild
|
||||||
R CMD check xgboost*.tar.gz
|
$(R) CMD check --as-cran xgboost*.tar.gz
|
||||||
|
|
||||||
-include build/*.d
|
-include build/*.d
|
||||||
-include build/*/*.d
|
-include build/*/*.d
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
Package: xgboost
|
Package: xgboost
|
||||||
Type: Package
|
Type: Package
|
||||||
Title: Extreme Gradient Boosting
|
Title: Extreme Gradient Boosting
|
||||||
Version: 1.2.0.1
|
Version: 1.7.2.1
|
||||||
Date: 2020-02-21
|
Date: 2022-12-08
|
||||||
Authors@R: c(
|
Authors@R: c(
|
||||||
person("Tianqi", "Chen", role = c("aut"),
|
person("Tianqi", "Chen", role = c("aut"),
|
||||||
email = "tianqi.tchen@gmail.com"),
|
email = "tianqi.tchen@gmail.com"),
|
||||||
person("Tong", "He", role = c("aut", "cre"),
|
person("Tong", "He", role = c("aut"),
|
||||||
email = "hetong007@gmail.com"),
|
email = "hetong007@gmail.com"),
|
||||||
person("Michael", "Benesty", role = c("aut"),
|
person("Michael", "Benesty", role = c("aut"),
|
||||||
email = "michael@benesty.fr"),
|
email = "michael@benesty.fr"),
|
||||||
@@ -26,9 +26,12 @@ Authors@R: c(
|
|||||||
person("Min", "Lin", role = c("aut")),
|
person("Min", "Lin", role = c("aut")),
|
||||||
person("Yifeng", "Geng", role = c("aut")),
|
person("Yifeng", "Geng", role = c("aut")),
|
||||||
person("Yutian", "Li", 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"),
|
person("XGBoost contributors", role = c("cph"),
|
||||||
comment = "base XGBoost implementation")
|
comment = "base XGBoost implementation")
|
||||||
)
|
)
|
||||||
|
Maintainer: Jiaming Yuan <jm.yuan@outlook.com>
|
||||||
Description: Extreme Gradient Boosting, which is an efficient implementation
|
Description: Extreme Gradient Boosting, which is an efficient implementation
|
||||||
of the gradient boosting framework from Chen & Guestrin (2016) <doi:10.1145/2939672.2939785>.
|
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
|
This package is its R interface. The package includes efficient linear
|
||||||
@@ -53,16 +56,15 @@ Suggests:
|
|||||||
testthat,
|
testthat,
|
||||||
lintr,
|
lintr,
|
||||||
igraph (>= 1.0.1),
|
igraph (>= 1.0.1),
|
||||||
jsonlite,
|
|
||||||
float,
|
float,
|
||||||
crayon
|
crayon,
|
||||||
|
titanic
|
||||||
Depends:
|
Depends:
|
||||||
R (>= 3.3.0)
|
R (>= 3.3.0)
|
||||||
Imports:
|
Imports:
|
||||||
Matrix (>= 1.1-0),
|
Matrix (>= 1.1-0),
|
||||||
methods,
|
methods,
|
||||||
data.table (>= 1.9.6),
|
data.table (>= 1.9.6),
|
||||||
magrittr (>= 1.5),
|
jsonlite (>= 1.0),
|
||||||
stringi (>= 0.5.2)
|
RoxygenNote: 7.2.1
|
||||||
RoxygenNote: 7.1.1
|
|
||||||
SystemRequirements: GNU make, C++14
|
SystemRequirements: GNU make, C++14
|
||||||
|
|||||||
@@ -36,8 +36,10 @@ export(xgb.create.features)
|
|||||||
export(xgb.cv)
|
export(xgb.cv)
|
||||||
export(xgb.dump)
|
export(xgb.dump)
|
||||||
export(xgb.gblinear.history)
|
export(xgb.gblinear.history)
|
||||||
|
export(xgb.get.config)
|
||||||
export(xgb.ggplot.deepness)
|
export(xgb.ggplot.deepness)
|
||||||
export(xgb.ggplot.importance)
|
export(xgb.ggplot.importance)
|
||||||
|
export(xgb.ggplot.shap.summary)
|
||||||
export(xgb.importance)
|
export(xgb.importance)
|
||||||
export(xgb.load)
|
export(xgb.load)
|
||||||
export(xgb.load.raw)
|
export(xgb.load.raw)
|
||||||
@@ -46,10 +48,12 @@ export(xgb.plot.deepness)
|
|||||||
export(xgb.plot.importance)
|
export(xgb.plot.importance)
|
||||||
export(xgb.plot.multi.trees)
|
export(xgb.plot.multi.trees)
|
||||||
export(xgb.plot.shap)
|
export(xgb.plot.shap)
|
||||||
|
export(xgb.plot.shap.summary)
|
||||||
export(xgb.plot.tree)
|
export(xgb.plot.tree)
|
||||||
export(xgb.save)
|
export(xgb.save)
|
||||||
export(xgb.save.raw)
|
export(xgb.save.raw)
|
||||||
export(xgb.serialize)
|
export(xgb.serialize)
|
||||||
|
export(xgb.set.config)
|
||||||
export(xgb.train)
|
export(xgb.train)
|
||||||
export(xgb.unserialize)
|
export(xgb.unserialize)
|
||||||
export(xgboost)
|
export(xgboost)
|
||||||
@@ -76,14 +80,10 @@ importFrom(graphics,lines)
|
|||||||
importFrom(graphics,par)
|
importFrom(graphics,par)
|
||||||
importFrom(graphics,points)
|
importFrom(graphics,points)
|
||||||
importFrom(graphics,title)
|
importFrom(graphics,title)
|
||||||
importFrom(magrittr,"%>%")
|
importFrom(jsonlite,fromJSON)
|
||||||
|
importFrom(jsonlite,toJSON)
|
||||||
importFrom(stats,median)
|
importFrom(stats,median)
|
||||||
importFrom(stats,predict)
|
importFrom(stats,predict)
|
||||||
importFrom(stringi,stri_detect_regex)
|
|
||||||
importFrom(stringi,stri_match_first_regex)
|
|
||||||
importFrom(stringi,stri_replace_all_regex)
|
|
||||||
importFrom(stringi,stri_replace_first_regex)
|
|
||||||
importFrom(stringi,stri_split_regex)
|
|
||||||
importFrom(utils,head)
|
importFrom(utils,head)
|
||||||
importFrom(utils,object.size)
|
importFrom(utils,object.size)
|
||||||
importFrom(utils,str)
|
importFrom(utils,str)
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ cb.reset.parameters <- function(new_params) {
|
|||||||
pnames <- gsub("\\.", "_", names(new_params))
|
pnames <- gsub("\\.", "_", names(new_params))
|
||||||
nrounds <- NULL
|
nrounds <- NULL
|
||||||
|
|
||||||
# run some checks in the begining
|
# run some checks in the beginning
|
||||||
init <- function(env) {
|
init <- function(env) {
|
||||||
nrounds <<- env$end_iteration - env$begin_iteration + 1
|
nrounds <<- env$end_iteration - env$begin_iteration + 1
|
||||||
|
|
||||||
@@ -263,10 +263,7 @@ cb.reset.parameters <- function(new_params) {
|
|||||||
#' \itemize{
|
#' \itemize{
|
||||||
#' \item \code{best_score} the evaluation score at the best iteration
|
#' \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_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:
|
#' The Same values are also stored as xgb-attributes:
|
||||||
#' \itemize{
|
#' \itemize{
|
||||||
#' \item \code{best_iteration} is stored as a 0-based iteration index (for interoperability of binary models)
|
#' \item \code{best_iteration} is stored as a 0-based iteration index (for interoperability of binary models)
|
||||||
@@ -352,9 +349,15 @@ cb.early.stop <- function(stopping_rounds, maximize = FALSE,
|
|||||||
finalizer <- function(env) {
|
finalizer <- function(env) {
|
||||||
if (!is.null(env$bst)) {
|
if (!is.null(env$bst)) {
|
||||||
attr_best_score <- as.numeric(xgb.attr(env$bst$handle, 'best_score'))
|
attr_best_score <- as.numeric(xgb.attr(env$bst$handle, 'best_score'))
|
||||||
if (best_score != attr_best_score)
|
if (best_score != attr_best_score) {
|
||||||
stop("Inconsistent 'best_score' values between the closure state: ", best_score,
|
# If the difference is too big, throw an error
|
||||||
" and the xgb.attr: ", attr_best_score)
|
if (abs(best_score - attr_best_score) >= 1e-14) {
|
||||||
|
stop("Inconsistent 'best_score' values between the closure state: ", best_score,
|
||||||
|
" and the xgb.attr: ", attr_best_score)
|
||||||
|
}
|
||||||
|
# If the difference is due to floating-point truncation, update best_score
|
||||||
|
best_score <- attr_best_score
|
||||||
|
}
|
||||||
env$bst$best_iteration <- best_iteration
|
env$bst$best_iteration <- best_iteration
|
||||||
env$bst$best_ntreelimit <- best_ntreelimit
|
env$bst$best_ntreelimit <- best_ntreelimit
|
||||||
env$bst$best_score <- best_score
|
env$bst$best_score <- best_score
|
||||||
@@ -492,13 +495,12 @@ cb.cv.predict <- function(save_models = FALSE) {
|
|||||||
rep(NA_real_, N)
|
rep(NA_real_, N)
|
||||||
}
|
}
|
||||||
|
|
||||||
ntreelimit <- NVL(env$basket$best_ntreelimit,
|
iterationrange <- c(1, NVL(env$basket$best_iteration, env$end_iteration) + 1)
|
||||||
env$end_iteration * env$num_parallel_tree)
|
|
||||||
if (NVL(env$params[['booster']], '') == 'gblinear') {
|
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) {
|
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)) {
|
if (is.matrix(pred)) {
|
||||||
pred[fd$index, ] <- pr
|
pred[fd$index, ] <- pr
|
||||||
} else {
|
} else {
|
||||||
@@ -527,7 +529,7 @@ cb.cv.predict <- function(save_models = FALSE) {
|
|||||||
#' Callback closure for collecting the model coefficients history of a gblinear booster
|
#' Callback closure for collecting the model coefficients history of a gblinear booster
|
||||||
#' during its training.
|
#' 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,
|
#' 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
|
#' when using the "thrifty" feature selector with fairly small number of top features
|
||||||
#' selected per iteration.
|
#' selected per iteration.
|
||||||
@@ -542,9 +544,11 @@ cb.cv.predict <- function(save_models = FALSE) {
|
|||||||
#'
|
#'
|
||||||
#' @return
|
#' @return
|
||||||
#' Results are stored in the \code{coefs} element of the closure.
|
#' 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.
|
#' 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
|
#' @seealso
|
||||||
#' \code{\link{callbacks}}, \code{\link{xgb.gblinear.history}}.
|
#' \code{\link{callbacks}}, \code{\link{xgb.gblinear.history}}.
|
||||||
@@ -554,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
|
#' # In the iris dataset, it is hard to linearly separate Versicolor class from the rest
|
||||||
#' # without considering the 2nd order interactions:
|
#' # without considering the 2nd order interactions:
|
||||||
#' require(magrittr)
|
|
||||||
#' x <- model.matrix(Species ~ .^2, iris)[,-1]
|
#' x <- model.matrix(Species ~ .^2, iris)[,-1]
|
||||||
#' colnames(x)
|
#' 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",
|
#' param <- list(booster = "gblinear", objective = "reg:logistic", eval_metric = "auc",
|
||||||
#' lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
#' lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||||
#' # For 'shotgun', which is a default linear updater, using high eta values may result in
|
#' # For 'shotgun', which is a default linear updater, using high eta values may result in
|
||||||
@@ -575,21 +578,21 @@ cb.cv.predict <- function(save_models = FALSE) {
|
|||||||
#' bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 200, eta = 0.8,
|
#' bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 200, eta = 0.8,
|
||||||
#' updater = 'coord_descent', feature_selector = 'thrifty', top_k = 1,
|
#' updater = 'coord_descent', feature_selector = 'thrifty', top_k = 1,
|
||||||
#' callbacks = list(cb.gblinear.history()))
|
#' 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.
|
#' # Componentwise boosting is known to have similar effect to Lasso regularization.
|
||||||
#' # Try experimenting with various values of top_k, eta, nrounds,
|
#' # Try experimenting with various values of top_k, eta, nrounds,
|
||||||
#' # as well as different feature_selectors.
|
#' # as well as different feature_selectors.
|
||||||
#'
|
#'
|
||||||
#' # For xgb.cv:
|
#' # For xgb.cv:
|
||||||
#' bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 100, eta = 0.8,
|
#' 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
|
#' # coefficients in the CV fold #3
|
||||||
#' xgb.gblinear.history(bst)[[3]] %>% matplot(type = 'l')
|
#' matplot(xgb.gblinear.history(bst)[[3]], type = 'l')
|
||||||
#'
|
#'
|
||||||
#'
|
#'
|
||||||
#' #### Multiclass classification:
|
#' #### 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,
|
#' param <- list(booster = "gblinear", objective = "multi:softprob", num_class = 3,
|
||||||
#' lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
#' lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||||
#' # For the default linear updater 'shotgun' it sometimes is helpful
|
#' # For the default linear updater 'shotgun' it sometimes is helpful
|
||||||
@@ -597,15 +600,15 @@ cb.cv.predict <- function(save_models = FALSE) {
|
|||||||
#' bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 70, eta = 0.5,
|
#' bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 70, eta = 0.5,
|
||||||
#' callbacks = list(cb.gblinear.history()))
|
#' callbacks = list(cb.gblinear.history()))
|
||||||
#' # Will plot the coefficient paths separately for each class:
|
#' # Will plot the coefficient paths separately for each class:
|
||||||
#' xgb.gblinear.history(bst, class_index = 0) %>% matplot(type = 'l')
|
#' matplot(xgb.gblinear.history(bst, class_index = 0), type = 'l')
|
||||||
#' xgb.gblinear.history(bst, class_index = 1) %>% matplot(type = 'l')
|
#' matplot(xgb.gblinear.history(bst, class_index = 1), type = 'l')
|
||||||
#' xgb.gblinear.history(bst, class_index = 2) %>% matplot(type = 'l')
|
#' matplot(xgb.gblinear.history(bst, class_index = 2), type = 'l')
|
||||||
#'
|
#'
|
||||||
#' # CV:
|
#' # CV:
|
||||||
#' bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 70, eta = 0.5,
|
#' bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 70, eta = 0.5,
|
||||||
#' callbacks = list(cb.gblinear.history(FALSE)))
|
#' callbacks = list(cb.gblinear.history(FALSE)))
|
||||||
#' # 1st forld of 1st class
|
#' # 1st fold of 1st class
|
||||||
#' xgb.gblinear.history(bst, class_index = 0)[[1]] %>% matplot(type = 'l')
|
#' matplot(xgb.gblinear.history(bst, class_index = 0)[[1]], type = 'l')
|
||||||
#'
|
#'
|
||||||
#' @export
|
#' @export
|
||||||
cb.gblinear.history <- function(sparse=FALSE) {
|
cb.gblinear.history <- function(sparse=FALSE) {
|
||||||
@@ -636,9 +639,14 @@ cb.gblinear.history <- function(sparse=FALSE) {
|
|||||||
if (!is.null(env$bst)) { # # xgb.train:
|
if (!is.null(env$bst)) { # # xgb.train:
|
||||||
coefs <<- list2mat(coefs)
|
coefs <<- list2mat(coefs)
|
||||||
} else { # xgb.cv:
|
} else { # xgb.cv:
|
||||||
# first lapply transposes the list
|
# second lapply transposes the list
|
||||||
coefs <<- lapply(seq_along(coefs[[1]]), function(i) lapply(coefs, "[[", i)) %>%
|
coefs <<- lapply(
|
||||||
lapply(function(x) list2mat(x))
|
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
|
# This file is for the low level reusable utility functions
|
||||||
# that are not supposed to be visibe to a user.
|
# that are not supposed to be visible to a user.
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -20,6 +20,12 @@ NVL <- function(x, val) {
|
|||||||
stop("typeof(x) == ", typeof(x), " is not supported by NVL")
|
stop("typeof(x) == ", typeof(x), " is not supported by NVL")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# List of classification and ranking objectives
|
||||||
|
.CLASSIFICATION_OBJECTIVES <- function() {
|
||||||
|
return(c('binary:logistic', 'binary:logitraw', 'binary:hinge', 'multi:softmax',
|
||||||
|
'multi:softprob', 'rank:pairwise', 'rank:ndcg', 'rank:map'))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Low-level functions for boosting --------------------------------------------
|
# Low-level functions for boosting --------------------------------------------
|
||||||
@@ -167,13 +173,13 @@ xgb.iter.eval <- function(booster_handle, watchlist, iter, feval = NULL) {
|
|||||||
evnames <- names(watchlist)
|
evnames <- names(watchlist)
|
||||||
if (is.null(feval)) {
|
if (is.null(feval)) {
|
||||||
msg <- .Call(XGBoosterEvalOneIter_R, booster_handle, as.integer(iter), watchlist, as.list(evnames))
|
msg <- .Call(XGBoosterEvalOneIter_R, booster_handle, as.integer(iter), watchlist, as.list(evnames))
|
||||||
msg <- stri_split_regex(msg, '(\\s+|:|\\s+)')[[1]][-1]
|
mat <- matrix(strsplit(msg, '\\s+|:')[[1]][-1], nrow = 2)
|
||||||
res <- as.numeric(msg[c(FALSE, TRUE)]) # even indices are the values
|
res <- structure(as.numeric(mat[2, ]), names = mat[1, ])
|
||||||
names(res) <- msg[c(TRUE, FALSE)] # odds are the names
|
|
||||||
} else {
|
} else {
|
||||||
res <- sapply(seq_along(watchlist), function(j) {
|
res <- sapply(seq_along(watchlist), function(j) {
|
||||||
w <- watchlist[[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)
|
eval_res <- feval(preds, w)
|
||||||
out <- eval_res$value
|
out <- eval_res$value
|
||||||
names(out) <- paste0(evnames[j], "-", eval_res$metric)
|
names(out) <- paste0(evnames[j], "-", eval_res$metric)
|
||||||
@@ -188,13 +194,23 @@ xgb.iter.eval <- function(booster_handle, watchlist, iter, feval = NULL) {
|
|||||||
# Helper functions for cross validation ---------------------------------------
|
# Helper functions for cross validation ---------------------------------------
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Possibly convert the labels into factors, depending on the objective.
|
||||||
|
# The labels are converted into factors only when the given objective refers to the classification
|
||||||
|
# or ranking tasks.
|
||||||
|
convert.labels <- function(labels, objective_name) {
|
||||||
|
if (objective_name %in% .CLASSIFICATION_OBJECTIVES()) {
|
||||||
|
return(as.factor(labels))
|
||||||
|
} else {
|
||||||
|
return(labels)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Generates random (stratified if needed) CV folds
|
# Generates random (stratified if needed) CV folds
|
||||||
generate.cv.folds <- function(nfold, nrows, stratified, label, params) {
|
generate.cv.folds <- function(nfold, nrows, stratified, label, params) {
|
||||||
|
|
||||||
# cannot do it for rank
|
# cannot do it for rank
|
||||||
if (exists('objective', where = params) &&
|
objective <- params$objective
|
||||||
is.character(params$objective) &&
|
if (is.character(objective) && strtrim(objective, 5) == 'rank:') {
|
||||||
strtrim(params$objective, 5) == 'rank:') {
|
|
||||||
stop("\n\tAutomatic generation of CV-folds is not implemented for ranking!\n",
|
stop("\n\tAutomatic generation of CV-folds is not implemented for ranking!\n",
|
||||||
"\tConsider providing pre-computed CV-folds through the 'folds=' parameter.\n")
|
"\tConsider providing pre-computed CV-folds through the 'folds=' parameter.\n")
|
||||||
}
|
}
|
||||||
@@ -207,19 +223,16 @@ generate.cv.folds <- function(nfold, nrows, stratified, label, params) {
|
|||||||
# - For classification, need to convert y labels to factor before making the folds,
|
# - For classification, need to convert y labels to factor before making the folds,
|
||||||
# and then do stratification by factor levels.
|
# and then do stratification by factor levels.
|
||||||
# - For regression, leave y numeric and do stratification by quantiles.
|
# - For regression, leave y numeric and do stratification by quantiles.
|
||||||
if (exists('objective', where = params) &&
|
if (is.character(objective)) {
|
||||||
is.character(params$objective)) {
|
y <- convert.labels(y, params$objective)
|
||||||
# If 'objective' provided in params, assume that y is a classification label
|
|
||||||
# unless objective is reg:squarederror
|
|
||||||
if (params$objective != 'reg:squarederror')
|
|
||||||
y <- factor(y)
|
|
||||||
} else {
|
} else {
|
||||||
# If no 'objective' given in params, it means that user either wants to
|
# If no 'objective' given in params, it means that user either wants to
|
||||||
# use the default 'reg:squarederror' objective or has provided a custom
|
# use the default 'reg:squarederror' objective or has provided a custom
|
||||||
# obj function. Here, assume classification setting when y has 5 or less
|
# obj function. Here, assume classification setting when y has 5 or less
|
||||||
# unique values:
|
# unique values:
|
||||||
if (length(unique(y)) <= 5)
|
if (length(unique(y)) <= 5) {
|
||||||
y <- factor(y)
|
y <- factor(y)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
folds <- xgb.createFolds(y, nfold)
|
folds <- xgb.createFolds(y, nfold)
|
||||||
} else {
|
} else {
|
||||||
@@ -272,7 +285,7 @@ xgb.createFolds <- function(y, k = 10)
|
|||||||
for (i in seq_along(numInClass)) {
|
for (i in seq_along(numInClass)) {
|
||||||
## create a vector of integers from 1:k as many times as possible without
|
## 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
|
## 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)
|
seqVector <- rep(seq_len(k), numInClass[i] %/% k)
|
||||||
## add enough random integers to get length(seqVector) == numInClass[i]
|
## add enough random integers to get length(seqVector) == numInClass[i]
|
||||||
if (numInClass[i] %% k > 0) seqVector <- c(seqVector, sample.int(k, numInClass[i] %% k))
|
if (numInClass[i] %% k > 0) seqVector <- c(seqVector, sample.int(k, numInClass[i] %% k))
|
||||||
@@ -349,6 +362,7 @@ NULL
|
|||||||
#' # Save as a stand-alone file (JSON); load it with xgb.load()
|
#' # Save as a stand-alone file (JSON); load it with xgb.load()
|
||||||
#' xgb.save(bst, 'xgb.model.json')
|
#' xgb.save(bst, 'xgb.model.json')
|
||||||
#' bst2 <- xgb.load('xgb.model.json')
|
#' bst2 <- xgb.load('xgb.model.json')
|
||||||
|
#' if (file.exists('xgb.model.json')) file.remove('xgb.model.json')
|
||||||
#'
|
#'
|
||||||
#' # Save as a raw byte vector; load it with xgb.load.raw()
|
#' # Save as a raw byte vector; load it with xgb.load.raw()
|
||||||
#' xgb_bytes <- xgb.save.raw(bst)
|
#' xgb_bytes <- xgb.save.raw(bst)
|
||||||
@@ -364,6 +378,7 @@ NULL
|
|||||||
#' obj2 <- readRDS('my_object.rds')
|
#' obj2 <- readRDS('my_object.rds')
|
||||||
#' # Re-construct xgb.Booster object from the bytes
|
#' # Re-construct xgb.Booster object from the bytes
|
||||||
#' bst2 <- xgb.load.raw(obj2$xgb_model_bytes)
|
#' bst2 <- xgb.load.raw(obj2$xgb_model_bytes)
|
||||||
|
#' if (file.exists('my_object.rds')) file.remove('my_object.rds')
|
||||||
#'
|
#'
|
||||||
#' @name a-compatibility-note-for-saveRDS-save
|
#' @name a-compatibility-note-for-saveRDS-save
|
||||||
NULL
|
NULL
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Construct an internal xgboost Booster and return a handle to it.
|
# Construct an internal xgboost Booster and return a handle to it.
|
||||||
# internal utility function
|
# internal utility function
|
||||||
xgb.Booster.handle <- function(params = list(), cachelist = list(),
|
xgb.Booster.handle <- function(params = list(), cachelist = list(),
|
||||||
modelfile = NULL) {
|
modelfile = NULL, handle = NULL) {
|
||||||
if (typeof(cachelist) != "list" ||
|
if (typeof(cachelist) != "list" ||
|
||||||
!all(vapply(cachelist, inherits, logical(1), what = 'xgb.DMatrix'))) {
|
!all(vapply(cachelist, inherits, logical(1), what = 'xgb.DMatrix'))) {
|
||||||
stop("cachelist must be a list of xgb.DMatrix objects")
|
stop("cachelist must be a list of xgb.DMatrix objects")
|
||||||
@@ -11,6 +11,7 @@ xgb.Booster.handle <- function(params = list(), cachelist = list(),
|
|||||||
if (typeof(modelfile) == "character") {
|
if (typeof(modelfile) == "character") {
|
||||||
## A filename
|
## A filename
|
||||||
handle <- .Call(XGBoosterCreate_R, cachelist)
|
handle <- .Call(XGBoosterCreate_R, cachelist)
|
||||||
|
modelfile <- path.expand(modelfile)
|
||||||
.Call(XGBoosterLoadModel_R, handle, modelfile[1])
|
.Call(XGBoosterLoadModel_R, handle, modelfile[1])
|
||||||
class(handle) <- "xgb.Booster.handle"
|
class(handle) <- "xgb.Booster.handle"
|
||||||
if (length(params) > 0) {
|
if (length(params) > 0) {
|
||||||
@@ -19,7 +20,7 @@ xgb.Booster.handle <- function(params = list(), cachelist = list(),
|
|||||||
return(handle)
|
return(handle)
|
||||||
} else if (typeof(modelfile) == "raw") {
|
} else if (typeof(modelfile) == "raw") {
|
||||||
## A memory buffer
|
## A memory buffer
|
||||||
bst <- xgb.unserialize(modelfile)
|
bst <- xgb.unserialize(modelfile, handle)
|
||||||
xgb.parameters(bst) <- params
|
xgb.parameters(bst) <- params
|
||||||
return (bst)
|
return (bst)
|
||||||
} else if (inherits(modelfile, "xgb.Booster")) {
|
} else if (inherits(modelfile, "xgb.Booster")) {
|
||||||
@@ -128,7 +129,7 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
|||||||
stop("argument type must be xgb.Booster")
|
stop("argument type must be xgb.Booster")
|
||||||
|
|
||||||
if (is.null.handle(object$handle)) {
|
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 {
|
} else {
|
||||||
if (is.null(object$raw) && saveraw) {
|
if (is.null(object$raw) && saveraw) {
|
||||||
object$raw <- xgb.serialize(object$handle)
|
object$raw <- xgb.serialize(object$handle)
|
||||||
@@ -161,14 +162,17 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
|||||||
#' Predicted values based on either xgboost model or model handle object.
|
#' 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 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
|
#' @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).
|
#' 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
|
#' @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
|
#' 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.
|
#' 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).
|
#' @param ntreelimit Deprecated, use \code{iterationrange} instead.
|
||||||
#' It will use all the trees by default (\code{NULL} value).
|
|
||||||
#' @param predleaf whether predict leaf index.
|
#' @param predleaf whether predict leaf index.
|
||||||
#' @param predcontrib whether to return feature contributions to individual predictions (see Details).
|
#' @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).
|
#' @param approxcontrib whether to use a fast approximation for feature contributions (see Details).
|
||||||
@@ -178,16 +182,19 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
|||||||
#' or predinteraction flags is TRUE.
|
#' or predinteraction flags is TRUE.
|
||||||
#' @param training whether is the prediction result used for training. For dart booster,
|
#' @param training whether is the prediction result used for training. For dart booster,
|
||||||
#' training predicting will perform dropout.
|
#' 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}
|
#' @param ... Parameters passed to \code{predict.xgb.Booster}
|
||||||
#'
|
#'
|
||||||
#' @details
|
#' @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.
|
#' since gblinear doesn't keep its boosting history.
|
||||||
#'
|
#'
|
||||||
#' One possible practical applications of the \code{predleaf} option is to use the model
|
#' One possible practical applications of the \code{predleaf} option is to use the model
|
||||||
@@ -208,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.
|
#' of the most important features first. See below about the format of the returned results.
|
||||||
#'
|
#'
|
||||||
#' @return
|
#' @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
|
#' For multiclass classification, either a \code{num_class * nrows(newdata)} vector or
|
||||||
#' a \code{(nrows(newdata), num_class)} dimension matrix is returned, depending on
|
#' a \code{(nrows(newdata), num_class)} dimension matrix is returned, depending on
|
||||||
#' the \code{reshape} value.
|
#' the \code{reshape} value.
|
||||||
@@ -230,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
|
#' For a multiclass case, a list of \code{num_class} elements is returned, where each element is
|
||||||
#' such an array.
|
#' 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
|
#' @seealso
|
||||||
#' \code{\link{xgb.train}}.
|
#' \code{\link{xgb.train}}.
|
||||||
#'
|
#'
|
||||||
@@ -252,7 +267,7 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
|||||||
#' # use all trees by default
|
#' # use all trees by default
|
||||||
#' pred <- predict(bst, test$data)
|
#' pred <- predict(bst, test$data)
|
||||||
#' # use only the 1st tree
|
#' # use only the 1st tree
|
||||||
#' pred1 <- predict(bst, test$data, ntreelimit = 1)
|
#' pred1 <- predict(bst, test$data, iterationrange = c(1, 2))
|
||||||
#'
|
#'
|
||||||
#' # Predicting tree leafs:
|
#' # Predicting tree leafs:
|
||||||
#' # the result is an nsamples X ntrees matrix
|
#' # the result is an nsamples X ntrees matrix
|
||||||
@@ -304,31 +319,14 @@ xgb.Booster.complete <- function(object, saveraw = TRUE) {
|
|||||||
#' all.equal(pred, pred_labels)
|
#' all.equal(pred, pred_labels)
|
||||||
#' # prediction from using only 5 iterations should result
|
#' # prediction from using only 5 iterations should result
|
||||||
#' # in the same error as seen in iteration 5:
|
#' # 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)
|
#' 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
|
#' @rdname predict.xgb.Booster
|
||||||
#' @export
|
#' @export
|
||||||
predict.xgb.Booster <- function(object, newdata, missing = NA, outputmargin = FALSE, ntreelimit = NULL,
|
predict.xgb.Booster <- function(object, newdata, missing = NA, outputmargin = FALSE, ntreelimit = NULL,
|
||||||
predleaf = FALSE, predcontrib = FALSE, approxcontrib = FALSE, predinteraction = FALSE,
|
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)
|
object <- xgb.Booster.complete(object, saveraw = FALSE)
|
||||||
if (!inherits(newdata, "xgb.DMatrix"))
|
if (!inherits(newdata, "xgb.DMatrix"))
|
||||||
newdata <- xgb.DMatrix(newdata, missing = missing)
|
newdata <- xgb.DMatrix(newdata, missing = missing)
|
||||||
@@ -336,62 +334,136 @@ predict.xgb.Booster <- function(object, newdata, missing = NA, outputmargin = FA
|
|||||||
!is.null(colnames(newdata)) &&
|
!is.null(colnames(newdata)) &&
|
||||||
!identical(object[["feature_names"]], colnames(newdata)))
|
!identical(object[["feature_names"]], colnames(newdata)))
|
||||||
stop("Feature names stored in `object` and `newdata` are different!")
|
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' || is.null(ntreelimit))
|
||||||
if (NVL(object$params[['booster']], '') == 'gblinear')
|
|
||||||
ntreelimit <- 0
|
ntreelimit <- 0
|
||||||
if (ntreelimit < 0)
|
|
||||||
stop("ntreelimit cannot be negative")
|
|
||||||
|
|
||||||
option <- 0L + 1L * as.logical(outputmargin) + 2L * as.logical(predleaf) + 4L * as.logical(predcontrib) +
|
if (ntreelimit != 0 && is.null(iterationrange)) {
|
||||||
8L * as.logical(approxcontrib) + 16L * as.logical(predinteraction)
|
## 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],
|
## We set strict_shape to TRUE then drop the dimensions conditionally
|
||||||
as.integer(ntreelimit), as.integer(training))
|
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_ret <- length(ret)
|
||||||
n_row <- nrow(newdata)
|
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)
|
arr <- array(data = ret, dim = rev(shape))
|
||||||
stop("prediction length ", n_ret, " is not multiple of nrows(newdata) ", n_row)
|
|
||||||
|
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) {
|
if (predleaf) {
|
||||||
ret <- if (n_ret == n_row) {
|
## Predict leaf
|
||||||
matrix(ret, ncol = 1)
|
arr <- if (n_ret == n_row) {
|
||||||
|
matrix(arr, ncol = 1)
|
||||||
} else {
|
} else {
|
||||||
matrix(ret, nrow = n_row, byrow = TRUE)
|
matrix(arr, nrow = n_row, byrow = TRUE)
|
||||||
}
|
}
|
||||||
} else if (predcontrib) {
|
} else if (predcontrib) {
|
||||||
n_col1 <- ncol(newdata) + 1
|
## Predict contribution
|
||||||
n_group <- npred_per_case / n_col1
|
arr <- aperm(a = arr, perm = c(2, 3, 1)) # [group, row, col]
|
||||||
cnames <- if (!is.null(colnames(newdata))) c(colnames(newdata), "BIAS") else NULL
|
arr <- if (n_ret == n_row) {
|
||||||
ret <- if (n_ret == n_row) {
|
matrix(arr, ncol = 1, dimnames = list(NULL, cnames))
|
||||||
matrix(ret, ncol = 1, dimnames = list(NULL, cnames))
|
} else if (n_groups != 1) {
|
||||||
} else if (n_group == 1) {
|
## turns array into list of matrices
|
||||||
matrix(ret, nrow = n_row, byrow = TRUE, dimnames = list(NULL, cnames))
|
lapply(seq_len(n_groups), function(g) arr[g, , ])
|
||||||
} else {
|
} else {
|
||||||
arr <- array(ret, c(n_col1, n_group, n_row),
|
## remove the first axis (group)
|
||||||
dimnames = list(cnames, NULL, NULL)) %>% aperm(c(2, 3, 1)) # [group, row, col]
|
dn <- dimnames(arr)
|
||||||
lapply(seq_len(n_group), function(g) arr[g, , ])
|
matrix(arr[1, , ], nrow = dim(arr)[2], ncol = dim(arr)[3], dimnames = c(dn[2], dn[3]))
|
||||||
}
|
}
|
||||||
} else if (predinteraction) {
|
} else if (predinteraction) {
|
||||||
n_col1 <- ncol(newdata) + 1
|
## Predict interaction
|
||||||
n_group <- npred_per_case / n_col1^2
|
arr <- aperm(a = arr, perm = c(3, 4, 1, 2)) # [group, row, col, col]
|
||||||
cnames <- if (!is.null(colnames(newdata))) c(colnames(newdata), "BIAS") else NULL
|
arr <- if (n_ret == n_row) {
|
||||||
ret <- if (n_ret == n_row) {
|
matrix(arr, ncol = 1, dimnames = list(NULL, cnames))
|
||||||
matrix(ret, ncol = 1, dimnames = list(NULL, cnames))
|
} else if (n_groups != 1) {
|
||||||
} else if (n_group == 1) {
|
## turns array into list of matrices
|
||||||
array(ret, c(n_col1, n_col1, n_row), dimnames = list(cnames, cnames, NULL)) %>% aperm(c(3, 1, 2))
|
lapply(seq_len(n_groups), function(g) arr[g, , , ])
|
||||||
} else {
|
} else {
|
||||||
arr <- array(ret, c(n_col1, n_col1, n_group, n_row),
|
## remove the first axis (group)
|
||||||
dimnames = list(cnames, cnames, NULL, NULL)) %>% aperm(c(3, 4, 1, 2)) # [group, row, col1, col2]
|
arr <- arr[1, , , , drop = FALSE]
|
||||||
lapply(seq_len(n_group), function(g) arr[g, , , ])
|
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
|
#' @rdname predict.xgb.Booster
|
||||||
|
|||||||
@@ -1,44 +1,63 @@
|
|||||||
#' Construct xgb.DMatrix object
|
#' Construct xgb.DMatrix object
|
||||||
#'
|
#'
|
||||||
#' Construct xgb.DMatrix object from either a dense matrix, a sparse matrix, or a local file.
|
#' 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}}).
|
#' \code{\link{xgb.DMatrix.save}}).
|
||||||
#'
|
#'
|
||||||
#' @param data a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object, or a character
|
#' @param data a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object,
|
||||||
#' string representing a filename.
|
#' 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.
|
#' @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
|
#' 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).
|
#' @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.
|
#' 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 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.
|
#' @param ... the \code{info} data could be passed directly as parameters, without creating an \code{info} list.
|
||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
#' xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
#' xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||||
#' dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
#' dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||||
#' if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
#' if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
||||||
#' @export
|
#' @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
|
cnames <- NULL
|
||||||
if (typeof(data) == "character") {
|
if (typeof(data) == "character") {
|
||||||
if (length(data) > 1)
|
if (length(data) > 1)
|
||||||
stop("'data' has class 'character' and length ", length(data),
|
stop("'data' has class 'character' and length ", length(data),
|
||||||
".\n 'data' accepts either a numeric matrix or a single filename.")
|
".\n 'data' accepts either a numeric matrix or a single filename.")
|
||||||
|
data <- path.expand(data)
|
||||||
handle <- .Call(XGDMatrixCreateFromFile_R, data, as.integer(silent))
|
handle <- .Call(XGDMatrixCreateFromFile_R, data, as.integer(silent))
|
||||||
} else if (is.matrix(data)) {
|
} 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)
|
cnames <- colnames(data)
|
||||||
} else if (inherits(data, "dgCMatrix")) {
|
} 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)
|
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 {
|
} else {
|
||||||
stop("xgb.DMatrix does not support construction from ", typeof(data))
|
stop("xgb.DMatrix does not support construction from ", typeof(data))
|
||||||
}
|
}
|
||||||
dmat <- handle
|
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(...))
|
info <- append(info, list(...))
|
||||||
for (i in seq_along(info)) {
|
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
|
# get dmatrix from data, label
|
||||||
# internal helper method
|
# 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 (inherits(data, "dgCMatrix") || is.matrix(data)) {
|
||||||
if (is.null(label)) {
|
if (is.null(label)) {
|
||||||
stop("label must be provided when data is a matrix")
|
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)){
|
if (!is.null(weight)){
|
||||||
setinfo(dtrain, "weight", weight)
|
setinfo(dtrain, "weight", weight)
|
||||||
}
|
}
|
||||||
@@ -65,6 +84,7 @@ xgb.get.DMatrix <- function(data, label = NULL, missing = NA, weight = NULL) {
|
|||||||
warning("xgboost: label will be ignored.")
|
warning("xgboost: label will be ignored.")
|
||||||
}
|
}
|
||||||
if (is.character(data)) {
|
if (is.character(data)) {
|
||||||
|
data <- path.expand(data)
|
||||||
dtrain <- xgb.DMatrix(data[1])
|
dtrain <- xgb.DMatrix(data[1])
|
||||||
} else if (inherits(data, "xgb.DMatrix")) {
|
} else if (inherits(data, "xgb.DMatrix")) {
|
||||||
dtrain <- data
|
dtrain <- data
|
||||||
@@ -90,7 +110,7 @@ xgb.get.DMatrix <- function(data, label = NULL, missing = NA, weight = NULL) {
|
|||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' 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(nrow(dtrain) == nrow(train$data))
|
||||||
#' stopifnot(ncol(dtrain) == ncol(train$data))
|
#' stopifnot(ncol(dtrain) == ncol(train$data))
|
||||||
@@ -118,7 +138,7 @@ dim.xgb.DMatrix <- function(x) {
|
|||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' train <- agaricus.train
|
||||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
#' dtrain <- xgb.DMatrix(train$data, label=train$label, nthread = 2)
|
||||||
#' dimnames(dtrain)
|
#' dimnames(dtrain)
|
||||||
#' colnames(dtrain)
|
#' colnames(dtrain)
|
||||||
#' colnames(dtrain) <- make.names(1:ncol(train$data))
|
#' colnames(dtrain) <- make.names(1:ncol(train$data))
|
||||||
@@ -127,7 +147,9 @@ dim.xgb.DMatrix <- function(x) {
|
|||||||
#' @rdname dimnames.xgb.DMatrix
|
#' @rdname dimnames.xgb.DMatrix
|
||||||
#' @export
|
#' @export
|
||||||
dimnames.xgb.DMatrix <- function(x) {
|
dimnames.xgb.DMatrix <- function(x) {
|
||||||
attr(x, '.Dimnames')
|
fn <- getinfo(x, "feature_name")
|
||||||
|
## row names is null.
|
||||||
|
list(NULL, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
#' @rdname dimnames.xgb.DMatrix
|
#' @rdname dimnames.xgb.DMatrix
|
||||||
@@ -138,13 +160,13 @@ dimnames.xgb.DMatrix <- function(x) {
|
|||||||
if (!is.null(value[[1L]]))
|
if (!is.null(value[[1L]]))
|
||||||
stop("xgb.DMatrix does not have rownames")
|
stop("xgb.DMatrix does not have rownames")
|
||||||
if (is.null(value[[2]])) {
|
if (is.null(value[[2]])) {
|
||||||
attr(x, '.Dimnames') <- NULL
|
setinfo(x, "feature_name", NULL)
|
||||||
return(x)
|
return(x)
|
||||||
}
|
}
|
||||||
if (ncol(x) != length(value[[2]]))
|
if (ncol(x) != length(value[[2]])) {
|
||||||
stop("can't assign ", length(value[[2]]), " colnames to a ",
|
stop("can't assign ", length(value[[2]]), " colnames to a ", ncol(x), " column xgb.DMatrix")
|
||||||
ncol(x), " column xgb.DMatrix")
|
}
|
||||||
attr(x, '.Dimnames') <- value
|
setinfo(x, "feature_name", value[[2]])
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,9 +182,9 @@ dimnames.xgb.DMatrix <- function(x) {
|
|||||||
#' The \code{name} field can be one of the following:
|
#' The \code{name} field can be one of the following:
|
||||||
#'
|
#'
|
||||||
#' \itemize{
|
#' \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{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}.
|
#' \item \code{nrow}: number of rows of the \code{xgb.DMatrix}.
|
||||||
#'
|
#'
|
||||||
#' }
|
#' }
|
||||||
@@ -171,8 +193,7 @@ dimnames.xgb.DMatrix <- function(x) {
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
#'
|
#'
|
||||||
#' labels <- getinfo(dtrain, 'label')
|
#' labels <- getinfo(dtrain, 'label')
|
||||||
#' setinfo(dtrain, 'label', 1-labels)
|
#' setinfo(dtrain, 'label', 1-labels)
|
||||||
@@ -187,13 +208,17 @@ getinfo <- function(object, ...) UseMethod("getinfo")
|
|||||||
#' @export
|
#' @export
|
||||||
getinfo.xgb.DMatrix <- function(object, name, ...) {
|
getinfo.xgb.DMatrix <- function(object, name, ...) {
|
||||||
if (typeof(name) != "character" ||
|
if (typeof(name) != "character" ||
|
||||||
length(name) != 1 ||
|
length(name) != 1 ||
|
||||||
!name %in% c('label', 'weight', 'base_margin', 'nrow',
|
!name %in% c('label', 'weight', 'base_margin', 'nrow',
|
||||||
'label_lower_bound', 'label_upper_bound')) {
|
'label_lower_bound', 'label_upper_bound', "feature_type", "feature_name")) {
|
||||||
stop("getinfo: name must be one of the following\n",
|
stop(
|
||||||
" 'label', 'weight', 'base_margin', 'nrow', 'label_lower_bound', 'label_upper_bound'")
|
"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)
|
ret <- .Call(XGDMatrixGetInfo_R, object, name)
|
||||||
} else {
|
} else {
|
||||||
ret <- nrow(object)
|
ret <- nrow(object)
|
||||||
@@ -216,16 +241,15 @@ getinfo.xgb.DMatrix <- function(object, name, ...) {
|
|||||||
#' The \code{name} field can be one of the following:
|
#' The \code{name} field can be one of the following:
|
||||||
#'
|
#'
|
||||||
#' \itemize{
|
#' \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{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).
|
#' \item \code{group}: number of rows in each group (to use with \code{rank:pairwise} objective).
|
||||||
#' }
|
#' }
|
||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
#'
|
#'
|
||||||
#' labels <- getinfo(dtrain, 'label')
|
#' labels <- getinfo(dtrain, 'label')
|
||||||
#' setinfo(dtrain, 'label', 1-labels)
|
#' setinfo(dtrain, 'label', 1-labels)
|
||||||
@@ -272,6 +296,37 @@ setinfo.xgb.DMatrix <- function(object, name, info, ...) {
|
|||||||
.Call(XGDMatrixSetInfo_R, object, name, as.integer(info))
|
.Call(XGDMatrixSetInfo_R, object, name, as.integer(info))
|
||||||
return(TRUE)
|
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)
|
stop("setinfo: unknown info name ", name)
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
}
|
}
|
||||||
@@ -290,8 +345,7 @@ setinfo.xgb.DMatrix <- function(object, name, info, ...) {
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
#'
|
#'
|
||||||
#' dsub <- slice(dtrain, 1:42)
|
#' dsub <- slice(dtrain, 1:42)
|
||||||
#' labels1 <- getinfo(dsub, 'label')
|
#' labels1 <- getinfo(dsub, 'label')
|
||||||
@@ -347,8 +401,7 @@ slice.xgb.DMatrix <- function(object, idxset, ...) {
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
#'
|
#'
|
||||||
#' dtrain
|
#' dtrain
|
||||||
#' print(dtrain, verbose=TRUE)
|
#' print(dtrain, verbose=TRUE)
|
||||||
@@ -357,7 +410,7 @@ slice.xgb.DMatrix <- function(object, idxset, ...) {
|
|||||||
#' @export
|
#' @export
|
||||||
print.xgb.DMatrix <- function(x, verbose = FALSE, ...) {
|
print.xgb.DMatrix <- function(x, verbose = FALSE, ...) {
|
||||||
cat('xgb.DMatrix dim:', nrow(x), 'x', ncol(x), ' info: ')
|
cat('xgb.DMatrix dim:', nrow(x), 'x', ncol(x), ' info: ')
|
||||||
infos <- c()
|
infos <- character(0)
|
||||||
if (length(getinfo(x, 'label')) > 0) infos <- 'label'
|
if (length(getinfo(x, 'label')) > 0) infos <- 'label'
|
||||||
if (length(getinfo(x, 'weight')) > 0) infos <- c(infos, 'weight')
|
if (length(getinfo(x, 'weight')) > 0) infos <- c(infos, 'weight')
|
||||||
if (length(getinfo(x, 'base_margin')) > 0) infos <- c(infos, 'base_margin')
|
if (length(getinfo(x, 'base_margin')) > 0) infos <- c(infos, 'base_margin')
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' train <- agaricus.train
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
#' xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
#' xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||||
#' dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
#' dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||||
#' if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
#' if (file.exists('xgb.DMatrix.data')) file.remove('xgb.DMatrix.data')
|
||||||
@@ -19,6 +18,7 @@ xgb.DMatrix.save <- function(dmatrix, fname) {
|
|||||||
if (!inherits(dmatrix, "xgb.DMatrix"))
|
if (!inherits(dmatrix, "xgb.DMatrix"))
|
||||||
stop("dmatrix must be xgb.DMatrix")
|
stop("dmatrix must be xgb.DMatrix")
|
||||||
|
|
||||||
|
fname <- path.expand(fname)
|
||||||
.Call(XGDMatrixSaveBinary_R, dmatrix, fname[1], 0L)
|
.Call(XGDMatrixSaveBinary_R, dmatrix, fname[1], 0L)
|
||||||
return(TRUE)
|
return(TRUE)
|
||||||
}
|
}
|
||||||
|
|||||||
38
R-package/R/xgb.config.R
Normal file
38
R-package/R/xgb.config.R
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#' Global configuration consists of a collection of parameters that can be applied in the global
|
||||||
|
#' scope. See \url{https://xgboost.readthedocs.io/en/stable/parameter.html} for the full list of
|
||||||
|
#' parameters supported in the global configuration. Use \code{xgb.set.config} to update the
|
||||||
|
#' values of one or more global-scope parameters. Use \code{xgb.get.config} to fetch the current
|
||||||
|
#' values of all global-scope parameters (listed in
|
||||||
|
#' \url{https://xgboost.readthedocs.io/en/stable/parameter.html}).
|
||||||
|
#'
|
||||||
|
#' @rdname xgbConfig
|
||||||
|
#' @title Set and get global configuration
|
||||||
|
#' @name xgb.set.config, xgb.get.config
|
||||||
|
#' @export xgb.set.config xgb.get.config
|
||||||
|
#' @param ... List of parameters to be set, as keyword arguments
|
||||||
|
#' @return
|
||||||
|
#' \code{xgb.set.config} returns \code{TRUE} to signal success. \code{xgb.get.config} returns
|
||||||
|
#' a list containing all global-scope parameters and their values.
|
||||||
|
#'
|
||||||
|
#' @examples
|
||||||
|
#' # Set verbosity level to silent (0)
|
||||||
|
#' xgb.set.config(verbosity = 0)
|
||||||
|
#' # Now global verbosity level is 0
|
||||||
|
#' config <- xgb.get.config()
|
||||||
|
#' print(config$verbosity)
|
||||||
|
#' # Set verbosity level to warning (1)
|
||||||
|
#' xgb.set.config(verbosity = 1)
|
||||||
|
#' # Now global verbosity level is 1
|
||||||
|
#' config <- xgb.get.config()
|
||||||
|
#' print(config$verbosity)
|
||||||
|
xgb.set.config <- function(...) {
|
||||||
|
new_config <- list(...)
|
||||||
|
.Call(XGBSetGlobalConfig_R, jsonlite::toJSON(new_config, auto_unbox = TRUE))
|
||||||
|
return(TRUE)
|
||||||
|
}
|
||||||
|
|
||||||
|
#' @rdname xgbConfig
|
||||||
|
xgb.get.config <- function() {
|
||||||
|
config <- .Call(XGBGetGlobalConfig_R)
|
||||||
|
return(jsonlite::fromJSON(config))
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
#'
|
#'
|
||||||
#' International Workshop on Data Mining for Online Advertising (ADKDD) - August 24, 2014
|
#' 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:
|
#' Extract explaining the method:
|
||||||
#'
|
#'
|
||||||
@@ -48,8 +48,8 @@
|
|||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' data(agaricus.test, package='xgboost')
|
#' data(agaricus.test, package='xgboost')
|
||||||
#' dtrain <- xgb.DMatrix(data = agaricus.train$data, label = agaricus.train$label)
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtest <- xgb.DMatrix(data = agaricus.test$data, label = agaricus.test$label)
|
#' dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#'
|
#'
|
||||||
#' param <- list(max_depth=2, eta=1, silent=1, objective='binary:logistic')
|
#' param <- list(max_depth=2, eta=1, silent=1, objective='binary:logistic')
|
||||||
#' nrounds = 4
|
#' nrounds = 4
|
||||||
@@ -65,8 +65,12 @@
|
|||||||
#' new.features.test <- xgb.create.features(model = bst, agaricus.test$data)
|
#' new.features.test <- xgb.create.features(model = bst, agaricus.test$data)
|
||||||
#'
|
#'
|
||||||
#' # learning with new features
|
#' # learning with new features
|
||||||
#' new.dtrain <- xgb.DMatrix(data = new.features.train, label = agaricus.train$label)
|
#' new.dtrain <- xgb.DMatrix(
|
||||||
#' new.dtest <- xgb.DMatrix(data = new.features.test, label = agaricus.test$label)
|
#' 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)
|
#' watchlist <- list(train = new.dtrain)
|
||||||
#' bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
#' bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
||||||
#'
|
#'
|
||||||
@@ -79,7 +83,7 @@
|
|||||||
#' accuracy.after, "!\n"))
|
#' accuracy.after, "!\n"))
|
||||||
#'
|
#'
|
||||||
#' @export
|
#' @export
|
||||||
xgb.create.features <- function(model, data, ...){
|
xgb.create.features <- function(model, data, ...) {
|
||||||
check.deprecation(...)
|
check.deprecation(...)
|
||||||
pred_with_leaf <- predict(model, data, predleaf = TRUE)
|
pred_with_leaf <- predict(model, data, predleaf = TRUE)
|
||||||
cols <- lapply(as.data.frame(pred_with_leaf), factor)
|
cols <- lapply(as.data.frame(pred_with_leaf), factor)
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#' \item \code{error} binary classification error rate
|
#' \item \code{error} binary classification error rate
|
||||||
#' \item \code{rmse} Rooted mean square error
|
#' \item \code{rmse} Rooted mean square error
|
||||||
#' \item \code{logloss} negative log-likelihood function
|
#' \item \code{logloss} negative log-likelihood function
|
||||||
|
#' \item \code{mae} Mean absolute error
|
||||||
|
#' \item \code{mape} Mean absolute percentage error
|
||||||
#' \item \code{auc} Area under curve
|
#' \item \code{auc} Area under curve
|
||||||
#' \item \code{aucpr} Area under PR curve
|
#' \item \code{aucpr} Area under PR curve
|
||||||
#' \item \code{merror} Exact matching error, used to evaluate multi-class classification
|
#' \item \code{merror} Exact matching error, used to evaluate multi-class classification
|
||||||
@@ -79,7 +81,7 @@
|
|||||||
#'
|
#'
|
||||||
#' All observations are used for both training and validation.
|
#' All observations are used for both training and validation.
|
||||||
#'
|
#'
|
||||||
#' Adapted from \url{http://en.wikipedia.org/wiki/Cross-validation_\%28statistics\%29#k-fold_cross-validation}
|
#' Adapted from \url{https://en.wikipedia.org/wiki/Cross-validation_\%28statistics\%29}
|
||||||
#'
|
#'
|
||||||
#' @return
|
#' @return
|
||||||
#' An object of class \code{xgb.cv.synchronous} with the following elements:
|
#' An object of class \code{xgb.cv.synchronous} with the following elements:
|
||||||
@@ -99,9 +101,7 @@
|
|||||||
#' parameter or randomly generated.
|
#' parameter or randomly generated.
|
||||||
#' \item \code{best_iteration} iteration number with the best evaluation metric value
|
#' \item \code{best_iteration} iteration number with the best evaluation metric value
|
||||||
#' (only available with early stopping).
|
#' (only available with early stopping).
|
||||||
#' \item \code{best_ntreelimit} the \code{ntreelimit} value corresponding to the best iteration,
|
#' \item \code{best_ntreelimit} and the \code{ntreelimit} Deprecated attributes, use \code{best_iteration} instead.
|
||||||
#' which could further be used in \code{predict} method
|
|
||||||
#' (only available with early stopping).
|
|
||||||
#' \item \code{pred} CV prediction values available when \code{prediction} is set.
|
#' \item \code{pred} CV prediction values available when \code{prediction} is set.
|
||||||
#' It is either vector or matrix (see \code{\link{cb.cv.predict}}).
|
#' 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
|
#' \item \code{models} a list of the CV folds' models. It is only available with the explicit
|
||||||
@@ -110,9 +110,9 @@
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' 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"),
|
#' 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)
|
||||||
#' print(cv, verbose=TRUE)
|
#' print(cv, verbose=TRUE)
|
||||||
#'
|
#'
|
||||||
@@ -192,7 +192,7 @@ xgb.cv <- function(params=list(), data, nrounds, nfold, label = NULL, missing =
|
|||||||
|
|
||||||
# create the booster-folds
|
# create the booster-folds
|
||||||
# train_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) {
|
bst_folds <- lapply(seq_along(folds), function(k) {
|
||||||
dtest <- slice(dall, folds[[k]])
|
dtest <- slice(dall, folds[[k]])
|
||||||
# code originally contributed by @RolandASc on stackoverflow
|
# 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.
|
#' @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.
|
#' 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.
|
#' @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
|
#' See demo/ for walkthrough example in R, and
|
||||||
#' \url{https://github.com/dmlc/xgboost/blob/master/demo/data/featmap.txt}
|
#' \url{https://github.com/dmlc/xgboost/blob/master/demo/data/featmap.txt}
|
||||||
#' for example Format.
|
#' for example Format.
|
||||||
@@ -56,16 +54,17 @@ xgb.dump <- function(model, fname = NULL, fmap = "", with_stats=FALSE,
|
|||||||
as.character(dump_format))
|
as.character(dump_format))
|
||||||
|
|
||||||
if (is.null(fname))
|
if (is.null(fname))
|
||||||
model_dump <- stri_replace_all_regex(model_dump, '\t', '')
|
model_dump <- gsub('\t', '', model_dump, fixed = TRUE)
|
||||||
|
|
||||||
if (dump_format == "text")
|
if (dump_format == "text")
|
||||||
model_dump <- unlist(stri_split_regex(model_dump, '\n'))
|
model_dump <- unlist(strsplit(model_dump, '\n', fixed = TRUE))
|
||||||
|
|
||||||
model_dump <- grep('^\\s*$', model_dump, invert = TRUE, value = TRUE)
|
model_dump <- grep('^\\s*$', model_dump, invert = TRUE, value = TRUE)
|
||||||
|
|
||||||
if (is.null(fname)) {
|
if (is.null(fname)) {
|
||||||
return(model_dump)
|
return(model_dump)
|
||||||
} else {
|
} else {
|
||||||
|
fname <- path.expand(fname)
|
||||||
writeLines(model_dump, fname[1])
|
writeLines(model_dump, fname[1])
|
||||||
return(TRUE)
|
return(TRUE)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,6 +99,84 @@ xgb.ggplot.deepness <- function(model = NULL, which = c("2x1", "max.depth", "med
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#' @rdname xgb.plot.shap.summary
|
||||||
|
#' @export
|
||||||
|
xgb.ggplot.shap.summary <- function(data, shap_contrib = NULL, features = NULL, top_n = 10, model = NULL,
|
||||||
|
trees = NULL, target_class = NULL, approxcontrib = FALSE, subsample = NULL) {
|
||||||
|
data_list <- xgb.shap.data(
|
||||||
|
data = data,
|
||||||
|
shap_contrib = shap_contrib,
|
||||||
|
features = features,
|
||||||
|
top_n = top_n,
|
||||||
|
model = model,
|
||||||
|
trees = trees,
|
||||||
|
target_class = target_class,
|
||||||
|
approxcontrib = approxcontrib,
|
||||||
|
subsample = subsample,
|
||||||
|
max_observations = 10000 # 10,000 samples per feature.
|
||||||
|
)
|
||||||
|
p_data <- prepare.ggplot.shap.data(data_list, normalize = TRUE)
|
||||||
|
# Reverse factor levels so that the first level is at the top of the plot
|
||||||
|
p_data[, "feature" := factor(feature, rev(levels(feature)))]
|
||||||
|
p <- ggplot2::ggplot(p_data, ggplot2::aes(x = feature, y = p_data$shap_value, colour = p_data$feature_value)) +
|
||||||
|
ggplot2::geom_jitter(alpha = 0.5, width = 0.1) +
|
||||||
|
ggplot2::scale_colour_viridis_c(limits = c(-3, 3), option = "plasma", direction = -1) +
|
||||||
|
ggplot2::geom_abline(slope = 0, intercept = 0, colour = "darkgrey") +
|
||||||
|
ggplot2::coord_flip()
|
||||||
|
|
||||||
|
p
|
||||||
|
}
|
||||||
|
|
||||||
|
#' Combine and melt feature values and SHAP contributions for sample
|
||||||
|
#' observations.
|
||||||
|
#'
|
||||||
|
#' Conforms to data format required for ggplot functions.
|
||||||
|
#'
|
||||||
|
#' Internal utility function.
|
||||||
|
#'
|
||||||
|
#' @param data_list List containing 'data' and 'shap_contrib' returned by
|
||||||
|
#' \code{xgb.shap.data()}.
|
||||||
|
#' @param normalize Whether to standardize feature values to have mean 0 and
|
||||||
|
#' standard deviation 1 (useful for comparing multiple features on the same
|
||||||
|
#' plot). Default \code{FALSE}.
|
||||||
|
#'
|
||||||
|
#' @return A data.table containing the observation ID, the feature name, the
|
||||||
|
#' feature value (normalized if specified), and the SHAP contribution value.
|
||||||
|
prepare.ggplot.shap.data <- function(data_list, normalize = FALSE) {
|
||||||
|
data <- data_list[["data"]]
|
||||||
|
shap_contrib <- data_list[["shap_contrib"]]
|
||||||
|
|
||||||
|
data <- data.table::as.data.table(as.matrix(data))
|
||||||
|
if (normalize) {
|
||||||
|
data[, (names(data)) := lapply(.SD, normalize)]
|
||||||
|
}
|
||||||
|
data[, "id" := seq_len(nrow(data))]
|
||||||
|
data_m <- data.table::melt.data.table(data, id.vars = "id", variable.name = "feature", value.name = "feature_value")
|
||||||
|
|
||||||
|
shap_contrib <- data.table::as.data.table(as.matrix(shap_contrib))
|
||||||
|
shap_contrib[, "id" := seq_len(nrow(shap_contrib))]
|
||||||
|
shap_contrib_m <- data.table::melt.data.table(shap_contrib, id.vars = "id", variable.name = "feature", value.name = "shap_value")
|
||||||
|
|
||||||
|
p_data <- data.table::merge.data.table(data_m, shap_contrib_m, by = c("id", "feature"))
|
||||||
|
|
||||||
|
p_data
|
||||||
|
}
|
||||||
|
|
||||||
|
#' Scale feature value to have mean 0, standard deviation 1
|
||||||
|
#'
|
||||||
|
#' This is used to compare multiple features on the same plot.
|
||||||
|
#' Internal utility function
|
||||||
|
#'
|
||||||
|
#' @param x Numeric vector
|
||||||
|
#'
|
||||||
|
#' @return Numeric vector with mean 0 and sd 1.
|
||||||
|
normalize <- function(x) {
|
||||||
|
loc <- mean(x, na.rm = TRUE)
|
||||||
|
scale <- stats::sd(x, na.rm = TRUE)
|
||||||
|
|
||||||
|
(x - loc) / scale
|
||||||
|
}
|
||||||
|
|
||||||
# Plot multiple ggplot graph aligned by rows and columns.
|
# Plot multiple ggplot graph aligned by rows and columns.
|
||||||
# ... the plots
|
# ... the plots
|
||||||
# cols number of columns
|
# cols number of columns
|
||||||
@@ -131,5 +209,5 @@ multiplot <- function(..., cols = 1) {
|
|||||||
|
|
||||||
globalVariables(c(
|
globalVariables(c(
|
||||||
"Cluster", "ggplot", "aes", "geom_bar", "coord_flip", "xlab", "ylab", "ggtitle", "theme",
|
"Cluster", "ggplot", "aes", "geom_bar", "coord_flip", "xlab", "ylab", "ggtitle", "theme",
|
||||||
"element_blank", "element_text", "V1", "Weight"
|
"element_blank", "element_text", "V1", "Weight", "feature"
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -96,40 +96,44 @@ xgb.importance <- function(feature_names = NULL, model = NULL, trees = NULL,
|
|||||||
if (!(is.null(feature_names) || is.character(feature_names)))
|
if (!(is.null(feature_names) || is.character(feature_names)))
|
||||||
stop("feature_names: Has to be a character vector")
|
stop("feature_names: Has to be a character vector")
|
||||||
|
|
||||||
model_text_dump <- xgb.dump(model = model, with_stats = TRUE)
|
model <- xgb.Booster.complete(model)
|
||||||
|
config <- jsonlite::fromJSON(xgb.config(model))
|
||||||
# linear model
|
if (config$learner$gradient_booster$name == "gblinear") {
|
||||||
if (model_text_dump[2] == "bias:"){
|
args <- list(importance_type = "weight", feature_names = feature_names)
|
||||||
weights <- which(model_text_dump == "weight:") %>%
|
results <- .Call(
|
||||||
{model_text_dump[(. + 1):length(model_text_dump)]} %>%
|
XGBoosterFeatureScore_R, model$handle, jsonlite::toJSON(args, auto_unbox = TRUE, null = "null")
|
||||||
as.numeric
|
)
|
||||||
|
names(results) <- c("features", "shape", "weight")
|
||||||
num_class <- NVL(model$params$num_class, 1)
|
n_classes <- if (length(results$shape) == 2) { results$shape[2] } else { 0 }
|
||||||
if (is.null(feature_names))
|
importance <- if (n_classes == 0) {
|
||||||
feature_names <- seq(to = length(weights) / num_class) - 1
|
data.table(Feature = results$features, Weight = results$weight)[order(-abs(Weight))]
|
||||||
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))]
|
|
||||||
} else {
|
} else {
|
||||||
data.table(Feature = rep(feature_names, each = num_class),
|
data.table(
|
||||||
Weight = weights,
|
Feature = rep(results$features, each = n_classes), Weight = results$weight, Class = seq_len(n_classes) - 1
|
||||||
Class = seq_len(num_class) - 1)[order(Class, -abs(Weight))]
|
)[order(Class, -abs(Weight))]
|
||||||
}
|
}
|
||||||
} else { # tree model
|
} else {
|
||||||
result <- xgb.model.dt.tree(feature_names = feature_names,
|
concatenated <- list()
|
||||||
text = model_text_dump,
|
output_names <- vector()
|
||||||
trees = trees)[
|
for (importance_type in c("weight", "total_gain", "total_cover")) {
|
||||||
Feature != "Leaf", .(Gain = sum(Quality),
|
args <- list(importance_type = importance_type, feature_names = feature_names, tree_idx = trees)
|
||||||
Cover = sum(Cover),
|
results <- .Call(
|
||||||
Frequency = .N), by = Feature][
|
XGBoosterFeatureScore_R, model$handle, jsonlite::toJSON(args, auto_unbox = TRUE, null = "null")
|
||||||
, `:=`(Gain = Gain / sum(Gain),
|
)
|
||||||
Cover = Cover / sum(Cover),
|
names(results) <- c("features", "shape", importance_type)
|
||||||
Frequency = Frequency / sum(Frequency))][
|
concatenated[
|
||||||
order(Gain, decreasing = TRUE)]
|
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.
|
# Avoid error messages during CRAN check.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#' @param modelfile the name of the binary input file.
|
#' @param modelfile the name of the binary input file.
|
||||||
#'
|
#'
|
||||||
#' @details
|
#' @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
|
#' 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
|
#' 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.
|
#' 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)
|
handle <- xgb.Booster.handle(modelfile = modelfile)
|
||||||
# re-use modelfile if it is raw so we do not need to serialize
|
# re-use modelfile if it is raw so we do not need to serialize
|
||||||
if (typeof(modelfile) == "raw") {
|
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)
|
bst <- xgb.handleToBooster(handle, modelfile)
|
||||||
} else {
|
} else {
|
||||||
bst <- xgb.handleToBooster(handle, NULL)
|
bst <- xgb.handleToBooster(handle, NULL)
|
||||||
|
|||||||
@@ -3,12 +3,21 @@
|
|||||||
#' User can generate raw memory buffer by calling xgb.save.raw
|
#' User can generate raw memory buffer by calling xgb.save.raw
|
||||||
#'
|
#'
|
||||||
#' @param buffer the buffer returned by 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
|
#' @export
|
||||||
xgb.load.raw <- function(buffer) {
|
xgb.load.raw <- function(buffer, as_booster = FALSE) {
|
||||||
cachelist <- list()
|
cachelist <- list()
|
||||||
handle <- .Call(XGBoosterCreate_R, cachelist)
|
handle <- .Call(XGBoosterCreate_R, cachelist)
|
||||||
.Call(XGBoosterLoadModelFromRaw_R, handle, buffer)
|
.Call(XGBoosterLoadModelFromRaw_R, handle, buffer)
|
||||||
class(handle) <- "xgb.Booster.handle"
|
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,11 +87,11 @@ xgb.model.dt.tree <- function(feature_names = NULL, model = NULL, text = NULL,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (length(text) < 2 ||
|
if (length(text) < 2 ||
|
||||||
sum(stri_detect_regex(text, 'yes=(\\d+),no=(\\d+)')) < 1) {
|
sum(grepl('leaf=(\\d+)', text)) < 1) {
|
||||||
stop("Non-tree model detected! This function can only be used with tree models.")
|
stop("Non-tree model detected! This function can only be used with tree models.")
|
||||||
}
|
}
|
||||||
|
|
||||||
position <- which(!is.na(stri_match_first_regex(text, "booster")))
|
position <- which(grepl("booster", text, fixed = TRUE))
|
||||||
|
|
||||||
add.tree.id <- function(node, tree) if (use_int_id) node else paste(tree, node, sep = "-")
|
add.tree.id <- function(node, tree) if (use_int_id) node else paste(tree, node, sep = "-")
|
||||||
|
|
||||||
@@ -108,23 +108,36 @@ xgb.model.dt.tree <- function(feature_names = NULL, model = NULL, text = NULL,
|
|||||||
}
|
}
|
||||||
td <- td[Tree %in% trees & !grepl('^booster', t)]
|
td <- td[Tree %in% trees & !grepl('^booster', t)]
|
||||||
|
|
||||||
td[, Node := stri_match_first_regex(t, "(\\d+):")[, 2] %>% as.integer]
|
td[, Node := as.integer(sub("^([0-9]+):.*", "\\1", t))]
|
||||||
if (!use_int_id) td[, ID := add.tree.id(Node, Tree)]
|
if (!use_int_id) td[, ID := add.tree.id(Node, Tree)]
|
||||||
td[, isLeaf := !is.na(stri_match_first_regex(t, "leaf"))]
|
td[, isLeaf := grepl("leaf", t, fixed = TRUE)]
|
||||||
|
|
||||||
# parse branch lines
|
# parse branch lines
|
||||||
branch_rx <- paste0("f(\\d+)<(", anynumber_regex, ")\\] yes=(\\d+),no=(\\d+),missing=(\\d+),",
|
branch_rx <- paste0("f(\\d+)<(", anynumber_regex, ")\\] yes=(\\d+),no=(\\d+),missing=(\\d+),",
|
||||||
"gain=(", anynumber_regex, "),cover=(", anynumber_regex, ")")
|
"gain=(", anynumber_regex, "),cover=(", anynumber_regex, ")")
|
||||||
branch_cols <- c("Feature", "Split", "Yes", "No", "Missing", "Quality", "Cover")
|
branch_cols <- c("Feature", "Split", "Yes", "No", "Missing", "Quality", "Cover")
|
||||||
td[isLeaf == FALSE,
|
td[
|
||||||
(branch_cols) := {
|
isLeaf == FALSE,
|
||||||
|
(branch_cols) := {
|
||||||
|
matches <- regmatches(t, regexec(branch_rx, t))
|
||||||
# skip some indices with spurious capture groups from anynumber_regex
|
# skip some indices with spurious capture groups from anynumber_regex
|
||||||
xtr <- stri_match_first_regex(t, branch_rx)[, c(2, 3, 5, 6, 7, 8, 10), drop = FALSE]
|
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)
|
xtr[, 3:5] <- add.tree.id(xtr[, 3:5], Tree)
|
||||||
lapply(seq_len(ncol(xtr)), function(i) xtr[, i])
|
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
|
# 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))
|
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")
|
stop("feature_names has less elements than there are features used in the model")
|
||||||
td[isLeaf == FALSE, Feature := feature_names[as.numeric(Feature) + 1]]
|
td[isLeaf == FALSE, Feature := feature_names[as.numeric(Feature) + 1]]
|
||||||
@@ -133,11 +146,18 @@ xgb.model.dt.tree <- function(feature_names = NULL, model = NULL, text = NULL,
|
|||||||
# parse leaf lines
|
# parse leaf lines
|
||||||
leaf_rx <- paste0("leaf=(", anynumber_regex, "),cover=(", anynumber_regex, ")")
|
leaf_rx <- paste0("leaf=(", anynumber_regex, "),cover=(", anynumber_regex, ")")
|
||||||
leaf_cols <- c("Feature", "Quality", "Cover")
|
leaf_cols <- c("Feature", "Quality", "Cover")
|
||||||
td[isLeaf == TRUE,
|
td[
|
||||||
(leaf_cols) := {
|
isLeaf == TRUE,
|
||||||
xtr <- stri_match_first_regex(t, leaf_rx)[, c(2, 4)]
|
(leaf_cols) := {
|
||||||
c("Leaf", lapply(seq_len(ncol(xtr)), function(i) xtr[, i]))
|
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
|
# convert some columns to numeric
|
||||||
numeric_cols <- c("Split", "Quality", "Cover")
|
numeric_cols <- c("Split", "Quality", "Cover")
|
||||||
|
|||||||
@@ -99,21 +99,20 @@ xgb.plot.importance <- function(importance_matrix = NULL, top_n = NULL, measure
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (plot) {
|
if (plot) {
|
||||||
op <- par(no.readonly = TRUE)
|
original_mar <- par()$mar
|
||||||
mar <- op$mar
|
|
||||||
|
# reset margins so this function doesn't have side effects
|
||||||
|
on.exit({par(mar = original_mar)})
|
||||||
|
|
||||||
|
mar <- original_mar
|
||||||
if (!is.null(left_margin))
|
if (!is.null(left_margin))
|
||||||
mar[2] <- left_margin
|
mar[2] <- left_margin
|
||||||
par(mar = mar)
|
par(mar = mar)
|
||||||
|
|
||||||
# reverse the order of rows to have the highest ranked at the top
|
# reverse the order of rows to have the highest ranked at the top
|
||||||
importance_matrix[nrow(importance_matrix):1,
|
importance_matrix[rev(seq_len(nrow(importance_matrix))),
|
||||||
barplot(Importance, horiz = TRUE, border = NA, cex.names = cex,
|
barplot(Importance, horiz = TRUE, border = NA, cex.names = cex,
|
||||||
names.arg = Feature, las = 1, ...)]
|
names.arg = Feature, las = 1, ...)]
|
||||||
grid(NULL, NA)
|
|
||||||
# redraw over the grid
|
|
||||||
importance_matrix[nrow(importance_matrix):1,
|
|
||||||
barplot(Importance, horiz = TRUE, border = NA, add = TRUE)]
|
|
||||||
par(op)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invisible(importance_matrix)
|
invisible(importance_matrix)
|
||||||
|
|||||||
@@ -62,12 +62,15 @@
|
|||||||
#' @export
|
#' @export
|
||||||
xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5, plot_width = NULL, plot_height = NULL,
|
xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5, plot_width = NULL, plot_height = NULL,
|
||||||
render = TRUE, ...){
|
render = TRUE, ...){
|
||||||
|
if (!requireNamespace("DiagrammeR", quietly = TRUE)) {
|
||||||
|
stop("DiagrammeR is required for xgb.plot.multi.trees")
|
||||||
|
}
|
||||||
check.deprecation(...)
|
check.deprecation(...)
|
||||||
tree.matrix <- xgb.model.dt.tree(feature_names = feature_names, model = model)
|
tree.matrix <- xgb.model.dt.tree(feature_names = feature_names, model = model)
|
||||||
|
|
||||||
# first number of the path represents the tree, then the following numbers are related to the path to follow
|
# first number of the path represents the tree, then the following numbers are related to the path to follow
|
||||||
# root init
|
# root init
|
||||||
root.nodes <- tree.matrix[stri_detect_regex(ID, "\\d+-0"), ID]
|
root.nodes <- tree.matrix[Node == 0, ID]
|
||||||
tree.matrix[ID %in% root.nodes, abs.node.position := root.nodes]
|
tree.matrix[ID %in% root.nodes, abs.node.position := root.nodes]
|
||||||
|
|
||||||
precedent.nodes <- root.nodes
|
precedent.nodes <- root.nodes
|
||||||
@@ -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) {
|
while (tree.matrix[, sum(is.na(abs.node.position))] > 0) {
|
||||||
yes.row.nodes <- tree.matrix[abs.node.position %in% precedent.nodes & !is.na(Yes)]
|
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)]
|
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")
|
yes.nodes.abs.pos <- paste0(yes.row.nodes[, abs.node.position], "_0")
|
||||||
no.nodes.abs.pos <- no.row.nodes[, abs.node.position] %>% paste0("_1")
|
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% 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]
|
tree.matrix[ID %in% no.row.nodes[, No], abs.node.position := no.nodes.abs.pos]
|
||||||
@@ -86,28 +89,34 @@ xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5,
|
|||||||
tree.matrix[!is.na(Yes), Yes := paste0(abs.node.position, "_0")]
|
tree.matrix[!is.na(Yes), Yes := paste0(abs.node.position, "_0")]
|
||||||
tree.matrix[!is.na(No), No := paste0(abs.node.position, "_1")]
|
tree.matrix[!is.na(No), No := paste0(abs.node.position, "_1")]
|
||||||
|
|
||||||
remove.tree <- . %>% stri_replace_first_regex(pattern = "^\\d+-", replacement = "")
|
for (nm in c("abs.node.position", "Yes", "No"))
|
||||||
|
data.table::set(tree.matrix, j = nm, value = sub("^\\d+-", "", tree.matrix[[nm]]))
|
||||||
tree.matrix[, `:=`(abs.node.position = remove.tree(abs.node.position),
|
|
||||||
Yes = remove.tree(Yes),
|
|
||||||
No = remove.tree(No))]
|
|
||||||
|
|
||||||
nodes.dt <- tree.matrix[
|
nodes.dt <- tree.matrix[
|
||||||
, .(Quality = sum(Quality))
|
, .(Quality = sum(Quality))
|
||||||
, by = .(abs.node.position, Feature)
|
, by = .(abs.node.position, Feature)
|
||||||
][, .(Text = paste0(Feature[1:min(length(Feature), features_keep)],
|
][, .(Text = paste0(
|
||||||
" (",
|
paste0(
|
||||||
format(Quality[1:min(length(Quality), features_keep)], digits = 5),
|
Feature[1:min(length(Feature), features_keep)],
|
||||||
")") %>%
|
" (",
|
||||||
paste0(collapse = "\n"))
|
format(Quality[1:min(length(Quality), features_keep)], digits = 5),
|
||||||
, by = abs.node.position]
|
")"
|
||||||
|
),
|
||||||
|
collapse = "\n"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
, by = abs.node.position
|
||||||
|
]
|
||||||
|
|
||||||
edges.dt <- tree.matrix[Feature != "Leaf", .(abs.node.position, Yes)] %>%
|
edges.dt <- data.table::rbindlist(
|
||||||
list(tree.matrix[Feature != "Leaf", .(abs.node.position, No)]) %>%
|
l = list(
|
||||||
rbindlist() %>%
|
tree.matrix[Feature != "Leaf", .(abs.node.position, Yes)],
|
||||||
setnames(c("From", "To")) %>%
|
tree.matrix[Feature != "Leaf", .(abs.node.position, No)]
|
||||||
.[, .N, .(From, To)] %>%
|
)
|
||||||
.[, N := NULL]
|
)
|
||||||
|
data.table::setnames(edges.dt, c("From", "To"))
|
||||||
|
edges.dt <- edges.dt[, .N, .(From, To)]
|
||||||
|
edges.dt[, N := NULL]
|
||||||
|
|
||||||
nodes <- DiagrammeR::create_node_df(
|
nodes <- DiagrammeR::create_node_df(
|
||||||
n = nrow(nodes.dt),
|
n = nrow(nodes.dt),
|
||||||
@@ -123,21 +132,25 @@ xgb.plot.multi.trees <- function(model, feature_names = NULL, features_keep = 5,
|
|||||||
nodes_df = nodes,
|
nodes_df = nodes,
|
||||||
edges_df = edges,
|
edges_df = edges,
|
||||||
attr_theme = NULL
|
attr_theme = NULL
|
||||||
) %>%
|
)
|
||||||
DiagrammeR::add_global_graph_attrs(
|
graph <- DiagrammeR::add_global_graph_attrs(
|
||||||
|
graph = graph,
|
||||||
attr_type = "graph",
|
attr_type = "graph",
|
||||||
attr = c("layout", "rankdir"),
|
attr = c("layout", "rankdir"),
|
||||||
value = c("dot", "LR")
|
value = c("dot", "LR")
|
||||||
) %>%
|
)
|
||||||
DiagrammeR::add_global_graph_attrs(
|
graph <- DiagrammeR::add_global_graph_attrs(
|
||||||
|
graph = graph,
|
||||||
attr_type = "node",
|
attr_type = "node",
|
||||||
attr = c("color", "fillcolor", "style", "shape", "fontname"),
|
attr = c("color", "fillcolor", "style", "shape", "fontname"),
|
||||||
value = c("DimGray", "beige", "filled", "rectangle", "Helvetica")
|
value = c("DimGray", "beige", "filled", "rectangle", "Helvetica")
|
||||||
) %>%
|
)
|
||||||
DiagrammeR::add_global_graph_attrs(
|
graph <- DiagrammeR::add_global_graph_attrs(
|
||||||
|
graph = graph,
|
||||||
attr_type = "edge",
|
attr_type = "edge",
|
||||||
attr = c("color", "arrowsize", "arrowhead", "fontname"),
|
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))
|
if (!render) return(invisible(graph))
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#' @param col_loess a color to use for the loess curves.
|
#' @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 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 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}.
|
#' @param ... other parameters passed to \code{plot}.
|
||||||
#'
|
#'
|
||||||
#' @details
|
#' @details
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
#' xgb.plot.shap(agaricus.test$data, model = bst, features = "odor=none")
|
#' xgb.plot.shap(agaricus.test$data, model = bst, features = "odor=none")
|
||||||
#' contr <- predict(bst, agaricus.test$data, predcontrib = TRUE)
|
#' contr <- predict(bst, agaricus.test$data, predcontrib = TRUE)
|
||||||
#' xgb.plot.shap(agaricus.test$data, contr, model = bst, top_n = 12, n_col = 3)
|
#' xgb.plot.shap(agaricus.test$data, contr, model = bst, top_n = 12, n_col = 3)
|
||||||
|
#' xgb.ggplot.shap.summary(agaricus.test$data, contr, model = bst, top_n = 12) # Summary plot
|
||||||
#'
|
#'
|
||||||
#' # multiclass example - plots for each class separately:
|
#' # multiclass example - plots for each class separately:
|
||||||
#' nclass <- 3
|
#' nclass <- 3
|
||||||
@@ -99,6 +100,7 @@
|
|||||||
#' n_col = 2, col = col, pch = 16, pch_NA = 17)
|
#' n_col = 2, col = col, pch = 16, pch_NA = 17)
|
||||||
#' xgb.plot.shap(x, model = mbst, trees = trees0 + 2, target_class = 2, top_n = 4,
|
#' xgb.plot.shap(x, model = mbst, trees = trees0 + 2, target_class = 2, top_n = 4,
|
||||||
#' n_col = 2, col = col, pch = 16, pch_NA = 17)
|
#' n_col = 2, col = col, pch = 16, pch_NA = 17)
|
||||||
|
#' xgb.ggplot.shap.summary(x, model = mbst, target_class = 0, top_n = 4) # Summary plot
|
||||||
#'
|
#'
|
||||||
#' @rdname xgb.plot.shap
|
#' @rdname xgb.plot.shap
|
||||||
#' @export
|
#' @export
|
||||||
@@ -109,69 +111,33 @@ xgb.plot.shap <- function(data, shap_contrib = NULL, features = NULL, top_n = 1,
|
|||||||
plot_NA = TRUE, col_NA = rgb(0.7, 0, 1, 0.6), pch_NA = '.', pos_NA = 1.07,
|
plot_NA = TRUE, col_NA = rgb(0.7, 0, 1, 0.6), pch_NA = '.', pos_NA = 1.07,
|
||||||
plot_loess = TRUE, col_loess = 2, span_loess = 0.5,
|
plot_loess = TRUE, col_loess = 2, span_loess = 0.5,
|
||||||
which = c("1d", "2d"), plot = TRUE, ...) {
|
which = c("1d", "2d"), plot = TRUE, ...) {
|
||||||
|
data_list <- xgb.shap.data(
|
||||||
if (!is.matrix(data) && !inherits(data, "dgCMatrix"))
|
data = data,
|
||||||
stop("data: must be either matrix or dgCMatrix")
|
shap_contrib = shap_contrib,
|
||||||
|
features = features,
|
||||||
if (is.null(shap_contrib) && (is.null(model) || !inherits(model, "xgb.Booster")))
|
top_n = top_n,
|
||||||
stop("when shap_contrib is not provided, one must provide an xgb.Booster model")
|
model = model,
|
||||||
|
trees = trees,
|
||||||
if (is.null(features) && (is.null(model) || !inherits(model, "xgb.Booster")))
|
target_class = target_class,
|
||||||
stop("when features are not provided, one must provide an xgb.Booster model to rank the features")
|
approxcontrib = approxcontrib,
|
||||||
|
subsample = subsample,
|
||||||
if (!is.null(shap_contrib) &&
|
max_observations = 100000
|
||||||
(!is.matrix(shap_contrib) || nrow(shap_contrib) != nrow(data) || ncol(shap_contrib) != ncol(data) + 1))
|
)
|
||||||
stop("shap_contrib is not compatible with the provided data")
|
data <- data_list[["data"]]
|
||||||
|
shap_contrib <- data_list[["shap_contrib"]]
|
||||||
nsample <- if (is.null(subsample)) min(100000, nrow(data)) else as.integer(subsample * nrow(data))
|
features <- colnames(data)
|
||||||
idx <- sample(1:nrow(data), nsample)
|
|
||||||
data <- data[idx, ]
|
|
||||||
|
|
||||||
if (is.null(shap_contrib)) {
|
|
||||||
shap_contrib <- predict(model, data, predcontrib = TRUE, approxcontrib = approxcontrib)
|
|
||||||
} else {
|
|
||||||
shap_contrib <- shap_contrib[idx, ]
|
|
||||||
}
|
|
||||||
|
|
||||||
which <- match.arg(which)
|
which <- match.arg(which)
|
||||||
if (which == "2d")
|
if (which == "2d")
|
||||||
stop("2D plots are not implemented yet")
|
stop("2D plots are not implemented yet")
|
||||||
|
|
||||||
if (is.null(features)) {
|
|
||||||
imp <- xgb.importance(model = model, trees = trees)
|
|
||||||
top_n <- as.integer(top_n[1])
|
|
||||||
if (top_n < 1 && top_n > 100)
|
|
||||||
stop("top_n: must be an integer within [1, 100]")
|
|
||||||
features <- imp$Feature[1:min(top_n, NROW(imp))]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is.character(features)) {
|
|
||||||
if (is.null(colnames(data)))
|
|
||||||
stop("Either provide `data` with column names or provide `features` as column indices")
|
|
||||||
features <- match(features, colnames(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_col > length(features)) n_col <- length(features)
|
if (n_col > length(features)) n_col <- length(features)
|
||||||
|
|
||||||
if (is.list(shap_contrib)) { # multiclass: either choose a class or merge
|
|
||||||
shap_contrib <- if (!is.null(target_class)) shap_contrib[[target_class + 1]]
|
|
||||||
else Reduce("+", lapply(shap_contrib, abs))
|
|
||||||
}
|
|
||||||
|
|
||||||
shap_contrib <- shap_contrib[, features, drop = FALSE]
|
|
||||||
data <- data[, features, drop = FALSE]
|
|
||||||
cols <- colnames(data)
|
|
||||||
if (is.null(cols)) cols <- colnames(shap_contrib)
|
|
||||||
if (is.null(cols)) cols <- paste0('X', 1:ncol(data))
|
|
||||||
colnames(data) <- cols
|
|
||||||
colnames(shap_contrib) <- cols
|
|
||||||
|
|
||||||
if (plot && which == "1d") {
|
if (plot && which == "1d") {
|
||||||
op <- par(mfrow = c(ceiling(length(features) / n_col), n_col),
|
op <- par(mfrow = c(ceiling(length(features) / n_col), n_col),
|
||||||
oma = c(0, 0, 0, 0) + 0.2,
|
oma = c(0, 0, 0, 0) + 0.2,
|
||||||
mar = c(3.5, 3.5, 0, 0) + 0.1,
|
mar = c(3.5, 3.5, 0, 0) + 0.1,
|
||||||
mgp = c(1.7, 0.6, 0))
|
mgp = c(1.7, 0.6, 0))
|
||||||
for (f in cols) {
|
for (f in features) {
|
||||||
ord <- order(data[, f])
|
ord <- order(data[, f])
|
||||||
x <- data[, f][ord]
|
x <- data[, f][ord]
|
||||||
y <- shap_contrib[, f][ord]
|
y <- shap_contrib[, f][ord]
|
||||||
@@ -191,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, ...)
|
plot(x2plot, y, pch = pch, xlab = f, col = col, xlim = x_lim, ylim = y_lim, ylab = ylab, ...)
|
||||||
grid()
|
grid()
|
||||||
if (plot_loess) {
|
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]
|
zz <- data.table(x = signif(x, 3), y)[, .(.N, y = mean(y)), x]
|
||||||
if (nrow(zz) <= 5) {
|
if (nrow(zz) <= 5) {
|
||||||
lines(zz$x, zz$y, col = col_loess)
|
lines(zz$x, zz$y, col = col_loess)
|
||||||
@@ -216,3 +182,108 @@ xgb.plot.shap <- function(data, shap_contrib = NULL, features = NULL, top_n = 1,
|
|||||||
}
|
}
|
||||||
invisible(list(data = data, shap_contrib = shap_contrib))
|
invisible(list(data = data, shap_contrib = shap_contrib))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#' SHAP contribution dependency summary plot
|
||||||
|
#'
|
||||||
|
#' Compare SHAP contributions of different features.
|
||||||
|
#'
|
||||||
|
#' A point plot (each point representing one sample from \code{data}) is
|
||||||
|
#' produced for each feature, with the points plotted on the SHAP value axis.
|
||||||
|
#' Each point (observation) is coloured based on its feature value. The plot
|
||||||
|
#' hence allows us to see which features have a negative / positive contribution
|
||||||
|
#' on the model prediction, and whether the contribution is different for larger
|
||||||
|
#' or smaller values of the feature. We effectively try to replicate the
|
||||||
|
#' \code{summary_plot} function from https://github.com/slundberg/shap.
|
||||||
|
#'
|
||||||
|
#' @inheritParams xgb.plot.shap
|
||||||
|
#'
|
||||||
|
#' @return A \code{ggplot2} object.
|
||||||
|
#' @export
|
||||||
|
#'
|
||||||
|
#' @examples # See \code{\link{xgb.plot.shap}}.
|
||||||
|
#' @seealso \code{\link{xgb.plot.shap}}, \code{\link{xgb.ggplot.shap.summary}},
|
||||||
|
#' \url{https://github.com/slundberg/shap}
|
||||||
|
xgb.plot.shap.summary <- function(data, shap_contrib = NULL, features = NULL, top_n = 10, model = NULL,
|
||||||
|
trees = NULL, target_class = NULL, approxcontrib = FALSE, subsample = NULL) {
|
||||||
|
# Only ggplot implementation is available.
|
||||||
|
xgb.ggplot.shap.summary(data, shap_contrib, features, top_n, model, trees, target_class, approxcontrib, subsample)
|
||||||
|
}
|
||||||
|
|
||||||
|
#' Prepare data for SHAP plots. To be used in xgb.plot.shap, xgb.plot.shap.summary, etc.
|
||||||
|
#' Internal utility function.
|
||||||
|
#'
|
||||||
|
#' @inheritParams xgb.plot.shap
|
||||||
|
#' @keywords internal
|
||||||
|
#'
|
||||||
|
#' @return A list containing: 'data', a matrix containing sample observations
|
||||||
|
#' and their feature values; 'shap_contrib', a matrix containing the SHAP contribution
|
||||||
|
#' values for these observations.
|
||||||
|
xgb.shap.data <- function(data, shap_contrib = NULL, features = NULL, top_n = 1, model = NULL,
|
||||||
|
trees = NULL, target_class = NULL, approxcontrib = FALSE,
|
||||||
|
subsample = NULL, max_observations = 100000) {
|
||||||
|
if (!is.matrix(data) && !inherits(data, "dgCMatrix"))
|
||||||
|
stop("data: must be either matrix or dgCMatrix")
|
||||||
|
|
||||||
|
if (is.null(shap_contrib) && (is.null(model) || !inherits(model, "xgb.Booster")))
|
||||||
|
stop("when shap_contrib is not provided, one must provide an xgb.Booster model")
|
||||||
|
|
||||||
|
if (is.null(features) && (is.null(model) || !inherits(model, "xgb.Booster")))
|
||||||
|
stop("when features are not provided, one must provide an xgb.Booster model to rank the features")
|
||||||
|
|
||||||
|
if (!is.null(shap_contrib) &&
|
||||||
|
(!is.matrix(shap_contrib) || nrow(shap_contrib) != nrow(data) || ncol(shap_contrib) != ncol(data) + 1))
|
||||||
|
stop("shap_contrib is not compatible with the provided data")
|
||||||
|
|
||||||
|
if (is.character(features) && is.null(colnames(data)))
|
||||||
|
stop("either provide `data` with column names or provide `features` as column indices")
|
||||||
|
|
||||||
|
if (is.null(model$feature_names) && model$nfeatures != ncol(data))
|
||||||
|
stop("if model has no feature_names, columns in `data` must match features in model")
|
||||||
|
|
||||||
|
if (!is.null(subsample)) {
|
||||||
|
idx <- sample(x = seq_len(nrow(data)), size = as.integer(subsample * nrow(data)), replace = FALSE)
|
||||||
|
} else {
|
||||||
|
idx <- seq_len(min(nrow(data), max_observations))
|
||||||
|
}
|
||||||
|
data <- data[idx, ]
|
||||||
|
if (is.null(colnames(data))) {
|
||||||
|
colnames(data) <- paste0("X", seq_len(ncol(data)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is.null(shap_contrib)) {
|
||||||
|
if (is.list(shap_contrib)) { # multiclass: either choose a class or merge
|
||||||
|
shap_contrib <- if (!is.null(target_class)) shap_contrib[[target_class + 1]] else Reduce("+", lapply(shap_contrib, abs))
|
||||||
|
}
|
||||||
|
shap_contrib <- shap_contrib[idx, ]
|
||||||
|
if (is.null(colnames(shap_contrib))) {
|
||||||
|
colnames(shap_contrib) <- paste0("X", seq_len(ncol(data)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shap_contrib <- predict(model, newdata = data, predcontrib = TRUE, approxcontrib = approxcontrib)
|
||||||
|
if (is.list(shap_contrib)) { # multiclass: either choose a class or merge
|
||||||
|
shap_contrib <- if (!is.null(target_class)) shap_contrib[[target_class + 1]] else Reduce("+", lapply(shap_contrib, abs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is.null(features)) {
|
||||||
|
if (!is.null(model$feature_names)) {
|
||||||
|
imp <- xgb.importance(model = model, trees = trees)
|
||||||
|
} else {
|
||||||
|
imp <- xgb.importance(model = model, trees = trees, feature_names = colnames(data))
|
||||||
|
}
|
||||||
|
top_n <- top_n[1]
|
||||||
|
if (top_n < 1 | top_n > 100) stop("top_n: must be an integer within [1, 100]")
|
||||||
|
features <- imp$Feature[1:min(top_n, NROW(imp))]
|
||||||
|
}
|
||||||
|
if (is.character(features)) {
|
||||||
|
features <- match(features, colnames(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
shap_contrib <- shap_contrib[, features, drop = FALSE]
|
||||||
|
data <- data[, features, drop = FALSE]
|
||||||
|
|
||||||
|
list(
|
||||||
|
data = data,
|
||||||
|
shap_contrib = shap_contrib
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -98,34 +98,46 @@ xgb.plot.tree <- function(feature_names = NULL, model = NULL, trees = NULL, plot
|
|||||||
data = dt$Feature,
|
data = dt$Feature,
|
||||||
fontcolor = "black")
|
fontcolor = "black")
|
||||||
|
|
||||||
edges <- DiagrammeR::create_edge_df(
|
if (nrow(dt[Feature != "Leaf"]) != 0) {
|
||||||
from = match(dt[Feature != "Leaf", c(ID)] %>% rep(2), dt$ID),
|
edges <- DiagrammeR::create_edge_df(
|
||||||
to = match(dt[Feature != "Leaf", c(Yes, No)], dt$ID),
|
from = match(rep(dt[Feature != "Leaf", c(ID)], 2), dt$ID),
|
||||||
label = dt[Feature != "Leaf", paste("<", Split)] %>%
|
to = match(dt[Feature != "Leaf", c(Yes, No)], dt$ID),
|
||||||
c(rep("", nrow(dt[Feature != "Leaf"]))),
|
label = c(
|
||||||
style = dt[Feature != "Leaf", ifelse(Missing == Yes, "bold", "solid")] %>%
|
dt[Feature != "Leaf", paste("<", Split)],
|
||||||
c(dt[Feature != "Leaf", ifelse(Missing == No, "bold", "solid")]),
|
rep("", nrow(dt[Feature != "Leaf"]))
|
||||||
rel = "leading_to")
|
),
|
||||||
|
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(
|
graph <- DiagrammeR::create_graph(
|
||||||
nodes_df = nodes,
|
nodes_df = nodes,
|
||||||
edges_df = edges,
|
edges_df = edges,
|
||||||
attr_theme = NULL
|
attr_theme = NULL
|
||||||
) %>%
|
)
|
||||||
DiagrammeR::add_global_graph_attrs(
|
graph <- DiagrammeR::add_global_graph_attrs(
|
||||||
|
graph = graph,
|
||||||
attr_type = "graph",
|
attr_type = "graph",
|
||||||
attr = c("layout", "rankdir"),
|
attr = c("layout", "rankdir"),
|
||||||
value = c("dot", "LR")
|
value = c("dot", "LR")
|
||||||
) %>%
|
)
|
||||||
DiagrammeR::add_global_graph_attrs(
|
graph <- DiagrammeR::add_global_graph_attrs(
|
||||||
|
graph = graph,
|
||||||
attr_type = "node",
|
attr_type = "node",
|
||||||
attr = c("color", "style", "fontname"),
|
attr = c("color", "style", "fontname"),
|
||||||
value = c("DimGray", "filled", "Helvetica")
|
value = c("DimGray", "filled", "Helvetica")
|
||||||
) %>%
|
)
|
||||||
DiagrammeR::add_global_graph_attrs(
|
graph <- DiagrammeR::add_global_graph_attrs(
|
||||||
|
graph = graph,
|
||||||
attr_type = "edge",
|
attr_type = "edge",
|
||||||
attr = c("color", "arrowsize", "arrowhead", "fontname"),
|
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))
|
if (!render) return(invisible(graph))
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ xgb.save <- function(model, fname) {
|
|||||||
if (inherits(model, "xgb.DMatrix")) " Use xgb.DMatrix.save to save an xgb.DMatrix object." else "")
|
if (inherits(model, "xgb.DMatrix")) " Use xgb.DMatrix.save to save an xgb.DMatrix object." else "")
|
||||||
}
|
}
|
||||||
model <- xgb.Booster.complete(model, saveraw = FALSE)
|
model <- xgb.Booster.complete(model, saveraw = FALSE)
|
||||||
|
fname <- path.expand(fname)
|
||||||
.Call(XGBoosterSaveModel_R, model$handle, fname[1])
|
.Call(XGBoosterSaveModel_R, model$handle, fname[1])
|
||||||
return(TRUE)
|
return(TRUE)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,14 @@
|
|||||||
#' Save xgboost model from xgboost or xgb.train
|
#' Save xgboost model from xgboost or xgb.train
|
||||||
#'
|
#'
|
||||||
#' @param model the model object.
|
#' @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
|
#' @examples
|
||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
@@ -17,7 +25,8 @@
|
|||||||
#' pred <- predict(bst, test$data)
|
#' pred <- predict(bst, test$data)
|
||||||
#'
|
#'
|
||||||
#' @export
|
#' @export
|
||||||
xgb.save.raw <- function(model) {
|
xgb.save.raw <- function(model, raw_format = "deprecated") {
|
||||||
handle <- xgb.get.handle(model)
|
handle <- xgb.get.handle(model)
|
||||||
.Call(XGBoosterModelToRaw_R, handle)
|
args <- list(format = raw_format)
|
||||||
|
.Call(XGBoosterSaveModelToRaw_R, handle, jsonlite::toJSON(args, auto_unbox = TRUE))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#'
|
#'
|
||||||
#' 2. Booster Parameters
|
#' 2. Booster Parameters
|
||||||
#'
|
#'
|
||||||
#' 2.1. Parameter for Tree Booster
|
#' 2.1. Parameters for Tree Booster
|
||||||
#'
|
#'
|
||||||
#' \itemize{
|
#' \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
|
#' \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
|
||||||
@@ -24,12 +24,14 @@
|
|||||||
#' \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{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{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{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{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.
|
#' \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{
|
#' \itemize{
|
||||||
#' \item \code{lambda} L2 regularization term on weights. Default: 0
|
#' \item \code{lambda} L2 regularization term on weights. Default: 0
|
||||||
@@ -49,10 +51,10 @@
|
|||||||
#' \item \code{binary:logistic} logistic regression for binary classification. Output probability.
|
#' \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: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{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: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{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: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{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.
|
#' \item \code{rank:pairwise} set xgboost to do ranking task by minimizing the pairwise loss.
|
||||||
@@ -124,22 +126,24 @@
|
|||||||
#' Parallelization is automatically enabled if \code{OpenMP} is present.
|
#' Parallelization is automatically enabled if \code{OpenMP} is present.
|
||||||
#' Number of threads can also be manually specified via \code{nthread} parameter.
|
#' 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.
|
#' when the \code{eval_metric} parameter is not provided.
|
||||||
#' User may set one or several \code{eval_metric} parameters.
|
#' User may set one or several \code{eval_metric} parameters.
|
||||||
#' Note that when using a customized metric, only this single metric can be used.
|
#' 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{
|
#' \itemize{
|
||||||
#' \item \code{rmse} root mean square error. \url{http://en.wikipedia.org/wiki/Root_mean_square_error}
|
#' \item \code{rmse} root mean square error. \url{https://en.wikipedia.org/wiki/Root_mean_square_error}
|
||||||
#' \item \code{logloss} negative log-likelihood. \url{http://en.wikipedia.org/wiki/Log-likelihood}
|
#' \item \code{logloss} negative log-likelihood. \url{https://en.wikipedia.org/wiki/Log-likelihood}
|
||||||
#' \item \code{mlogloss} multiclass logloss. \url{http://wiki.fast.ai/index.php/Log_Loss}
|
#' \item \code{mlogloss} multiclass logloss. \url{https://scikit-learn.org/stable/modules/generated/sklearn.metrics.log_loss.html}
|
||||||
#' \item \code{error} Binary classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
#' \item \code{error} Binary classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
||||||
#' By default, it uses the 0.5 threshold for predicted values to define negative and positive instances.
|
#' By default, it uses the 0.5 threshold for predicted values to define negative and positive instances.
|
||||||
#' Different threshold (e.g., 0.) could be specified as "error@0."
|
#' Different threshold (e.g., 0.) could be specified as "error@0."
|
||||||
#' \item \code{merror} Multiclass classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
#' \item \code{merror} Multiclass classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
||||||
#' \item \code{auc} Area under the curve. \url{http://en.wikipedia.org/wiki/Receiver_operating_characteristic#'Area_under_curve} for ranking evaluation.
|
#' \item \code{mae} Mean absolute error
|
||||||
|
#' \item \code{mape} Mean absolute percentage error
|
||||||
|
#' \item \code{auc} Area under the curve. \url{https://en.wikipedia.org/wiki/Receiver_operating_characteristic#'Area_under_curve} for ranking evaluation.
|
||||||
#' \item \code{aucpr} Area under the PR curve. \url{https://en.wikipedia.org/wiki/Precision_and_recall} for ranking evaluation.
|
#' \item \code{aucpr} Area under the PR curve. \url{https://en.wikipedia.org/wiki/Precision_and_recall} for ranking evaluation.
|
||||||
#' \item \code{ndcg} Normalized Discounted Cumulative Gain (for ranking task). \url{http://en.wikipedia.org/wiki/NDCG}
|
#' \item \code{ndcg} Normalized Discounted Cumulative Gain (for ranking task). \url{https://en.wikipedia.org/wiki/NDCG}
|
||||||
#' }
|
#' }
|
||||||
#'
|
#'
|
||||||
#' The following callbacks are automatically created when certain parameters are set:
|
#' The following callbacks are automatically created when certain parameters are set:
|
||||||
@@ -167,9 +171,6 @@
|
|||||||
#' explicitly passed.
|
#' explicitly passed.
|
||||||
#' \item \code{best_iteration} iteration number with the best evaluation metric value
|
#' \item \code{best_iteration} iteration number with the best evaluation metric value
|
||||||
#' (only available with early stopping).
|
#' (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.
|
#' \item \code{best_score} the best evaluation metric value during early stopping.
|
||||||
#' (only available with early stopping).
|
#' (only available with early stopping).
|
||||||
#' \item \code{feature_names} names of the training dataset features
|
#' \item \code{feature_names} names of the training dataset features
|
||||||
@@ -191,8 +192,8 @@
|
|||||||
#' data(agaricus.train, package='xgboost')
|
#' data(agaricus.train, package='xgboost')
|
||||||
#' data(agaricus.test, package='xgboost')
|
#' data(agaricus.test, package='xgboost')
|
||||||
#'
|
#'
|
||||||
#' dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
#' dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
#' dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
#' watchlist <- list(train = dtrain, eval = dtest)
|
#' watchlist <- list(train = dtrain, eval = dtest)
|
||||||
#'
|
#'
|
||||||
#' ## A simple xgb.train example:
|
#' ## A simple xgb.train example:
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
#' Load the instance back from \code{\link{xgb.serialize}}
|
#' Load the instance back from \code{\link{xgb.serialize}}
|
||||||
#'
|
#'
|
||||||
#' @param buffer the buffer containing booster instance saved by \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
|
#' @export
|
||||||
xgb.unserialize <- function(buffer) {
|
xgb.unserialize <- function(buffer, handle = NULL) {
|
||||||
cachelist <- list()
|
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(
|
tryCatch(
|
||||||
.Call(XGBoosterUnserializeFromBuffer_R, handle, buffer),
|
.Call(XGBoosterUnserializeFromBuffer_R, handle, buffer),
|
||||||
error = function(e) {
|
error = function(e) {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ xgboost <- function(data = NULL, label = NULL, missing = NA, weight = NULL,
|
|||||||
early_stopping_rounds = NULL, maximize = NULL,
|
early_stopping_rounds = NULL, maximize = NULL,
|
||||||
save_period = NULL, save_name = "xgboost.model",
|
save_period = NULL, save_name = "xgboost.model",
|
||||||
xgb_model = NULL, callbacks = list(), ...) {
|
xgb_model = NULL, callbacks = list(), ...) {
|
||||||
|
merged <- check.booster.params(params, ...)
|
||||||
dtrain <- xgb.get.DMatrix(data, label, missing, weight)
|
dtrain <- xgb.get.DMatrix(data, label, missing, weight, nthread = merged$nthread)
|
||||||
|
|
||||||
watchlist <- list(train = dtrain)
|
watchlist <- list(train = dtrain)
|
||||||
|
|
||||||
@@ -90,12 +90,8 @@ NULL
|
|||||||
#' @importFrom data.table setkey
|
#' @importFrom data.table setkey
|
||||||
#' @importFrom data.table setkeyv
|
#' @importFrom data.table setkeyv
|
||||||
#' @importFrom data.table setnames
|
#' @importFrom data.table setnames
|
||||||
#' @importFrom magrittr %>%
|
#' @importFrom jsonlite fromJSON
|
||||||
#' @importFrom stringi stri_detect_regex
|
#' @importFrom jsonlite toJSON
|
||||||
#' @importFrom stringi stri_match_first_regex
|
|
||||||
#' @importFrom stringi stri_replace_first_regex
|
|
||||||
#' @importFrom stringi stri_replace_all_regex
|
|
||||||
#' @importFrom stringi stri_split_regex
|
|
||||||
#' @importFrom utils object.size str tail
|
#' @importFrom utils object.size str tail
|
||||||
#' @importFrom stats predict
|
#' @importFrom stats predict
|
||||||
#' @importFrom stats median
|
#' @importFrom stats median
|
||||||
|
|||||||
@@ -30,4 +30,4 @@ Examples
|
|||||||
Development
|
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
|
#!/bin/sh
|
||||||
|
|
||||||
rm -f src/Makevars
|
rm -f src/Makevars
|
||||||
rm -f CMakeLists.txt
|
|
||||||
|
|||||||
34
R-package/configure
vendored
34
R-package/configure
vendored
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69 for xgboost 0.6-3.
|
# Generated by GNU Autoconf 2.69 for xgboost 1.7.2.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||||
@@ -576,8 +576,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='xgboost'
|
PACKAGE_NAME='xgboost'
|
||||||
PACKAGE_TARNAME='xgboost'
|
PACKAGE_TARNAME='xgboost'
|
||||||
PACKAGE_VERSION='0.6-3'
|
PACKAGE_VERSION='1.7.2'
|
||||||
PACKAGE_STRING='xgboost 0.6-3'
|
PACKAGE_STRING='xgboost 1.7.2'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
@@ -1195,7 +1195,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures xgboost 0.6-3 to adapt to many kinds of systems.
|
\`configure' configures xgboost 1.7.2 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -1257,7 +1257,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of xgboost 0.6-3:";;
|
short | recursive ) echo "Configuration of xgboost 1.7.2:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1336,7 +1336,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
xgboost configure 0.6-3
|
xgboost configure 1.7.2
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
@@ -1479,7 +1479,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by xgboost $as_me 0.6-3, which was
|
It was created by xgboost $as_me 1.7.2, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@@ -2709,8 +2709,15 @@ fi
|
|||||||
|
|
||||||
if test `uname -s` = "Darwin"
|
if test `uname -s` = "Darwin"
|
||||||
then
|
then
|
||||||
OPENMP_CXXFLAGS='-Xclang -fopenmp'
|
if command -v brew &> /dev/null
|
||||||
OPENMP_LIB='-lomp'
|
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_pkg_openmp=no
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenMP will work in a package" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenMP will work in a package" >&5
|
||||||
$as_echo_n "checking whether OpenMP will work in a package... " >&6; }
|
$as_echo_n "checking whether OpenMP will work in a package... " >&6; }
|
||||||
@@ -2725,14 +2732,14 @@ main ()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_ACEOF
|
_ACEOF
|
||||||
${CC} -o conftest conftest.c ${OPENMP_LIB} ${OPENMP_CXXFLAGS} 2>/dev/null && ./conftest && ac_pkg_openmp=yes
|
${CC} -o conftest conftest.c ${CPPFLAGS} ${LDFLAGS} ${OPENMP_LIB} ${OPENMP_CXXFLAGS} 2>/dev/null && ./conftest && ac_pkg_openmp=yes
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_pkg_openmp}" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_pkg_openmp}" >&5
|
||||||
$as_echo "${ac_pkg_openmp}" >&6; }
|
$as_echo "${ac_pkg_openmp}" >&6; }
|
||||||
if test "${ac_pkg_openmp}" = no; then
|
if test "${ac_pkg_openmp}" = no; then
|
||||||
OPENMP_CXXFLAGS=''
|
OPENMP_CXXFLAGS=''
|
||||||
OPENMP_LIB=''
|
OPENMP_LIB=''
|
||||||
echo '*****************************************************************************************'
|
echo '*****************************************************************************************'
|
||||||
echo 'WARNING: OpenMP is unavailable on this Mac OSX system. Training speed may be suboptimal.'
|
echo ' OpenMP is unavailable on this Mac OSX system. Training speed may be suboptimal.'
|
||||||
echo ' To use all CPU cores for training jobs, you should install OpenMP by running\n'
|
echo ' To use all CPU cores for training jobs, you should install OpenMP by running\n'
|
||||||
echo ' brew install libomp'
|
echo ' brew install libomp'
|
||||||
echo '*****************************************************************************************'
|
echo '*****************************************************************************************'
|
||||||
@@ -3287,7 +3294,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by xgboost $as_me 0.6-3, which was
|
This file was extended by xgboost $as_me 1.7.2, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -3340,7 +3347,7 @@ _ACEOF
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
xgboost config.status 0.6-3
|
xgboost config.status 1.7.2
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
@@ -3900,4 +3907,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
|
|||||||
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
|
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
AC_PREREQ(2.69)
|
AC_PREREQ(2.69)
|
||||||
|
|
||||||
AC_INIT([xgboost],[0.6-3],[],[xgboost],[])
|
AC_INIT([xgboost],[1.7.2],[],[xgboost],[])
|
||||||
|
|
||||||
# Use this line to set CC variable to a C compiler
|
# Use this line to set CC variable to a C compiler
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
@@ -28,18 +28,25 @@ fi
|
|||||||
|
|
||||||
if test `uname -s` = "Darwin"
|
if test `uname -s` = "Darwin"
|
||||||
then
|
then
|
||||||
OPENMP_CXXFLAGS='-Xclang -fopenmp'
|
if command -v brew &> /dev/null
|
||||||
OPENMP_LIB='-lomp'
|
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_pkg_openmp=no
|
||||||
AC_MSG_CHECKING([whether OpenMP will work in a package])
|
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); ]])])
|
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
|
${CC} -o conftest conftest.c ${CPPFLAGS} ${LDFLAGS} ${OPENMP_LIB} ${OPENMP_CXXFLAGS} 2>/dev/null && ./conftest && ac_pkg_openmp=yes
|
||||||
AC_MSG_RESULT([${ac_pkg_openmp}])
|
AC_MSG_RESULT([${ac_pkg_openmp}])
|
||||||
if test "${ac_pkg_openmp}" = no; then
|
if test "${ac_pkg_openmp}" = no; then
|
||||||
OPENMP_CXXFLAGS=''
|
OPENMP_CXXFLAGS=''
|
||||||
OPENMP_LIB=''
|
OPENMP_LIB=''
|
||||||
echo '*****************************************************************************************'
|
echo '*****************************************************************************************'
|
||||||
echo 'WARNING: OpenMP is unavailable on this Mac OSX system. Training speed may be suboptimal.'
|
echo ' OpenMP is unavailable on this Mac OSX system. Training speed may be suboptimal.'
|
||||||
echo ' To use all CPU cores for training jobs, you should install OpenMP by running\n'
|
echo ' To use all CPU cores for training jobs, you should install OpenMP by running\n'
|
||||||
echo ' brew install libomp'
|
echo ' brew install libomp'
|
||||||
echo '*****************************************************************************************'
|
echo '*****************************************************************************************'
|
||||||
@@ -52,4 +59,3 @@ AC_SUBST(ENDIAN_FLAG)
|
|||||||
AC_SUBST(BACKTRACE_LIB)
|
AC_SUBST(BACKTRACE_LIB)
|
||||||
AC_CONFIG_FILES([src/Makevars])
|
AC_CONFIG_FILES([src/Makevars])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
basic_walkthrough Basic feature walkthrough
|
basic_walkthrough Basic feature walkthrough
|
||||||
caret_wrapper Use xgboost to train in caret library
|
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
|
boost_from_prediction Boosting from existing prediction
|
||||||
predict_first_ntree Predicting using first n trees
|
predict_first_ntree Predicting using first n trees
|
||||||
generalized_linear_model Generalized Linear Model
|
generalized_linear_model Generalized Linear Model
|
||||||
@@ -8,8 +8,8 @@ cross_validation Cross validation
|
|||||||
create_sparse_matrix Create Sparse Matrix
|
create_sparse_matrix Create Sparse Matrix
|
||||||
predict_leaf_indices Predicting the corresponding leaves
|
predict_leaf_indices Predicting the corresponding leaves
|
||||||
early_stopping Early Stop in training
|
early_stopping Early Stop in training
|
||||||
poisson_regression Poisson Regression on count data
|
poisson_regression Poisson regression on count data
|
||||||
tweedie_regression Tweddie Regression
|
tweedie_regression Tweedie regression
|
||||||
gpu_accelerated GPU-accelerated tree building algorithms
|
gpu_accelerated GPU-accelerated tree building algorithms
|
||||||
interaction_constraints Interaction constraints among features
|
interaction_constraints Interaction constraints among features
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ XGBoost R Feature Walkthrough
|
|||||||
====
|
====
|
||||||
* [Basic walkthrough of wrappers](basic_walkthrough.R)
|
* [Basic walkthrough of wrappers](basic_walkthrough.R)
|
||||||
* [Train a xgboost model from caret library](caret_wrapper.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)
|
* [Boosting from existing prediction](boost_from_prediction.R)
|
||||||
* [Predicting using first n trees](predict_first_ntree.R)
|
* [Predicting using first n trees](predict_first_ntree.R)
|
||||||
* [Generalized Linear Model](generalized_linear_model.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,
|
bst <- xgboost(data = dtrain, max_depth = 2, eta = 1, nrounds = 2,
|
||||||
nthread = 2, objective = "binary:logistic", verbose = 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
|
# 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")
|
# 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
|
# save model to R's raw vector
|
||||||
raw <- xgb.save.raw(bst)
|
raw <- xgb.save.raw(bst)
|
||||||
# load binary model to R
|
# load binary model to R
|
||||||
bst3 <- xgb.load(raw)
|
bst3 <- xgb.load.raw(raw)
|
||||||
pred3 <- predict(bst3, test$data)
|
pred3 <- predict(bst3, test$data)
|
||||||
# pred3 should be identical to pred
|
# pred3 should be identical to pred
|
||||||
print(paste("sum(abs(pred3-pred))=", sum(abs(pred3 - pred))))
|
print(paste("sum(abs(pred3-pred))=", sum(abs(pred3 - pred))))
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ require(xgboost)
|
|||||||
require(Matrix)
|
require(Matrix)
|
||||||
require(data.table)
|
require(data.table)
|
||||||
if (!require(vcd)) {
|
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)
|
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.
|
# 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.
|
# 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.
|
# In R, categorical variable is called Factor.
|
||||||
# Type ?factor in console for more information.
|
# 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".
|
# The method we are going to see is usually called "one hot encoding".
|
||||||
|
|
||||||
#load Arthritis dataset in memory.
|
#load Arthritis dataset in memory.
|
||||||
@@ -25,13 +25,13 @@ df <- data.table(Arthritis, keep.rownames = FALSE)
|
|||||||
cat("Print the dataset\n")
|
cat("Print the dataset\n")
|
||||||
print(df)
|
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")
|
cat("Structure of the dataset\n")
|
||||||
str(df)
|
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.
|
# 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))]
|
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!).
|
# 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)
|
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
|
# See custom_objective.R
|
||||||
##
|
##
|
||||||
print ('running cross validation, with cutomsized loss function')
|
print ('running cross validation, with customized loss function')
|
||||||
|
|
||||||
logregobj <- function(preds, dtrain) {
|
logregobj <- function(preds, dtrain) {
|
||||||
labels <- getinfo(dtrain, "label")
|
labels <- getinfo(dtrain, "label")
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ watchlist <- list(eval = dtest, train = dtrain)
|
|||||||
num_round <- 2
|
num_round <- 2
|
||||||
|
|
||||||
# user define objective function, given prediction, return gradient and second order gradient
|
# 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) {
|
logregobj <- function(preds, dtrain) {
|
||||||
labels <- getinfo(dtrain, "label")
|
labels <- getinfo(dtrain, "label")
|
||||||
preds <- 1 / (1 + exp(-preds))
|
preds <- 1 / (1 + exp(-preds))
|
||||||
@@ -23,9 +23,9 @@ logregobj <- function(preds, dtrain) {
|
|||||||
|
|
||||||
# user defined evaluation function, return a pair metric_name, result
|
# user defined evaluation function, return a pair metric_name, result
|
||||||
# NOTE: when you do customized loss function, the default prediction value is margin
|
# 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
|
# 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
|
# Take this in mind when you use the customization, and maybe you need write customized evaluation function
|
||||||
evalerror <- function(preds, dtrain) {
|
evalerror <- function(preds, dtrain) {
|
||||||
labels <- getinfo(dtrain, "label")
|
labels <- getinfo(dtrain, "label")
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ param <- list(max_depth = 2, eta = 1, nthread = 2, verbosity = 0)
|
|||||||
watchlist <- list(eval = dtest)
|
watchlist <- list(eval = dtest)
|
||||||
num_round <- 20
|
num_round <- 20
|
||||||
# user define objective function, given prediction, return gradient and second order gradient
|
# 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) {
|
logregobj <- function(preds, dtrain) {
|
||||||
labels <- getinfo(dtrain, "label")
|
labels <- getinfo(dtrain, "label")
|
||||||
preds <- 1 / (1 + exp(-preds))
|
preds <- 1 / (1 + exp(-preds))
|
||||||
@@ -21,9 +21,9 @@ logregobj <- function(preds, dtrain) {
|
|||||||
}
|
}
|
||||||
# user defined evaluation function, return a pair metric_name, result
|
# user defined evaluation function, return a pair metric_name, result
|
||||||
# NOTE: when you do customized loss function, the default prediction value is margin
|
# 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
|
# 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
|
# Take this in mind when you use the customization, and maybe you need write customized evaluation function
|
||||||
evalerror <- function(preds, dtrain) {
|
evalerror <- function(preds, dtrain) {
|
||||||
labels <- getinfo(dtrain, "label")
|
labels <- getinfo(dtrain, "label")
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ treeInteractions <- function(input_tree, input_max_depth) {
|
|||||||
interaction_trees <- trees[!is.na(Split) & !is.na(parent_1),
|
interaction_trees <- trees[!is.na(Split) & !is.na(parent_1),
|
||||||
c('Feature', paste0('parent_feat_', 1:(input_max_depth - 1))),
|
c('Feature', paste0('parent_feat_', 1:(input_max_depth - 1))),
|
||||||
with = FALSE]
|
with = FALSE]
|
||||||
interaction_trees_split <- split(interaction_trees, 1:nrow(interaction_trees))
|
interaction_trees_split <- split(interaction_trees, seq_len(nrow(interaction_trees)))
|
||||||
interaction_list <- lapply(interaction_trees_split, as.character)
|
interaction_list <- lapply(interaction_trees_split, as.character)
|
||||||
|
|
||||||
# Remove NAs (no parent interaction)
|
# Remove NAs (no parent interaction)
|
||||||
@@ -101,8 +101,8 @@ bst3_interactions <- treeInteractions(bst3_tree, 4)
|
|||||||
|
|
||||||
# Show monotonic constraints still apply by checking scores after incrementing V1
|
# Show monotonic constraints still apply by checking scores after incrementing V1
|
||||||
x1 <- sort(unique(x[['V1']]))
|
x1 <- sort(unique(x[['V1']]))
|
||||||
for (i in 1:length(x1)){
|
for (i in seq_along(x1)){
|
||||||
testdata <- copy(x[, -c('V1')])
|
testdata <- copy(x[, - ('V1')])
|
||||||
testdata[['V1']] <- x1[i]
|
testdata[['V1']] <- x1[i]
|
||||||
testdata <- testdata[, paste0('V', 1:10), with = FALSE]
|
testdata <- testdata[, paste0('V', 1:10), with = FALSE]
|
||||||
pred <- predict(bst3, as.matrix(testdata))
|
pred <- predict(bst3, as.matrix(testdata))
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ bst2 <- xgb.load('xgb.model')
|
|||||||
# Save as a stand-alone file (JSON); load it with xgb.load()
|
# Save as a stand-alone file (JSON); load it with xgb.load()
|
||||||
xgb.save(bst, 'xgb.model.json')
|
xgb.save(bst, 'xgb.model.json')
|
||||||
bst2 <- xgb.load('xgb.model.json')
|
bst2 <- xgb.load('xgb.model.json')
|
||||||
|
if (file.exists('xgb.model.json')) file.remove('xgb.model.json')
|
||||||
|
|
||||||
# Save as a raw byte vector; load it with xgb.load.raw()
|
# Save as a raw byte vector; load it with xgb.load.raw()
|
||||||
xgb_bytes <- xgb.save.raw(bst)
|
xgb_bytes <- xgb.save.raw(bst)
|
||||||
@@ -58,5 +59,6 @@ saveRDS(obj, 'my_object.rds')
|
|||||||
obj2 <- readRDS('my_object.rds')
|
obj2 <- readRDS('my_object.rds')
|
||||||
# Re-construct xgb.Booster object from the bytes
|
# Re-construct xgb.Booster object from the bytes
|
||||||
bst2 <- xgb.load.raw(obj2$xgb_model_bytes)
|
bst2 <- xgb.load.raw(obj2$xgb_model_bytes)
|
||||||
|
if (file.exists('my_object.rds')) file.remove('my_object.rds')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,7 @@ The following additional fields are assigned to the model's R object:
|
|||||||
\itemize{
|
\itemize{
|
||||||
\item \code{best_score} the evaluation score at the best iteration
|
\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_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:
|
The Same values are also stored as xgb-attributes:
|
||||||
\itemize{
|
\itemize{
|
||||||
\item \code{best_iteration} is stored as a 0-based iteration index (for interoperability of binary models)
|
\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)
|
cb.gblinear.history(sparse = FALSE)
|
||||||
}
|
}
|
||||||
\arguments{
|
\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,
|
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
|
when using the "thrifty" feature selector with fairly small number of top features
|
||||||
selected per iteration.}
|
selected per iteration.}
|
||||||
}
|
}
|
||||||
\value{
|
\value{
|
||||||
Results are stored in the \code{coefs} element of the closure.
|
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.
|
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{
|
\description{
|
||||||
Callback closure for collecting the model coefficients history of a gblinear booster
|
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
|
# In the iris dataset, it is hard to linearly separate Versicolor class from the rest
|
||||||
# without considering the 2nd order interactions:
|
# without considering the 2nd order interactions:
|
||||||
require(magrittr)
|
|
||||||
x <- model.matrix(Species ~ .^2, iris)[,-1]
|
x <- model.matrix(Species ~ .^2, iris)[,-1]
|
||||||
colnames(x)
|
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",
|
param <- list(booster = "gblinear", objective = "reg:logistic", eval_metric = "auc",
|
||||||
lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||||
# For 'shotgun', which is a default linear updater, using high eta values may result in
|
# 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,
|
bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 200, eta = 0.8,
|
||||||
updater = 'coord_descent', feature_selector = 'thrifty', top_k = 1,
|
updater = 'coord_descent', feature_selector = 'thrifty', top_k = 1,
|
||||||
callbacks = list(cb.gblinear.history()))
|
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.
|
# Componentwise boosting is known to have similar effect to Lasso regularization.
|
||||||
# Try experimenting with various values of top_k, eta, nrounds,
|
# Try experimenting with various values of top_k, eta, nrounds,
|
||||||
# as well as different feature_selectors.
|
# as well as different feature_selectors.
|
||||||
|
|
||||||
# For xgb.cv:
|
# For xgb.cv:
|
||||||
bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 100, eta = 0.8,
|
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
|
# coefficients in the CV fold #3
|
||||||
xgb.gblinear.history(bst)[[3]] \%>\% matplot(type = 'l')
|
matplot(xgb.gblinear.history(bst)[[3]], type = 'l')
|
||||||
|
|
||||||
|
|
||||||
#### Multiclass classification:
|
#### 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,
|
param <- list(booster = "gblinear", objective = "multi:softprob", num_class = 3,
|
||||||
lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
lambda = 0.0003, alpha = 0.0003, nthread = 2)
|
||||||
# For the default linear updater 'shotgun' it sometimes is helpful
|
# 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,
|
bst <- xgb.train(param, dtrain, list(tr=dtrain), nrounds = 70, eta = 0.5,
|
||||||
callbacks = list(cb.gblinear.history()))
|
callbacks = list(cb.gblinear.history()))
|
||||||
# Will plot the coefficient paths separately for each class:
|
# Will plot the coefficient paths separately for each class:
|
||||||
xgb.gblinear.history(bst, class_index = 0) \%>\% matplot(type = 'l')
|
matplot(xgb.gblinear.history(bst, class_index = 0), type = 'l')
|
||||||
xgb.gblinear.history(bst, class_index = 1) \%>\% matplot(type = 'l')
|
matplot(xgb.gblinear.history(bst, class_index = 1), type = 'l')
|
||||||
xgb.gblinear.history(bst, class_index = 2) \%>\% matplot(type = 'l')
|
matplot(xgb.gblinear.history(bst, class_index = 2), type = 'l')
|
||||||
|
|
||||||
# CV:
|
# CV:
|
||||||
bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 70, eta = 0.5,
|
bst <- xgb.cv(param, dtrain, nfold = 5, nrounds = 70, eta = 0.5,
|
||||||
callbacks = list(cb.gblinear.history(FALSE)))
|
callbacks = list(cb.gblinear.history(FALSE)))
|
||||||
# 1st forld of 1st class
|
# 1st fold of 1st class
|
||||||
xgb.gblinear.history(bst, class_index = 0)[[1]] \%>\% matplot(type = 'l')
|
matplot(xgb.gblinear.history(bst, class_index = 0)[[1]], type = 'l')
|
||||||
|
|
||||||
}
|
}
|
||||||
\seealso{
|
\seealso{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ be directly used with an \code{xgb.DMatrix} object.
|
|||||||
\examples{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
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(nrow(dtrain) == nrow(train$data))
|
||||||
stopifnot(ncol(dtrain) == ncol(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{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
train <- agaricus.train
|
||||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
dtrain <- xgb.DMatrix(train$data, label=train$label, nthread = 2)
|
||||||
dimnames(dtrain)
|
dimnames(dtrain)
|
||||||
colnames(dtrain)
|
colnames(dtrain)
|
||||||
colnames(dtrain) <- make.names(1:ncol(train$data))
|
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:
|
The \code{name} field can be one of the following:
|
||||||
|
|
||||||
\itemize{
|
\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{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}.
|
\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{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
|
|
||||||
labels <- getinfo(dtrain, 'label')
|
labels <- getinfo(dtrain, 'label')
|
||||||
setinfo(dtrain, 'label', 1-labels)
|
setinfo(dtrain, 'label', 1-labels)
|
||||||
|
|||||||
18
R-package/man/normalize.Rd
Normal file
18
R-package/man/normalize.Rd
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/xgb.ggplot.R
|
||||||
|
\name{normalize}
|
||||||
|
\alias{normalize}
|
||||||
|
\title{Scale feature value to have mean 0, standard deviation 1}
|
||||||
|
\usage{
|
||||||
|
normalize(x)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{x}{Numeric vector}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
Numeric vector with mean 0 and sd 1.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
This is used to compare multiple features on the same plot.
|
||||||
|
Internal utility function
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
predinteraction = FALSE,
|
predinteraction = FALSE,
|
||||||
reshape = FALSE,
|
reshape = FALSE,
|
||||||
training = FALSE,
|
training = FALSE,
|
||||||
|
iterationrange = NULL,
|
||||||
|
strict_shape = FALSE,
|
||||||
...
|
...
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,7 +27,11 @@
|
|||||||
\arguments{
|
\arguments{
|
||||||
\item{object}{Object of class \code{xgb.Booster} or \code{xgb.Booster.handle}}
|
\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
|
\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).}
|
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
|
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.}
|
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).
|
\item{ntreelimit}{Deprecated, use \code{iterationrange} instead.}
|
||||||
It will use all the trees by default (\code{NULL} value).}
|
|
||||||
|
|
||||||
\item{predleaf}{whether predict leaf index.}
|
\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,
|
\item{training}{whether is the prediction result used for training. For dart booster,
|
||||||
training predicting will perform dropout.}
|
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}}
|
\item{...}{Parameters passed to \code{predict.xgb.Booster}}
|
||||||
}
|
}
|
||||||
\value{
|
\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
|
For multiclass classification, either a \code{num_class * nrows(newdata)} vector or
|
||||||
a \code{(nrows(newdata), num_class)} dimension matrix is returned, depending on
|
a \code{(nrows(newdata), num_class)} dimension matrix is returned, depending on
|
||||||
the \code{reshape} value.
|
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}.
|
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
|
For a multiclass case, a list of \code{num_class} elements is returned, where each element is
|
||||||
such an array.
|
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{
|
\description{
|
||||||
Predicted values based on either xgboost model or model handle object.
|
Predicted values based on either xgboost model or model handle object.
|
||||||
}
|
}
|
||||||
\details{
|
\details{
|
||||||
Note that \code{ntreelimit} is not necessarily equal to the number of boosting iterations
|
Note that \code{iterationrange} would currently do nothing for predictions from gblinear,
|
||||||
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,
|
|
||||||
since gblinear doesn't keep its boosting history.
|
since gblinear doesn't keep its boosting history.
|
||||||
|
|
||||||
One possible practical applications of the \code{predleaf} option is to use the model
|
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
|
# use all trees by default
|
||||||
pred <- predict(bst, test$data)
|
pred <- predict(bst, test$data)
|
||||||
# use only the 1st tree
|
# use only the 1st tree
|
||||||
pred1 <- predict(bst, test$data, ntreelimit = 1)
|
pred1 <- predict(bst, test$data, iterationrange = c(1, 2))
|
||||||
|
|
||||||
# Predicting tree leafs:
|
# Predicting tree leafs:
|
||||||
# the result is an nsamples X ntrees matrix
|
# the result is an nsamples X ntrees matrix
|
||||||
@@ -172,25 +188,9 @@ str(pred)
|
|||||||
all.equal(pred, pred_labels)
|
all.equal(pred, pred_labels)
|
||||||
# prediction from using only 5 iterations should result
|
# prediction from using only 5 iterations should result
|
||||||
# in the same error as seen in iteration 5:
|
# 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)
|
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{
|
\references{
|
||||||
Scott M. Lundberg, Su-In Lee, "A Unified Approach to Interpreting Model Predictions", NIPS Proceedings 2017, \url{https://arxiv.org/abs/1705.07874}
|
Scott M. Lundberg, Su-In Lee, "A Unified Approach to Interpreting Model Predictions", NIPS Proceedings 2017, \url{https://arxiv.org/abs/1705.07874}
|
||||||
|
|||||||
27
R-package/man/prepare.ggplot.shap.data.Rd
Normal file
27
R-package/man/prepare.ggplot.shap.data.Rd
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/xgb.ggplot.R
|
||||||
|
\name{prepare.ggplot.shap.data}
|
||||||
|
\alias{prepare.ggplot.shap.data}
|
||||||
|
\title{Combine and melt feature values and SHAP contributions for sample
|
||||||
|
observations.}
|
||||||
|
\usage{
|
||||||
|
prepare.ggplot.shap.data(data_list, normalize = FALSE)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{data_list}{List containing 'data' and 'shap_contrib' returned by
|
||||||
|
\code{xgb.shap.data()}.}
|
||||||
|
|
||||||
|
\item{normalize}{Whether to standardize feature values to have mean 0 and
|
||||||
|
standard deviation 1 (useful for comparing multiple features on the same
|
||||||
|
plot). Default \code{FALSE}.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A data.table containing the observation ID, the feature name, the
|
||||||
|
feature value (normalized if specified), and the SHAP contribution value.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Conforms to data format required for ggplot functions.
|
||||||
|
}
|
||||||
|
\details{
|
||||||
|
Internal utility function.
|
||||||
|
}
|
||||||
@@ -19,8 +19,7 @@ Currently it displays dimensions and presence of info-fields and colnames.
|
|||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
|
|
||||||
dtrain
|
dtrain
|
||||||
print(dtrain, verbose=TRUE)
|
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:
|
The \code{name} field can be one of the following:
|
||||||
|
|
||||||
\itemize{
|
\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{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).
|
\item \code{group}: number of rows in each group (to use with \code{rank:pairwise} objective).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
|
|
||||||
labels <- getinfo(dtrain, 'label')
|
labels <- getinfo(dtrain, 'label')
|
||||||
setinfo(dtrain, 'label', 1-labels)
|
setinfo(dtrain, 'label', 1-labels)
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ original xgb.DMatrix object
|
|||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
|
|
||||||
dsub <- slice(dtrain, 1:42)
|
dsub <- slice(dtrain, 1:42)
|
||||||
labels1 <- getinfo(dsub, 'label')
|
labels1 <- getinfo(dsub, 'label')
|
||||||
|
|||||||
@@ -4,11 +4,20 @@
|
|||||||
\alias{xgb.DMatrix}
|
\alias{xgb.DMatrix}
|
||||||
\title{Construct xgb.DMatrix object}
|
\title{Construct xgb.DMatrix object}
|
||||||
\usage{
|
\usage{
|
||||||
xgb.DMatrix(data, info = list(), missing = NA, silent = FALSE, ...)
|
xgb.DMatrix(
|
||||||
|
data,
|
||||||
|
info = list(),
|
||||||
|
missing = NA,
|
||||||
|
silent = FALSE,
|
||||||
|
nthread = NULL,
|
||||||
|
...
|
||||||
|
)
|
||||||
}
|
}
|
||||||
\arguments{
|
\arguments{
|
||||||
\item{data}{a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object, or a character
|
\item{data}{a \code{matrix} object (either numeric or integer), a \code{dgCMatrix} object,
|
||||||
string representing a filename.}
|
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.
|
\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}
|
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{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.}
|
\item{...}{the \code{info} data could be passed directly as parameters, without creating an \code{info} list.}
|
||||||
}
|
}
|
||||||
\description{
|
\description{
|
||||||
Construct xgb.DMatrix object from either a dense matrix, a sparse matrix, or a local file.
|
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}}).
|
\code{\link{xgb.DMatrix.save}}).
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||||
dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||||
if (file.exists('xgb.DMatrix.data')) file.remove('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{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
train <- agaricus.train
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtrain <- xgb.DMatrix(train$data, label=train$label)
|
|
||||||
xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
xgb.DMatrix.save(dtrain, 'xgb.DMatrix.data')
|
||||||
dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
dtrain <- xgb.DMatrix('xgb.DMatrix.data')
|
||||||
if (file.exists('xgb.DMatrix.data')) file.remove('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
|
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:
|
Extract explaining the method:
|
||||||
|
|
||||||
@@ -59,8 +59,8 @@ a rule on certain features."
|
|||||||
\examples{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
data(agaricus.test, package='xgboost')
|
data(agaricus.test, package='xgboost')
|
||||||
dtrain <- xgb.DMatrix(data = agaricus.train$data, label = agaricus.train$label)
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtest <- xgb.DMatrix(data = agaricus.test$data, label = agaricus.test$label)
|
dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
|
|
||||||
param <- list(max_depth=2, eta=1, silent=1, objective='binary:logistic')
|
param <- list(max_depth=2, eta=1, silent=1, objective='binary:logistic')
|
||||||
nrounds = 4
|
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)
|
new.features.test <- xgb.create.features(model = bst, agaricus.test$data)
|
||||||
|
|
||||||
# learning with new features
|
# learning with new features
|
||||||
new.dtrain <- xgb.DMatrix(data = new.features.train, label = agaricus.train$label)
|
new.dtrain <- xgb.DMatrix(
|
||||||
new.dtest <- xgb.DMatrix(data = new.features.test, label = agaricus.test$label)
|
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)
|
watchlist <- list(train = new.dtrain)
|
||||||
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ from each CV model. This parameter engages the \code{\link{cb.cv.predict}} callb
|
|||||||
\item \code{error} binary classification error rate
|
\item \code{error} binary classification error rate
|
||||||
\item \code{rmse} Rooted mean square error
|
\item \code{rmse} Rooted mean square error
|
||||||
\item \code{logloss} negative log-likelihood function
|
\item \code{logloss} negative log-likelihood function
|
||||||
|
\item \code{mae} Mean absolute error
|
||||||
|
\item \code{mape} Mean absolute percentage error
|
||||||
\item \code{auc} Area under curve
|
\item \code{auc} Area under curve
|
||||||
\item \code{aucpr} Area under PR curve
|
\item \code{aucpr} Area under PR curve
|
||||||
\item \code{merror} Exact matching error, used to evaluate multi-class classification
|
\item \code{merror} Exact matching error, used to evaluate multi-class classification
|
||||||
@@ -133,9 +135,7 @@ An object of class \code{xgb.cv.synchronous} with the following elements:
|
|||||||
parameter or randomly generated.
|
parameter or randomly generated.
|
||||||
\item \code{best_iteration} iteration number with the best evaluation metric value
|
\item \code{best_iteration} iteration number with the best evaluation metric value
|
||||||
(only available with early stopping).
|
(only available with early stopping).
|
||||||
\item \code{best_ntreelimit} the \code{ntreelimit} value corresponding to the best iteration,
|
\item \code{best_ntreelimit} and the \code{ntreelimit} Deprecated attributes, use \code{best_iteration} instead.
|
||||||
which could further be used in \code{predict} method
|
|
||||||
(only available with early stopping).
|
|
||||||
\item \code{pred} CV prediction values available when \code{prediction} is set.
|
\item \code{pred} CV prediction values available when \code{prediction} is set.
|
||||||
It is either vector or matrix (see \code{\link{cb.cv.predict}}).
|
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
|
\item \code{models} a list of the CV folds' models. It is only available with the explicit
|
||||||
@@ -154,13 +154,13 @@ The cross-validation process is then repeated \code{nrounds} times, with each of
|
|||||||
|
|
||||||
All observations are used for both training and validation.
|
All observations are used for both training and validation.
|
||||||
|
|
||||||
Adapted from \url{http://en.wikipedia.org/wiki/Cross-validation_\%28statistics\%29#k-fold_cross-validation}
|
Adapted from \url{https://en.wikipedia.org/wiki/Cross-validation_\%28statistics\%29}
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
data(agaricus.train, package='xgboost')
|
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"),
|
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)
|
||||||
print(cv, verbose=TRUE)
|
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.}
|
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.
|
\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
|
See demo/ for walkthrough example in R, and
|
||||||
\url{https://github.com/dmlc/xgboost/blob/master/demo/data/featmap.txt}
|
\url{https://github.com/dmlc/xgboost/blob/master/demo/data/featmap.txt}
|
||||||
for example Format.}
|
for example Format.}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ An object of \code{xgb.Booster} class.
|
|||||||
Load xgboost model from the binary model file.
|
Load xgboost model from the binary model file.
|
||||||
}
|
}
|
||||||
\details{
|
\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
|
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
|
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.
|
saved from there in xgboost format, could be loaded from R.
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
\alias{xgb.load.raw}
|
\alias{xgb.load.raw}
|
||||||
\title{Load serialised xgboost model from R's raw vector}
|
\title{Load serialised xgboost model from R's raw vector}
|
||||||
\usage{
|
\usage{
|
||||||
xgb.load.raw(buffer)
|
xgb.load.raw(buffer, as_booster = FALSE)
|
||||||
}
|
}
|
||||||
\arguments{
|
\arguments{
|
||||||
\item{buffer}{the buffer returned by xgb.save.raw}
|
\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{
|
\description{
|
||||||
User can generate raw memory buffer by calling xgb.save.raw
|
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{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}.}
|
\item{...}{other parameters passed to \code{plot}.}
|
||||||
}
|
}
|
||||||
@@ -131,6 +131,7 @@ bst <- xgboost(agaricus.train$data, agaricus.train$label, nrounds = 50,
|
|||||||
xgb.plot.shap(agaricus.test$data, model = bst, features = "odor=none")
|
xgb.plot.shap(agaricus.test$data, model = bst, features = "odor=none")
|
||||||
contr <- predict(bst, agaricus.test$data, predcontrib = TRUE)
|
contr <- predict(bst, agaricus.test$data, predcontrib = TRUE)
|
||||||
xgb.plot.shap(agaricus.test$data, contr, model = bst, top_n = 12, n_col = 3)
|
xgb.plot.shap(agaricus.test$data, contr, model = bst, top_n = 12, n_col = 3)
|
||||||
|
xgb.ggplot.shap.summary(agaricus.test$data, contr, model = bst, top_n = 12) # Summary plot
|
||||||
|
|
||||||
# multiclass example - plots for each class separately:
|
# multiclass example - plots for each class separately:
|
||||||
nclass <- 3
|
nclass <- 3
|
||||||
@@ -149,6 +150,7 @@ xgb.plot.shap(x, model = mbst, trees = trees0 + 1, target_class = 1, top_n = 4,
|
|||||||
n_col = 2, col = col, pch = 16, pch_NA = 17)
|
n_col = 2, col = col, pch = 16, pch_NA = 17)
|
||||||
xgb.plot.shap(x, model = mbst, trees = trees0 + 2, target_class = 2, top_n = 4,
|
xgb.plot.shap(x, model = mbst, trees = trees0 + 2, target_class = 2, top_n = 4,
|
||||||
n_col = 2, col = col, pch = 16, pch_NA = 17)
|
n_col = 2, col = col, pch = 16, pch_NA = 17)
|
||||||
|
xgb.ggplot.shap.summary(x, model = mbst, target_class = 0, top_n = 4) # Summary plot
|
||||||
|
|
||||||
}
|
}
|
||||||
\references{
|
\references{
|
||||||
|
|||||||
78
R-package/man/xgb.plot.shap.summary.Rd
Normal file
78
R-package/man/xgb.plot.shap.summary.Rd
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/xgb.ggplot.R, R/xgb.plot.shap.R
|
||||||
|
\name{xgb.ggplot.shap.summary}
|
||||||
|
\alias{xgb.ggplot.shap.summary}
|
||||||
|
\alias{xgb.plot.shap.summary}
|
||||||
|
\title{SHAP contribution dependency summary plot}
|
||||||
|
\usage{
|
||||||
|
xgb.ggplot.shap.summary(
|
||||||
|
data,
|
||||||
|
shap_contrib = NULL,
|
||||||
|
features = NULL,
|
||||||
|
top_n = 10,
|
||||||
|
model = NULL,
|
||||||
|
trees = NULL,
|
||||||
|
target_class = NULL,
|
||||||
|
approxcontrib = FALSE,
|
||||||
|
subsample = NULL
|
||||||
|
)
|
||||||
|
|
||||||
|
xgb.plot.shap.summary(
|
||||||
|
data,
|
||||||
|
shap_contrib = NULL,
|
||||||
|
features = NULL,
|
||||||
|
top_n = 10,
|
||||||
|
model = NULL,
|
||||||
|
trees = NULL,
|
||||||
|
target_class = NULL,
|
||||||
|
approxcontrib = FALSE,
|
||||||
|
subsample = NULL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{data}{data as a \code{matrix} or \code{dgCMatrix}.}
|
||||||
|
|
||||||
|
\item{shap_contrib}{a matrix of SHAP contributions that was computed earlier for the above
|
||||||
|
\code{data}. When it is NULL, it is computed internally using \code{model} and \code{data}.}
|
||||||
|
|
||||||
|
\item{features}{a vector of either column indices or of feature names to plot. When it is NULL,
|
||||||
|
feature importance is calculated, and \code{top_n} high ranked features are taken.}
|
||||||
|
|
||||||
|
\item{top_n}{when \code{features} is NULL, top_n [1, 100] most important features in a model are taken.}
|
||||||
|
|
||||||
|
\item{model}{an \code{xgb.Booster} model. It has to be provided when either \code{shap_contrib}
|
||||||
|
or \code{features} is missing.}
|
||||||
|
|
||||||
|
\item{trees}{passed to \code{\link{xgb.importance}} when \code{features = NULL}.}
|
||||||
|
|
||||||
|
\item{target_class}{is only relevant for multiclass models. When it is set to a 0-based class index,
|
||||||
|
only SHAP contributions for that specific class are used.
|
||||||
|
If it is not set, SHAP importances are averaged over all classes.}
|
||||||
|
|
||||||
|
\item{approxcontrib}{passed to \code{\link{predict.xgb.Booster}} when \code{shap_contrib = NULL}.}
|
||||||
|
|
||||||
|
\item{subsample}{a random fraction of data points to use for plotting. When it is NULL,
|
||||||
|
it is set so that up to 100K data points are used.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A \code{ggplot2} object.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Compare SHAP contributions of different features.
|
||||||
|
}
|
||||||
|
\details{
|
||||||
|
A point plot (each point representing one sample from \code{data}) is
|
||||||
|
produced for each feature, with the points plotted on the SHAP value axis.
|
||||||
|
Each point (observation) is coloured based on its feature value. The plot
|
||||||
|
hence allows us to see which features have a negative / positive contribution
|
||||||
|
on the model prediction, and whether the contribution is different for larger
|
||||||
|
or smaller values of the feature. We effectively try to replicate the
|
||||||
|
\code{summary_plot} function from https://github.com/slundberg/shap.
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
# See \code{\link{xgb.plot.shap}}.
|
||||||
|
}
|
||||||
|
\seealso{
|
||||||
|
\code{\link{xgb.plot.shap}}, \code{\link{xgb.ggplot.shap.summary}},
|
||||||
|
\url{https://github.com/slundberg/shap}
|
||||||
|
}
|
||||||
@@ -5,10 +5,19 @@
|
|||||||
\title{Save xgboost model to R's raw vector,
|
\title{Save xgboost model to R's raw vector,
|
||||||
user can call xgb.load.raw to load the model back from raw vector}
|
user can call xgb.load.raw to load the model back from raw vector}
|
||||||
\usage{
|
\usage{
|
||||||
xgb.save.raw(model)
|
xgb.save.raw(model, raw_format = "deprecated")
|
||||||
}
|
}
|
||||||
\arguments{
|
\arguments{
|
||||||
\item{model}{the model object.}
|
\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{
|
\description{
|
||||||
Save xgboost model from xgboost or xgb.train
|
Save xgboost model from xgboost or xgb.train
|
||||||
|
|||||||
55
R-package/man/xgb.shap.data.Rd
Normal file
55
R-package/man/xgb.shap.data.Rd
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/xgb.plot.shap.R
|
||||||
|
\name{xgb.shap.data}
|
||||||
|
\alias{xgb.shap.data}
|
||||||
|
\title{Prepare data for SHAP plots. To be used in xgb.plot.shap, xgb.plot.shap.summary, etc.
|
||||||
|
Internal utility function.}
|
||||||
|
\usage{
|
||||||
|
xgb.shap.data(
|
||||||
|
data,
|
||||||
|
shap_contrib = NULL,
|
||||||
|
features = NULL,
|
||||||
|
top_n = 1,
|
||||||
|
model = NULL,
|
||||||
|
trees = NULL,
|
||||||
|
target_class = NULL,
|
||||||
|
approxcontrib = FALSE,
|
||||||
|
subsample = NULL,
|
||||||
|
max_observations = 1e+05
|
||||||
|
)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{data}{data as a \code{matrix} or \code{dgCMatrix}.}
|
||||||
|
|
||||||
|
\item{shap_contrib}{a matrix of SHAP contributions that was computed earlier for the above
|
||||||
|
\code{data}. When it is NULL, it is computed internally using \code{model} and \code{data}.}
|
||||||
|
|
||||||
|
\item{features}{a vector of either column indices or of feature names to plot. When it is NULL,
|
||||||
|
feature importance is calculated, and \code{top_n} high ranked features are taken.}
|
||||||
|
|
||||||
|
\item{top_n}{when \code{features} is NULL, top_n [1, 100] most important features in a model are taken.}
|
||||||
|
|
||||||
|
\item{model}{an \code{xgb.Booster} model. It has to be provided when either \code{shap_contrib}
|
||||||
|
or \code{features} is missing.}
|
||||||
|
|
||||||
|
\item{trees}{passed to \code{\link{xgb.importance}} when \code{features = NULL}.}
|
||||||
|
|
||||||
|
\item{target_class}{is only relevant for multiclass models. When it is set to a 0-based class index,
|
||||||
|
only SHAP contributions for that specific class are used.
|
||||||
|
If it is not set, SHAP importances are averaged over all classes.}
|
||||||
|
|
||||||
|
\item{approxcontrib}{passed to \code{\link{predict.xgb.Booster}} when \code{shap_contrib = NULL}.}
|
||||||
|
|
||||||
|
\item{subsample}{a random fraction of data points to use for plotting. When it is NULL,
|
||||||
|
it is set so that up to 100K data points are used.}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
A list containing: 'data', a matrix containing sample observations
|
||||||
|
and their feature values; 'shap_contrib', a matrix containing the SHAP contribution
|
||||||
|
values for these observations.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Prepare data for SHAP plots. To be used in xgb.plot.shap, xgb.plot.shap.summary, etc.
|
||||||
|
Internal utility function.
|
||||||
|
}
|
||||||
|
\keyword{internal}
|
||||||
@@ -54,7 +54,7 @@ xgboost(
|
|||||||
|
|
||||||
2. Booster Parameters
|
2. Booster Parameters
|
||||||
|
|
||||||
2.1. Parameter for Tree Booster
|
2.1. Parameters for Tree Booster
|
||||||
|
|
||||||
\itemize{
|
\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
|
\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{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{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{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{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.
|
\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{
|
\itemize{
|
||||||
\item \code{lambda} L2 regularization term on weights. Default: 0
|
\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: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: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{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: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{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: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{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.
|
\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.
|
explicitly passed.
|
||||||
\item \code{best_iteration} iteration number with the best evaluation metric value
|
\item \code{best_iteration} iteration number with the best evaluation metric value
|
||||||
(only available with early stopping).
|
(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.
|
\item \code{best_score} the best evaluation metric value during early stopping.
|
||||||
(only available with early stopping).
|
(only available with early stopping).
|
||||||
\item \code{feature_names} names of the training dataset features
|
\item \code{feature_names} names of the training dataset features
|
||||||
@@ -209,22 +208,24 @@ than the \code{xgboost} interface.
|
|||||||
Parallelization is automatically enabled if \code{OpenMP} is present.
|
Parallelization is automatically enabled if \code{OpenMP} is present.
|
||||||
Number of threads can also be manually specified via \code{nthread} parameter.
|
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.
|
when the \code{eval_metric} parameter is not provided.
|
||||||
User may set one or several \code{eval_metric} parameters.
|
User may set one or several \code{eval_metric} parameters.
|
||||||
Note that when using a customized metric, only this single metric can be used.
|
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{
|
\itemize{
|
||||||
\item \code{rmse} root mean square error. \url{http://en.wikipedia.org/wiki/Root_mean_square_error}
|
\item \code{rmse} root mean square error. \url{https://en.wikipedia.org/wiki/Root_mean_square_error}
|
||||||
\item \code{logloss} negative log-likelihood. \url{http://en.wikipedia.org/wiki/Log-likelihood}
|
\item \code{logloss} negative log-likelihood. \url{https://en.wikipedia.org/wiki/Log-likelihood}
|
||||||
\item \code{mlogloss} multiclass logloss. \url{http://wiki.fast.ai/index.php/Log_Loss}
|
\item \code{mlogloss} multiclass logloss. \url{https://scikit-learn.org/stable/modules/generated/sklearn.metrics.log_loss.html}
|
||||||
\item \code{error} Binary classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
\item \code{error} Binary classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
||||||
By default, it uses the 0.5 threshold for predicted values to define negative and positive instances.
|
By default, it uses the 0.5 threshold for predicted values to define negative and positive instances.
|
||||||
Different threshold (e.g., 0.) could be specified as "error@0."
|
Different threshold (e.g., 0.) could be specified as "error@0."
|
||||||
\item \code{merror} Multiclass classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
\item \code{merror} Multiclass classification error rate. It is calculated as \code{(# wrong cases) / (# all cases)}.
|
||||||
\item \code{auc} Area under the curve. \url{http://en.wikipedia.org/wiki/Receiver_operating_characteristic#'Area_under_curve} for ranking evaluation.
|
\item \code{mae} Mean absolute error
|
||||||
|
\item \code{mape} Mean absolute percentage error
|
||||||
|
\item \code{auc} Area under the curve. \url{https://en.wikipedia.org/wiki/Receiver_operating_characteristic#'Area_under_curve} for ranking evaluation.
|
||||||
\item \code{aucpr} Area under the PR curve. \url{https://en.wikipedia.org/wiki/Precision_and_recall} for ranking evaluation.
|
\item \code{aucpr} Area under the PR curve. \url{https://en.wikipedia.org/wiki/Precision_and_recall} for ranking evaluation.
|
||||||
\item \code{ndcg} Normalized Discounted Cumulative Gain (for ranking task). \url{http://en.wikipedia.org/wiki/NDCG}
|
\item \code{ndcg} Normalized Discounted Cumulative Gain (for ranking task). \url{https://en.wikipedia.org/wiki/NDCG}
|
||||||
}
|
}
|
||||||
|
|
||||||
The following callbacks are automatically created when certain parameters are set:
|
The following callbacks are automatically created when certain parameters are set:
|
||||||
@@ -240,8 +241,8 @@ The following callbacks are automatically created when certain parameters are se
|
|||||||
data(agaricus.train, package='xgboost')
|
data(agaricus.train, package='xgboost')
|
||||||
data(agaricus.test, package='xgboost')
|
data(agaricus.test, package='xgboost')
|
||||||
|
|
||||||
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
dtrain <- with(agaricus.train, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
dtest <- with(agaricus.test, xgb.DMatrix(data, label = label, nthread = 2))
|
||||||
watchlist <- list(train = dtrain, eval = dtest)
|
watchlist <- list(train = dtrain, eval = dtest)
|
||||||
|
|
||||||
## A simple xgb.train example:
|
## A simple xgb.train example:
|
||||||
|
|||||||
@@ -4,10 +4,17 @@
|
|||||||
\alias{xgb.unserialize}
|
\alias{xgb.unserialize}
|
||||||
\title{Load the instance back from \code{\link{xgb.serialize}}}
|
\title{Load the instance back from \code{\link{xgb.serialize}}}
|
||||||
\usage{
|
\usage{
|
||||||
xgb.unserialize(buffer)
|
xgb.unserialize(buffer, handle = NULL)
|
||||||
}
|
}
|
||||||
\arguments{
|
\arguments{
|
||||||
\item{buffer}{the buffer containing booster instance saved by \code{\link{xgb.serialize}}}
|
\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{
|
\description{
|
||||||
Load the instance back from \code{\link{xgb.serialize}}
|
Load the instance back from \code{\link{xgb.serialize}}
|
||||||
|
|||||||
39
R-package/man/xgbConfig.Rd
Normal file
39
R-package/man/xgbConfig.Rd
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/xgb.config.R
|
||||||
|
\name{xgb.set.config, xgb.get.config}
|
||||||
|
\alias{xgb.set.config, xgb.get.config}
|
||||||
|
\alias{xgb.set.config}
|
||||||
|
\alias{xgb.get.config}
|
||||||
|
\title{Set and get global configuration}
|
||||||
|
\usage{
|
||||||
|
xgb.set.config(...)
|
||||||
|
|
||||||
|
xgb.get.config()
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{...}{List of parameters to be set, as keyword arguments}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
\code{xgb.set.config} returns \code{TRUE} to signal success. \code{xgb.get.config} returns
|
||||||
|
a list containing all global-scope parameters and their values.
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Global configuration consists of a collection of parameters that can be applied in the global
|
||||||
|
scope. See \url{https://xgboost.readthedocs.io/en/stable/parameter.html} for the full list of
|
||||||
|
parameters supported in the global configuration. Use \code{xgb.set.config} to update the
|
||||||
|
values of one or more global-scope parameters. Use \code{xgb.get.config} to fetch the current
|
||||||
|
values of all global-scope parameters (listed in
|
||||||
|
\url{https://xgboost.readthedocs.io/en/stable/parameter.html}).
|
||||||
|
}
|
||||||
|
\examples{
|
||||||
|
# Set verbosity level to silent (0)
|
||||||
|
xgb.set.config(verbosity = 0)
|
||||||
|
# Now global verbosity level is 0
|
||||||
|
config <- xgb.get.config()
|
||||||
|
print(config$verbosity)
|
||||||
|
# Set verbosity level to warning (1)
|
||||||
|
xgb.set.config(verbosity = 1)
|
||||||
|
# Now global verbosity level is 1
|
||||||
|
config <- xgb.get.config()
|
||||||
|
print(config$verbosity)
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ CXX_STD = CXX14
|
|||||||
XGB_RFLAGS = -DXGBOOST_STRICT_R_MODE=1 -DDMLC_LOG_BEFORE_THROW=0\
|
XGB_RFLAGS = -DXGBOOST_STRICT_R_MODE=1 -DDMLC_LOG_BEFORE_THROW=0\
|
||||||
-DDMLC_ENABLE_STD_THREAD=$(ENABLE_STD_THREAD) -DDMLC_DISABLE_STDIN=1\
|
-DDMLC_ENABLE_STD_THREAD=$(ENABLE_STD_THREAD) -DDMLC_DISABLE_STDIN=1\
|
||||||
-DDMLC_LOG_CUSTOMIZE=1 -DXGBOOST_CUSTOMIZE_LOGGER=1\
|
-DDMLC_LOG_CUSTOMIZE=1 -DXGBOOST_CUSTOMIZE_LOGGER=1\
|
||||||
-DRABIT_CUSTOMIZE_MSG_ -DRABIT_STRICT_CXX98_
|
-DRABIT_CUSTOMIZE_MSG_
|
||||||
|
|
||||||
# disable the use of thread_local for 32 bit windows:
|
# disable the use of thread_local for 32 bit windows:
|
||||||
ifeq ($(R_OSTYPE)$(WIN),windows)
|
ifeq ($(R_OSTYPE)$(WIN),windows)
|
||||||
@@ -17,8 +17,80 @@ endif
|
|||||||
$(foreach v, $(XGB_RFLAGS), $(warning $(v)))
|
$(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_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
|
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\
|
OBJECTS= \
|
||||||
$(PKGROOT)/rabit/src/engine_empty.o $(PKGROOT)/rabit/src/c_api.o
|
./xgboost_R.o \
|
||||||
|
./xgboost_custom.o \
|
||||||
|
./xgboost_assert.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,26 +1,14 @@
|
|||||||
# package root
|
# package root
|
||||||
PKGROOT=./
|
PKGROOT=../../
|
||||||
ENABLE_STD_THREAD=0
|
ENABLE_STD_THREAD=0
|
||||||
# _*_ mode: Makefile; _*_
|
# _*_ 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
|
CXX_STD = CXX14
|
||||||
|
|
||||||
XGB_RFLAGS = -DXGBOOST_STRICT_R_MODE=1 -DDMLC_LOG_BEFORE_THROW=0\
|
XGB_RFLAGS = -DXGBOOST_STRICT_R_MODE=1 -DDMLC_LOG_BEFORE_THROW=0\
|
||||||
-DDMLC_ENABLE_STD_THREAD=$(ENABLE_STD_THREAD) -DDMLC_DISABLE_STDIN=1\
|
-DDMLC_ENABLE_STD_THREAD=$(ENABLE_STD_THREAD) -DDMLC_DISABLE_STDIN=1\
|
||||||
-DDMLC_LOG_CUSTOMIZE=1 -DXGBOOST_CUSTOMIZE_LOGGER=1\
|
-DDMLC_LOG_CUSTOMIZE=1 -DXGBOOST_CUSTOMIZE_LOGGER=1\
|
||||||
-DRABIT_CUSTOMIZE_MSG_ -DRABIT_STRICT_CXX98_
|
-DRABIT_CUSTOMIZE_MSG_
|
||||||
|
|
||||||
# disable the use of thread_local for 32 bit windows:
|
# disable the use of thread_local for 32 bit windows:
|
||||||
ifeq ($(R_OSTYPE)$(WIN),windows)
|
ifeq ($(R_OSTYPE)$(WIN),windows)
|
||||||
@@ -29,10 +17,80 @@ endif
|
|||||||
$(foreach v, $(XGB_RFLAGS), $(warning $(v)))
|
$(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_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_CXXFLAGS= $(SHLIB_OPENMP_CXXFLAGS) -DDMLC_CMAKE_LITTLE_ENDIAN=1 $(SHLIB_PTHREAD_FLAGS) $(CXX_VISIBILITY)
|
||||||
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(SHLIB_PTHREAD_FLAGS)
|
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) -DDMLC_CMAKE_LITTLE_ENDIAN=1 $(SHLIB_PTHREAD_FLAGS) -lwsock32 -lws2_32
|
||||||
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_empty.o $(PKGROOT)/rabit/src/c_api.o
|
|
||||||
|
|
||||||
$(OBJECTS) : xgblib
|
OBJECTS= \
|
||||||
|
./xgboost_R.o \
|
||||||
|
./xgboost_custom.o \
|
||||||
|
./xgboost_assert.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 <Rinternals.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <R_ext/Rdynload.h>
|
#include <R_ext/Rdynload.h>
|
||||||
|
#include <R_ext/Visibility.h>
|
||||||
|
|
||||||
/* FIXME:
|
/* FIXME:
|
||||||
Check these declarations against the C/Fortran source code.
|
Check these declarations against the C/Fortran source code.
|
||||||
@@ -17,69 +18,85 @@ Check these declarations against the C/Fortran source code.
|
|||||||
/* .Call calls */
|
/* .Call calls */
|
||||||
extern SEXP XGBoosterBoostOneIter_R(SEXP, SEXP, SEXP, SEXP);
|
extern SEXP XGBoosterBoostOneIter_R(SEXP, SEXP, SEXP, SEXP);
|
||||||
extern SEXP XGBoosterCreate_R(SEXP);
|
extern SEXP XGBoosterCreate_R(SEXP);
|
||||||
|
extern SEXP XGBoosterCreateInEmptyObj_R(SEXP, SEXP);
|
||||||
extern SEXP XGBoosterDumpModel_R(SEXP, SEXP, SEXP, SEXP);
|
extern SEXP XGBoosterDumpModel_R(SEXP, SEXP, SEXP, SEXP);
|
||||||
extern SEXP XGBoosterEvalOneIter_R(SEXP, SEXP, SEXP, SEXP);
|
extern SEXP XGBoosterEvalOneIter_R(SEXP, SEXP, SEXP, SEXP);
|
||||||
extern SEXP XGBoosterGetAttrNames_R(SEXP);
|
extern SEXP XGBoosterGetAttrNames_R(SEXP);
|
||||||
extern SEXP XGBoosterGetAttr_R(SEXP, SEXP);
|
extern SEXP XGBoosterGetAttr_R(SEXP, SEXP);
|
||||||
extern SEXP XGBoosterLoadModelFromRaw_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 XGBoosterLoadModel_R(SEXP, SEXP);
|
||||||
extern SEXP XGBoosterSaveJsonConfig_R(SEXP handle);
|
extern SEXP XGBoosterSaveJsonConfig_R(SEXP handle);
|
||||||
extern SEXP XGBoosterLoadJsonConfig_R(SEXP handle, SEXP value);
|
extern SEXP XGBoosterLoadJsonConfig_R(SEXP handle, SEXP value);
|
||||||
extern SEXP XGBoosterSerializeToBuffer_R(SEXP handle);
|
extern SEXP XGBoosterSerializeToBuffer_R(SEXP handle);
|
||||||
extern SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw);
|
extern SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw);
|
||||||
extern SEXP XGBoosterModelToRaw_R(SEXP);
|
|
||||||
extern SEXP XGBoosterPredict_R(SEXP, SEXP, SEXP, SEXP, 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 XGBoosterSaveModel_R(SEXP, SEXP);
|
||||||
extern SEXP XGBoosterSetAttr_R(SEXP, SEXP, SEXP);
|
extern SEXP XGBoosterSetAttr_R(SEXP, SEXP, SEXP);
|
||||||
extern SEXP XGBoosterSetParam_R(SEXP, SEXP, SEXP);
|
extern SEXP XGBoosterSetParam_R(SEXP, SEXP, SEXP);
|
||||||
extern SEXP XGBoosterUpdateOneIter_R(SEXP, SEXP, SEXP);
|
extern SEXP XGBoosterUpdateOneIter_R(SEXP, SEXP, SEXP);
|
||||||
extern SEXP XGCheckNullPtr_R(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 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 XGDMatrixGetInfo_R(SEXP, SEXP);
|
||||||
|
extern SEXP XGDMatrixGetStrFeatureInfo_R(SEXP, SEXP);
|
||||||
extern SEXP XGDMatrixNumCol_R(SEXP);
|
extern SEXP XGDMatrixNumCol_R(SEXP);
|
||||||
extern SEXP XGDMatrixNumRow_R(SEXP);
|
extern SEXP XGDMatrixNumRow_R(SEXP);
|
||||||
extern SEXP XGDMatrixSaveBinary_R(SEXP, SEXP, SEXP);
|
extern SEXP XGDMatrixSaveBinary_R(SEXP, SEXP, SEXP);
|
||||||
extern SEXP XGDMatrixSetInfo_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 XGDMatrixSliceDMatrix_R(SEXP, SEXP);
|
||||||
|
extern SEXP XGBSetGlobalConfig_R(SEXP);
|
||||||
|
extern SEXP XGBGetGlobalConfig_R(void);
|
||||||
|
extern SEXP XGBoosterFeatureScore_R(SEXP, SEXP);
|
||||||
|
|
||||||
static const R_CallMethodDef CallEntries[] = {
|
static const R_CallMethodDef CallEntries[] = {
|
||||||
{"XGBoosterBoostOneIter_R", (DL_FUNC) &XGBoosterBoostOneIter_R, 4},
|
{"XGBoosterBoostOneIter_R", (DL_FUNC) &XGBoosterBoostOneIter_R, 4},
|
||||||
{"XGBoosterCreate_R", (DL_FUNC) &XGBoosterCreate_R, 1},
|
{"XGBoosterCreate_R", (DL_FUNC) &XGBoosterCreate_R, 1},
|
||||||
|
{"XGBoosterCreateInEmptyObj_R", (DL_FUNC) &XGBoosterCreateInEmptyObj_R, 2},
|
||||||
{"XGBoosterDumpModel_R", (DL_FUNC) &XGBoosterDumpModel_R, 4},
|
{"XGBoosterDumpModel_R", (DL_FUNC) &XGBoosterDumpModel_R, 4},
|
||||||
{"XGBoosterEvalOneIter_R", (DL_FUNC) &XGBoosterEvalOneIter_R, 4},
|
{"XGBoosterEvalOneIter_R", (DL_FUNC) &XGBoosterEvalOneIter_R, 4},
|
||||||
{"XGBoosterGetAttrNames_R", (DL_FUNC) &XGBoosterGetAttrNames_R, 1},
|
{"XGBoosterGetAttrNames_R", (DL_FUNC) &XGBoosterGetAttrNames_R, 1},
|
||||||
{"XGBoosterGetAttr_R", (DL_FUNC) &XGBoosterGetAttr_R, 2},
|
{"XGBoosterGetAttr_R", (DL_FUNC) &XGBoosterGetAttr_R, 2},
|
||||||
{"XGBoosterLoadModelFromRaw_R", (DL_FUNC) &XGBoosterLoadModelFromRaw_R, 2},
|
{"XGBoosterLoadModelFromRaw_R", (DL_FUNC) &XGBoosterLoadModelFromRaw_R, 2},
|
||||||
|
{"XGBoosterSaveModelToRaw_R", (DL_FUNC) &XGBoosterSaveModelToRaw_R, 2},
|
||||||
{"XGBoosterLoadModel_R", (DL_FUNC) &XGBoosterLoadModel_R, 2},
|
{"XGBoosterLoadModel_R", (DL_FUNC) &XGBoosterLoadModel_R, 2},
|
||||||
{"XGBoosterSaveJsonConfig_R", (DL_FUNC) &XGBoosterSaveJsonConfig_R, 1},
|
{"XGBoosterSaveJsonConfig_R", (DL_FUNC) &XGBoosterSaveJsonConfig_R, 1},
|
||||||
{"XGBoosterLoadJsonConfig_R", (DL_FUNC) &XGBoosterLoadJsonConfig_R, 2},
|
{"XGBoosterLoadJsonConfig_R", (DL_FUNC) &XGBoosterLoadJsonConfig_R, 2},
|
||||||
{"XGBoosterSerializeToBuffer_R", (DL_FUNC) &XGBoosterSerializeToBuffer_R, 1},
|
{"XGBoosterSerializeToBuffer_R", (DL_FUNC) &XGBoosterSerializeToBuffer_R, 1},
|
||||||
{"XGBoosterUnserializeFromBuffer_R", (DL_FUNC) &XGBoosterUnserializeFromBuffer_R, 2},
|
{"XGBoosterUnserializeFromBuffer_R", (DL_FUNC) &XGBoosterUnserializeFromBuffer_R, 2},
|
||||||
{"XGBoosterModelToRaw_R", (DL_FUNC) &XGBoosterModelToRaw_R, 1},
|
|
||||||
{"XGBoosterPredict_R", (DL_FUNC) &XGBoosterPredict_R, 5},
|
{"XGBoosterPredict_R", (DL_FUNC) &XGBoosterPredict_R, 5},
|
||||||
|
{"XGBoosterPredictFromDMatrix_R", (DL_FUNC) &XGBoosterPredictFromDMatrix_R, 3},
|
||||||
{"XGBoosterSaveModel_R", (DL_FUNC) &XGBoosterSaveModel_R, 2},
|
{"XGBoosterSaveModel_R", (DL_FUNC) &XGBoosterSaveModel_R, 2},
|
||||||
{"XGBoosterSetAttr_R", (DL_FUNC) &XGBoosterSetAttr_R, 3},
|
{"XGBoosterSetAttr_R", (DL_FUNC) &XGBoosterSetAttr_R, 3},
|
||||||
{"XGBoosterSetParam_R", (DL_FUNC) &XGBoosterSetParam_R, 3},
|
{"XGBoosterSetParam_R", (DL_FUNC) &XGBoosterSetParam_R, 3},
|
||||||
{"XGBoosterUpdateOneIter_R", (DL_FUNC) &XGBoosterUpdateOneIter_R, 3},
|
{"XGBoosterUpdateOneIter_R", (DL_FUNC) &XGBoosterUpdateOneIter_R, 3},
|
||||||
{"XGCheckNullPtr_R", (DL_FUNC) &XGCheckNullPtr_R, 1},
|
{"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},
|
{"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},
|
{"XGDMatrixGetInfo_R", (DL_FUNC) &XGDMatrixGetInfo_R, 2},
|
||||||
|
{"XGDMatrixGetStrFeatureInfo_R", (DL_FUNC) &XGDMatrixGetStrFeatureInfo_R, 2},
|
||||||
{"XGDMatrixNumCol_R", (DL_FUNC) &XGDMatrixNumCol_R, 1},
|
{"XGDMatrixNumCol_R", (DL_FUNC) &XGDMatrixNumCol_R, 1},
|
||||||
{"XGDMatrixNumRow_R", (DL_FUNC) &XGDMatrixNumRow_R, 1},
|
{"XGDMatrixNumRow_R", (DL_FUNC) &XGDMatrixNumRow_R, 1},
|
||||||
{"XGDMatrixSaveBinary_R", (DL_FUNC) &XGDMatrixSaveBinary_R, 3},
|
{"XGDMatrixSaveBinary_R", (DL_FUNC) &XGDMatrixSaveBinary_R, 3},
|
||||||
{"XGDMatrixSetInfo_R", (DL_FUNC) &XGDMatrixSetInfo_R, 3},
|
{"XGDMatrixSetInfo_R", (DL_FUNC) &XGDMatrixSetInfo_R, 3},
|
||||||
|
{"XGDMatrixSetStrFeatureInfo_R", (DL_FUNC) &XGDMatrixSetStrFeatureInfo_R, 3},
|
||||||
{"XGDMatrixSliceDMatrix_R", (DL_FUNC) &XGDMatrixSliceDMatrix_R, 2},
|
{"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}
|
{NULL, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
#endif // defined(_WIN32)
|
#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_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
|
||||||
R_useDynamicSymbols(dll, FALSE);
|
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,13 +1,23 @@
|
|||||||
// Copyright (c) 2014 by Contributors
|
/**
|
||||||
#include <dmlc/logging.h>
|
* Copyright 2014-2022 by XGBoost Contributors
|
||||||
|
*/
|
||||||
|
#include <dmlc/common.h>
|
||||||
#include <dmlc/omp.h>
|
#include <dmlc/omp.h>
|
||||||
#include <xgboost/c_api.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 <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <cstring>
|
#include <vector>
|
||||||
#include <cstdio>
|
|
||||||
#include <sstream>
|
#include "../../src/c_api/c_api_error.h"
|
||||||
|
#include "../../src/common/threading_utils.h"
|
||||||
|
|
||||||
#include "./xgboost_R.h"
|
#include "./xgboost_R.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -34,14 +44,27 @@
|
|||||||
error(XGBGetLastError()); \
|
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);
|
return ScalarLogical(R_ExternalPtrAddr(handle) == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _DMatrixFinalizer(SEXP ext) {
|
XGB_DLL void _DMatrixFinalizer(SEXP ext) {
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
if (R_ExternalPtrAddr(ext) == NULL) return;
|
if (R_ExternalPtrAddr(ext) == NULL) return;
|
||||||
CHECK_CALL(XGDMatrixFree(R_ExternalPtrAddr(ext)));
|
CHECK_CALL(XGDMatrixFree(R_ExternalPtrAddr(ext)));
|
||||||
@@ -49,7 +72,22 @@ void _DMatrixFinalizer(SEXP ext) {
|
|||||||
R_API_END();
|
R_API_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) {
|
XGB_DLL SEXP XGBSetGlobalConfig_R(SEXP json_str) {
|
||||||
|
R_API_BEGIN();
|
||||||
|
CHECK_CALL(XGBSetGlobalConfig(CHAR(asChar(json_str))));
|
||||||
|
R_API_END();
|
||||||
|
return R_NilValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
XGB_DLL SEXP XGBGetGlobalConfig_R() {
|
||||||
|
const char* json_str;
|
||||||
|
R_API_BEGIN();
|
||||||
|
CHECK_CALL(XGBGetGlobalConfig(&json_str));
|
||||||
|
R_API_END();
|
||||||
|
return mkString(json_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
XGB_DLL SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) {
|
||||||
SEXP ret;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
DMatrixHandle handle;
|
DMatrixHandle handle;
|
||||||
@@ -61,8 +99,7 @@ SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
XGB_DLL SEXP XGDMatrixCreateFromMat_R(SEXP mat, SEXP missing, SEXP n_threads) {
|
||||||
SEXP missing) {
|
|
||||||
SEXP ret;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
SEXP dim = getAttrib(mat, R_DimSymbol);
|
SEXP dim = getAttrib(mat, R_DimSymbol);
|
||||||
@@ -77,14 +114,16 @@ SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
|||||||
din = REAL(mat);
|
din = REAL(mat);
|
||||||
}
|
}
|
||||||
std::vector<float> data(nrow * ncol);
|
std::vector<float> data(nrow * ncol);
|
||||||
#pragma omp parallel for schedule(static)
|
int32_t threads = xgboost::common::OmpGetNumThreads(asInteger(n_threads));
|
||||||
for (omp_ulong i = 0; i < nrow; ++i) {
|
|
||||||
|
xgboost::common::ParallelFor(nrow, threads, [&](xgboost::omp_ulong i) {
|
||||||
for (size_t j = 0; j < ncol; ++j) {
|
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];
|
data[i * ncol + j] = is_int ? static_cast<float>(iin[i + nrow * j]) : din[i + nrow * j];
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
DMatrixHandle handle;
|
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));
|
ret = PROTECT(R_MakeExternalPtr(handle, R_NilValue, R_NilValue));
|
||||||
R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE);
|
R_RegisterCFinalizerEx(ret, _DMatrixFinalizer, TRUE);
|
||||||
R_API_END();
|
R_API_END();
|
||||||
@@ -92,10 +131,8 @@ SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
XGB_DLL SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, SEXP indices, SEXP data,
|
||||||
SEXP indices,
|
SEXP num_row, SEXP n_threads) {
|
||||||
SEXP data,
|
|
||||||
SEXP num_row) {
|
|
||||||
SEXP ret;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
const int *p_indptr = INTEGER(indptr);
|
const int *p_indptr = INTEGER(indptr);
|
||||||
@@ -111,11 +148,11 @@ SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
|||||||
for (size_t i = 0; i < nindptr; ++i) {
|
for (size_t i = 0; i < nindptr; ++i) {
|
||||||
col_ptr_[i] = static_cast<size_t>(p_indptr[i]);
|
col_ptr_[i] = static_cast<size_t>(p_indptr[i]);
|
||||||
}
|
}
|
||||||
#pragma omp parallel for schedule(static)
|
int32_t threads = xgboost::common::OmpGetNumThreads(asInteger(n_threads));
|
||||||
for (int64_t i = 0; i < static_cast<int64_t>(ndata); ++i) {
|
xgboost::common::ParallelFor(ndata, threads, [&](xgboost::omp_ulong i) {
|
||||||
indices_[i] = static_cast<unsigned>(p_indices[i]);
|
indices_[i] = static_cast<unsigned>(p_indices[i]);
|
||||||
data_[i] = static_cast<float>(p_data[i]);
|
data_[i] = static_cast<float>(p_data[i]);
|
||||||
}
|
});
|
||||||
DMatrixHandle handle;
|
DMatrixHandle handle;
|
||||||
CHECK_CALL(XGDMatrixCreateFromCSCEx(BeginPtr(col_ptr_), BeginPtr(indices_),
|
CHECK_CALL(XGDMatrixCreateFromCSCEx(BeginPtr(col_ptr_), BeginPtr(indices_),
|
||||||
BeginPtr(data_), nindptr, ndata,
|
BeginPtr(data_), nindptr, ndata,
|
||||||
@@ -127,7 +164,40 @@ SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
|||||||
return ret;
|
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;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
int len = length(idxset);
|
int len = length(idxset);
|
||||||
@@ -147,7 +217,7 @@ SEXP XGDMatrixSliceDMatrix_R(SEXP handle, SEXP idxset) {
|
|||||||
return ret;
|
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();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGDMatrixSaveBinary(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGDMatrixSaveBinary(R_ExternalPtrAddr(handle),
|
||||||
CHAR(asChar(fname)),
|
CHAR(asChar(fname)),
|
||||||
@@ -156,42 +226,76 @@ SEXP XGDMatrixSaveBinary_R(SEXP handle, SEXP fname, SEXP silent) {
|
|||||||
return R_NilValue;
|
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();
|
R_API_BEGIN();
|
||||||
int len = length(array);
|
int len = length(array);
|
||||||
const char *name = CHAR(asChar(field));
|
const char *name = CHAR(asChar(field));
|
||||||
|
auto ctx = DMatrixCtx(R_ExternalPtrAddr(handle));
|
||||||
if (!strcmp("group", name)) {
|
if (!strcmp("group", name)) {
|
||||||
std::vector<unsigned> vec(len);
|
std::vector<unsigned> vec(len);
|
||||||
#pragma omp parallel for schedule(static)
|
xgboost::common::ParallelFor(len, ctx->Threads(), [&](xgboost::omp_ulong i) {
|
||||||
for (int i = 0; i < len; ++i) {
|
|
||||||
vec[i] = static_cast<unsigned>(INTEGER(array)[i]);
|
vec[i] = static_cast<unsigned>(INTEGER(array)[i]);
|
||||||
}
|
});
|
||||||
CHECK_CALL(XGDMatrixSetUIntInfo(R_ExternalPtrAddr(handle),
|
CHECK_CALL(
|
||||||
CHAR(asChar(field)),
|
XGDMatrixSetUIntInfo(R_ExternalPtrAddr(handle), CHAR(asChar(field)), BeginPtr(vec), len));
|
||||||
BeginPtr(vec), len));
|
|
||||||
} else {
|
} else {
|
||||||
std::vector<float> vec(len);
|
std::vector<float> vec(len);
|
||||||
#pragma omp parallel for schedule(static)
|
xgboost::common::ParallelFor(len, ctx->Threads(),
|
||||||
for (int i = 0; i < len; ++i) {
|
[&](xgboost::omp_ulong i) { vec[i] = REAL(array)[i]; });
|
||||||
vec[i] = REAL(array)[i];
|
CHECK_CALL(
|
||||||
}
|
XGDMatrixSetFloatInfo(R_ExternalPtrAddr(handle), CHAR(asChar(field)), BeginPtr(vec), len));
|
||||||
CHECK_CALL(XGDMatrixSetFloatInfo(R_ExternalPtrAddr(handle),
|
|
||||||
CHAR(asChar(field)),
|
|
||||||
BeginPtr(vec), len));
|
|
||||||
}
|
}
|
||||||
R_API_END();
|
R_API_END();
|
||||||
return R_NilValue;
|
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;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
bst_ulong olen;
|
bst_ulong olen;
|
||||||
const float *res;
|
const float *res;
|
||||||
CHECK_CALL(XGDMatrixGetFloatInfo(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGDMatrixGetFloatInfo(R_ExternalPtrAddr(handle), CHAR(asChar(field)), &olen, &res));
|
||||||
CHAR(asChar(field)),
|
|
||||||
&olen,
|
|
||||||
&res));
|
|
||||||
ret = PROTECT(allocVector(REALSXP, olen));
|
ret = PROTECT(allocVector(REALSXP, olen));
|
||||||
for (size_t i = 0; i < olen; ++i) {
|
for (size_t i = 0; i < olen; ++i) {
|
||||||
REAL(ret)[i] = res[i];
|
REAL(ret)[i] = res[i];
|
||||||
@@ -201,7 +305,7 @@ SEXP XGDMatrixGetInfo_R(SEXP handle, SEXP field) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGDMatrixNumRow_R(SEXP handle) {
|
XGB_DLL SEXP XGDMatrixNumRow_R(SEXP handle) {
|
||||||
bst_ulong nrow;
|
bst_ulong nrow;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGDMatrixNumRow(R_ExternalPtrAddr(handle), &nrow));
|
CHECK_CALL(XGDMatrixNumRow(R_ExternalPtrAddr(handle), &nrow));
|
||||||
@@ -209,7 +313,7 @@ SEXP XGDMatrixNumRow_R(SEXP handle) {
|
|||||||
return ScalarInteger(static_cast<int>(nrow));
|
return ScalarInteger(static_cast<int>(nrow));
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGDMatrixNumCol_R(SEXP handle) {
|
XGB_DLL SEXP XGDMatrixNumCol_R(SEXP handle) {
|
||||||
bst_ulong ncol;
|
bst_ulong ncol;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGDMatrixNumCol(R_ExternalPtrAddr(handle), &ncol));
|
CHECK_CALL(XGDMatrixNumCol(R_ExternalPtrAddr(handle), &ncol));
|
||||||
@@ -224,7 +328,7 @@ void _BoosterFinalizer(SEXP ext) {
|
|||||||
R_ClearExternalPtr(ext);
|
R_ClearExternalPtr(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterCreate_R(SEXP dmats) {
|
XGB_DLL SEXP XGBoosterCreate_R(SEXP dmats) {
|
||||||
SEXP ret;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
int len = length(dmats);
|
int len = length(dmats);
|
||||||
@@ -241,7 +345,22 @@ SEXP XGBoosterCreate_R(SEXP dmats) {
|
|||||||
return ret;
|
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();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGBoosterSetParam(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGBoosterSetParam(R_ExternalPtrAddr(handle),
|
||||||
CHAR(asChar(name)),
|
CHAR(asChar(name)),
|
||||||
@@ -250,7 +369,7 @@ SEXP XGBoosterSetParam_R(SEXP handle, SEXP name, SEXP val) {
|
|||||||
return R_NilValue;
|
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();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGBoosterUpdateOneIter(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGBoosterUpdateOneIter(R_ExternalPtrAddr(handle),
|
||||||
asInteger(iter),
|
asInteger(iter),
|
||||||
@@ -259,17 +378,17 @@ SEXP XGBoosterUpdateOneIter_R(SEXP handle, SEXP iter, SEXP dtrain) {
|
|||||||
return R_NilValue;
|
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();
|
R_API_BEGIN();
|
||||||
CHECK_EQ(length(grad), length(hess))
|
CHECK_EQ(length(grad), length(hess))
|
||||||
<< "gradient and hess must have same length";
|
<< "gradient and hess must have same length";
|
||||||
int len = length(grad);
|
int len = length(grad);
|
||||||
std::vector<float> tgrad(len), thess(len);
|
std::vector<float> tgrad(len), thess(len);
|
||||||
#pragma omp parallel for schedule(static)
|
auto ctx = BoosterCtx(R_ExternalPtrAddr(handle));
|
||||||
for (int j = 0; j < len; ++j) {
|
xgboost::common::ParallelFor(len, ctx->Threads(), [&](xgboost::omp_ulong j) {
|
||||||
tgrad[j] = REAL(grad)[j];
|
tgrad[j] = REAL(grad)[j];
|
||||||
thess[j] = REAL(hess)[j];
|
thess[j] = REAL(hess)[j];
|
||||||
}
|
});
|
||||||
CHECK_CALL(XGBoosterBoostOneIter(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGBoosterBoostOneIter(R_ExternalPtrAddr(handle),
|
||||||
R_ExternalPtrAddr(dtrain),
|
R_ExternalPtrAddr(dtrain),
|
||||||
BeginPtr(tgrad), BeginPtr(thess),
|
BeginPtr(tgrad), BeginPtr(thess),
|
||||||
@@ -278,7 +397,7 @@ SEXP XGBoosterBoostOneIter_R(SEXP handle, SEXP dtrain, SEXP grad, SEXP hess) {
|
|||||||
return R_NilValue;
|
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;
|
const char *ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
CHECK_EQ(length(dmats), length(evnames))
|
CHECK_EQ(length(dmats), length(evnames))
|
||||||
@@ -303,8 +422,8 @@ SEXP XGBoosterEvalOneIter_R(SEXP handle, SEXP iter, SEXP dmats, SEXP evnames) {
|
|||||||
return mkString(ret);
|
return mkString(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
XGB_DLL SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
||||||
SEXP ntree_limit, SEXP training) {
|
SEXP ntree_limit, SEXP training) {
|
||||||
SEXP ret;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
bst_ulong olen;
|
bst_ulong olen;
|
||||||
@@ -324,36 +443,59 @@ SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
|||||||
return ret;
|
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();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGBoosterLoadModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname))));
|
CHECK_CALL(XGBoosterLoadModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname))));
|
||||||
R_API_END();
|
R_API_END();
|
||||||
return R_NilValue;
|
return R_NilValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterSaveModel_R(SEXP handle, SEXP fname) {
|
XGB_DLL SEXP XGBoosterSaveModel_R(SEXP handle, SEXP fname) {
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGBoosterSaveModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname))));
|
CHECK_CALL(XGBoosterSaveModel(R_ExternalPtrAddr(handle), CHAR(asChar(fname))));
|
||||||
R_API_END();
|
R_API_END();
|
||||||
return R_NilValue;
|
return R_NilValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterModelToRaw_R(SEXP handle) {
|
XGB_DLL SEXP XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw) {
|
||||||
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) {
|
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGBoosterLoadModelFromBuffer(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGBoosterLoadModelFromBuffer(R_ExternalPtrAddr(handle),
|
||||||
RAW(raw),
|
RAW(raw),
|
||||||
@@ -362,7 +504,23 @@ SEXP XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw) {
|
|||||||
return R_NilValue;
|
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;
|
const char* ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
bst_ulong len {0};
|
bst_ulong len {0};
|
||||||
@@ -373,14 +531,14 @@ SEXP XGBoosterSaveJsonConfig_R(SEXP handle) {
|
|||||||
return mkString(ret);
|
return mkString(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterLoadJsonConfig_R(SEXP handle, SEXP value) {
|
XGB_DLL SEXP XGBoosterLoadJsonConfig_R(SEXP handle, SEXP value) {
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGBoosterLoadJsonConfig(R_ExternalPtrAddr(handle), CHAR(asChar(value))));
|
CHECK_CALL(XGBoosterLoadJsonConfig(R_ExternalPtrAddr(handle), CHAR(asChar(value))));
|
||||||
R_API_END();
|
R_API_END();
|
||||||
return R_NilValue;
|
return R_NilValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterSerializeToBuffer_R(SEXP handle) {
|
XGB_DLL SEXP XGBoosterSerializeToBuffer_R(SEXP handle) {
|
||||||
SEXP ret;
|
SEXP ret;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
bst_ulong out_len;
|
bst_ulong out_len;
|
||||||
@@ -395,7 +553,7 @@ SEXP XGBoosterSerializeToBuffer_R(SEXP handle) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw) {
|
XGB_DLL SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw) {
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
CHECK_CALL(XGBoosterUnserializeFromBuffer(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGBoosterUnserializeFromBuffer(R_ExternalPtrAddr(handle),
|
||||||
RAW(raw),
|
RAW(raw),
|
||||||
@@ -404,7 +562,7 @@ SEXP XGBoosterUnserializeFromBuffer_R(SEXP handle, SEXP raw) {
|
|||||||
return R_NilValue;
|
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;
|
SEXP out;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
bst_ulong olen;
|
bst_ulong olen;
|
||||||
@@ -441,7 +599,7 @@ SEXP XGBoosterDumpModel_R(SEXP handle, SEXP fmap, SEXP with_stats, SEXP dump_for
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterGetAttr_R(SEXP handle, SEXP name) {
|
XGB_DLL SEXP XGBoosterGetAttr_R(SEXP handle, SEXP name) {
|
||||||
SEXP out;
|
SEXP out;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
int success;
|
int success;
|
||||||
@@ -461,7 +619,7 @@ SEXP XGBoosterGetAttr_R(SEXP handle, SEXP name) {
|
|||||||
return out;
|
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();
|
R_API_BEGIN();
|
||||||
const char *v = isNull(val) ? nullptr : CHAR(asChar(val));
|
const char *v = isNull(val) ? nullptr : CHAR(asChar(val));
|
||||||
CHECK_CALL(XGBoosterSetAttr(R_ExternalPtrAddr(handle),
|
CHECK_CALL(XGBoosterSetAttr(R_ExternalPtrAddr(handle),
|
||||||
@@ -470,7 +628,7 @@ SEXP XGBoosterSetAttr_R(SEXP handle, SEXP name, SEXP val) {
|
|||||||
return R_NilValue;
|
return R_NilValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEXP XGBoosterGetAttrNames_R(SEXP handle) {
|
XGB_DLL SEXP XGBoosterGetAttrNames_R(SEXP handle) {
|
||||||
SEXP out;
|
SEXP out;
|
||||||
R_API_BEGIN();
|
R_API_BEGIN();
|
||||||
bst_ulong len;
|
bst_ulong len;
|
||||||
@@ -489,3 +647,50 @@ SEXP XGBoosterGetAttrNames_R(SEXP handle) {
|
|||||||
UNPROTECT(1);
|
UNPROTECT(1);
|
||||||
return out;
|
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
|
* \file xgboost_R.h
|
||||||
* \author Tianqi Chen
|
* \author Tianqi Chen
|
||||||
* \brief R wrapper of xgboost
|
* \brief R wrapper of xgboost
|
||||||
@@ -21,6 +21,19 @@
|
|||||||
*/
|
*/
|
||||||
XGB_DLL SEXP XGCheckNullPtr_R(SEXP handle);
|
XGB_DLL SEXP XGCheckNullPtr_R(SEXP handle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set global configuration
|
||||||
|
* \param json_str a JSON string representing the list of key-value pairs
|
||||||
|
* \return R_NilValue
|
||||||
|
*/
|
||||||
|
XGB_DLL SEXP XGBSetGlobalConfig_R(SEXP json_str);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get global configuration
|
||||||
|
* \return JSON string
|
||||||
|
*/
|
||||||
|
XGB_DLL SEXP XGBGetGlobalConfig_R();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief load a data matrix
|
* \brief load a data matrix
|
||||||
* \param fname name of the content
|
* \param fname name of the content
|
||||||
@@ -34,22 +47,35 @@ XGB_DLL SEXP XGDMatrixCreateFromFile_R(SEXP fname, SEXP silent);
|
|||||||
* This assumes the matrix is stored in column major format
|
* This assumes the matrix is stored in column major format
|
||||||
* \param data R Matrix object
|
* \param data R Matrix object
|
||||||
* \param missing which value to represent missing value
|
* \param missing which value to represent missing value
|
||||||
|
* \param n_threads Number of threads used to construct DMatrix from dense matrix.
|
||||||
* \return created dmatrix
|
* \return created dmatrix
|
||||||
*/
|
*/
|
||||||
XGB_DLL SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
XGB_DLL SEXP XGDMatrixCreateFromMat_R(SEXP mat,
|
||||||
SEXP missing);
|
SEXP missing,
|
||||||
|
SEXP n_threads);
|
||||||
/*!
|
/*!
|
||||||
* \brief create a matrix content from CSC format
|
* \brief create a matrix content from CSC format
|
||||||
* \param indptr pointer to column headers
|
* \param indptr pointer to column headers
|
||||||
* \param indices row indices
|
* \param indices row indices
|
||||||
* \param data content of the data
|
* \param data content of the data
|
||||||
* \param num_row numer of rows (when it's set to 0, then guess from 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
|
* \return created dmatrix
|
||||||
*/
|
*/
|
||||||
XGB_DLL SEXP XGDMatrixCreateFromCSC_R(SEXP indptr,
|
XGB_DLL SEXP XGDMatrixCreateFromCSC_R(SEXP indptr, SEXP indices, SEXP data, SEXP num_row,
|
||||||
SEXP indices,
|
SEXP n_threads);
|
||||||
SEXP data,
|
|
||||||
SEXP num_row);
|
/*!
|
||||||
|
* \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
|
* \brief create a new dmatrix from sliced content of existing matrix
|
||||||
@@ -103,6 +129,14 @@ XGB_DLL SEXP XGDMatrixNumCol_R(SEXP handle);
|
|||||||
*/
|
*/
|
||||||
XGB_DLL SEXP XGBoosterCreate_R(SEXP dmats);
|
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
|
* \brief set parameters
|
||||||
* \param handle handle
|
* \param handle handle
|
||||||
@@ -143,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);
|
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 handle handle
|
||||||
* \param dmat data matrix
|
* \param dmat data matrix
|
||||||
* \param option_mask output_margin:1 predict_leaf:2
|
* \param option_mask output_margin:1 predict_leaf:2
|
||||||
@@ -152,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,
|
XGB_DLL SEXP XGBoosterPredict_R(SEXP handle, SEXP dmat, SEXP option_mask,
|
||||||
SEXP ntree_limit, SEXP training);
|
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
|
* \brief load model from existing file
|
||||||
* \param handle handle
|
* \param handle handle
|
||||||
@@ -176,11 +220,21 @@ XGB_DLL SEXP XGBoosterSaveModel_R(SEXP handle, SEXP fname);
|
|||||||
XGB_DLL SEXP XGBoosterLoadModelFromRaw_R(SEXP handle, SEXP raw);
|
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
|
* \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
|
* \brief Save internal parameters as a JSON string
|
||||||
@@ -244,4 +298,12 @@ XGB_DLL SEXP XGBoosterSetAttr_R(SEXP handle, SEXP name, SEXP val);
|
|||||||
*/
|
*/
|
||||||
XGB_DLL SEXP XGBoosterGetAttrNames_R(SEXP handle);
|
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(*)
|
#endif // XGBOOST_WRAPPER_R_H_ // NOLINT(*)
|
||||||
|
|||||||
@@ -13,27 +13,10 @@ void CustomLogMessage::Log(const std::string& msg) {
|
|||||||
}
|
}
|
||||||
} // namespace dmlc
|
} // namespace dmlc
|
||||||
|
|
||||||
// implements rabit error handling.
|
|
||||||
extern "C" {
|
|
||||||
void XGBoostAssert_R(int exp, const char *fmt, ...);
|
|
||||||
void XGBoostCheck_R(int exp, const char *fmt, ...);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace rabit {
|
|
||||||
namespace utils {
|
|
||||||
extern "C" {
|
|
||||||
void (*Printf)(const char *fmt, ...) = Rprintf;
|
|
||||||
void (*Assert)(int exp, const char *fmt, ...) = XGBoostAssert_R;
|
|
||||||
void (*Check)(int exp, const char *fmt, ...) = XGBoostCheck_R;
|
|
||||||
void (*Error)(const char *fmt, ...) = error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace xgboost {
|
namespace xgboost {
|
||||||
ConsoleLogger::~ConsoleLogger() {
|
ConsoleLogger::~ConsoleLogger() {
|
||||||
if (cur_verbosity_ == LogVerbosity::kIgnore ||
|
if (cur_verbosity_ == LogVerbosity::kIgnore ||
|
||||||
cur_verbosity_ <= global_verbosity_) {
|
cur_verbosity_ <= GlobalVerbosity()) {
|
||||||
dmlc::CustomLogMessage::Log(log_stream_.str());
|
dmlc::CustomLogMessage::Log(log_stream_.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
model_generator_metadata <- function() {
|
|
||||||
return (list(
|
|
||||||
kRounds = 2,
|
|
||||||
kRows = 1000,
|
|
||||||
kCols = 4,
|
|
||||||
kForests = 2,
|
|
||||||
kMaxDepth = 2,
|
|
||||||
kClasses = 3
|
|
||||||
))
|
|
||||||
}
|
|
||||||
@@ -2,10 +2,16 @@
|
|||||||
# of saved model files from XGBoost version 0.90 and 1.0.x.
|
# of saved model files from XGBoost version 0.90 and 1.0.x.
|
||||||
library(xgboost)
|
library(xgboost)
|
||||||
library(Matrix)
|
library(Matrix)
|
||||||
source('./generate_models_params.R')
|
|
||||||
|
|
||||||
set.seed(0)
|
set.seed(0)
|
||||||
metadata <- model_generator_metadata()
|
metadata <- list(
|
||||||
|
kRounds = 2,
|
||||||
|
kRows = 1000,
|
||||||
|
kCols = 4,
|
||||||
|
kForests = 2,
|
||||||
|
kMaxDepth = 2,
|
||||||
|
kClasses = 3
|
||||||
|
)
|
||||||
X <- Matrix(data = rnorm(metadata$kRows * metadata$kCols), nrow = metadata$kRows,
|
X <- Matrix(data = rnorm(metadata$kRows * metadata$kCols), nrow = metadata$kRows,
|
||||||
ncol = metadata$kCols, sparse = TRUE)
|
ncol = metadata$kCols, sparse = TRUE)
|
||||||
w <- runif(metadata$kRows)
|
w <- runif(metadata$kRows)
|
||||||
@@ -46,11 +52,16 @@ generate_logistic_model <- function () {
|
|||||||
y <- sample(0:1, size = metadata$kRows, replace = TRUE)
|
y <- sample(0:1, size = metadata$kRows, replace = TRUE)
|
||||||
stopifnot(max(y) == 1, min(y) == 0)
|
stopifnot(max(y) == 1, min(y) == 0)
|
||||||
|
|
||||||
data <- xgb.DMatrix(X, label = y, weight = w)
|
objective <- c('binary:logistic', 'binary:logitraw')
|
||||||
params <- list(tree_method = 'hist', num_parallel_tree = metadata$kForests,
|
name <- c('logit', 'logitraw')
|
||||||
max_depth = metadata$kMaxDepth, objective = 'binary:logistic')
|
|
||||||
booster <- xgb.train(params, data, nrounds = metadata$kRounds)
|
for (i in seq_len(length(objective))) {
|
||||||
save_booster(booster, 'logit')
|
data <- xgb.DMatrix(X, label = y, weight = w)
|
||||||
|
params <- list(tree_method = 'hist', num_parallel_tree = metadata$kForests,
|
||||||
|
max_depth = metadata$kMaxDepth, objective = objective[i])
|
||||||
|
booster <- xgb.train(params, data, nrounds = metadata$kRounds)
|
||||||
|
save_booster(booster, name[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_classification_model <- function () {
|
generate_classification_model <- function () {
|
||||||
@@ -6,21 +6,21 @@ my_linters <- list(
|
|||||||
assignment_linter = lintr::assignment_linter,
|
assignment_linter = lintr::assignment_linter,
|
||||||
closed_curly_linter = lintr::closed_curly_linter,
|
closed_curly_linter = lintr::closed_curly_linter,
|
||||||
commas_linter = lintr::commas_linter,
|
commas_linter = lintr::commas_linter,
|
||||||
# commented_code_linter = lintr::commented_code_linter,
|
equals_na = lintr::equals_na_linter,
|
||||||
infix_spaces_linter = lintr::infix_spaces_linter,
|
infix_spaces_linter = lintr::infix_spaces_linter,
|
||||||
line_length_linter = lintr::line_length_linter,
|
line_length_linter = lintr::line_length_linter,
|
||||||
no_tab_linter = lintr::no_tab_linter,
|
no_tab_linter = lintr::no_tab_linter,
|
||||||
object_usage_linter = lintr::object_usage_linter,
|
object_usage_linter = lintr::object_usage_linter,
|
||||||
# snake_case_linter = lintr::snake_case_linter,
|
|
||||||
# multiple_dots_linter = lintr::multiple_dots_linter,
|
|
||||||
object_length_linter = lintr::object_length_linter,
|
object_length_linter = lintr::object_length_linter,
|
||||||
open_curly_linter = lintr::open_curly_linter,
|
open_curly_linter = lintr::open_curly_linter,
|
||||||
# single_quotes_linter = lintr::single_quotes_linter,
|
semicolon = lintr::semicolon_terminator_linter(semicolon = c("compound", "trailing")),
|
||||||
|
seq = lintr::seq_linter,
|
||||||
spaces_inside_linter = lintr::spaces_inside_linter,
|
spaces_inside_linter = lintr::spaces_inside_linter,
|
||||||
spaces_left_parentheses_linter = lintr::spaces_left_parentheses_linter,
|
spaces_left_parentheses_linter = lintr::spaces_left_parentheses_linter,
|
||||||
trailing_blank_lines_linter = lintr::trailing_blank_lines_linter,
|
trailing_blank_lines_linter = lintr::trailing_blank_lines_linter,
|
||||||
trailing_whitespace_linter = lintr::trailing_whitespace_linter,
|
trailing_whitespace_linter = lintr::trailing_whitespace_linter,
|
||||||
true_false = lintr::T_and_F_symbol_linter
|
true_false = lintr::T_and_F_symbol_linter,
|
||||||
|
unneeded_concatenation = lintr::unneeded_concatenation_linter
|
||||||
)
|
)
|
||||||
|
|
||||||
results <- lapply(
|
results <- lapply(
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
require(xgboost)
|
require(xgboost)
|
||||||
|
library(Matrix)
|
||||||
|
|
||||||
context("basic functions")
|
context("basic functions")
|
||||||
|
|
||||||
@@ -17,7 +18,8 @@ test_that("train and predict binary classification", {
|
|||||||
nrounds <- 2
|
nrounds <- 2
|
||||||
expect_output(
|
expect_output(
|
||||||
bst <- xgboost(data = train$data, label = train$label, max_depth = 2,
|
bst <- xgboost(data = train$data, label = train$label, max_depth = 2,
|
||||||
eta = 1, nthread = 2, nrounds = nrounds, objective = "binary:logistic")
|
eta = 1, nthread = 2, nrounds = nrounds, objective = "binary:logistic",
|
||||||
|
eval_metric = "error")
|
||||||
, "train-error")
|
, "train-error")
|
||||||
expect_equal(class(bst), "xgb.Booster")
|
expect_equal(class(bst), "xgb.Booster")
|
||||||
expect_equal(bst$niter, nrounds)
|
expect_equal(bst$niter, nrounds)
|
||||||
@@ -33,6 +35,10 @@ test_that("train and predict binary classification", {
|
|||||||
err_pred1 <- sum((pred1 > 0.5) != train$label) / length(train$label)
|
err_pred1 <- sum((pred1 > 0.5) != train$label) / length(train$label)
|
||||||
err_log <- bst$evaluation_log[1, train_error]
|
err_log <- bst$evaluation_log[1, train_error]
|
||||||
expect_lt(abs(err_pred1 - err_log), 10e-6)
|
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", {
|
test_that("parameter validation works", {
|
||||||
@@ -65,7 +71,7 @@ test_that("parameter validation works", {
|
|||||||
xgb.train(params = params, data = dtrain, nrounds = nrounds))
|
xgb.train(params = params, data = dtrain, nrounds = nrounds))
|
||||||
print(output)
|
print(output)
|
||||||
}
|
}
|
||||||
expect_output(incorrect(), "bar, foo")
|
expect_output(incorrect(), '\\\\"bar\\\\", \\\\"foo\\\\"')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -122,7 +128,7 @@ test_that("train and predict softprob", {
|
|||||||
expect_output(
|
expect_output(
|
||||||
bst <- xgboost(data = as.matrix(iris[, -5]), label = lb,
|
bst <- xgboost(data = as.matrix(iris[, -5]), label = lb,
|
||||||
max_depth = 3, eta = 0.5, nthread = 2, nrounds = 5,
|
max_depth = 3, eta = 0.5, nthread = 2, nrounds = 5,
|
||||||
objective = "multi:softprob", num_class = 3)
|
objective = "multi:softprob", num_class = 3, eval_metric = "merror")
|
||||||
, "train-merror")
|
, "train-merror")
|
||||||
expect_false(is.null(bst$evaluation_log))
|
expect_false(is.null(bst$evaluation_log))
|
||||||
expect_lt(bst$evaluation_log[, min(train_merror)], 0.025)
|
expect_lt(bst$evaluation_log[, min(train_merror)], 0.025)
|
||||||
@@ -142,6 +148,24 @@ test_that("train and predict softprob", {
|
|||||||
pred_labels <- max.col(mpred) - 1
|
pred_labels <- max.col(mpred) - 1
|
||||||
err <- sum(pred_labels != lb) / length(lb)
|
err <- sum(pred_labels != lb) / length(lb)
|
||||||
expect_equal(bst$evaluation_log[1, train_merror], err, tolerance = 5e-6)
|
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", {
|
test_that("train and predict softmax", {
|
||||||
@@ -150,7 +174,7 @@ test_that("train and predict softmax", {
|
|||||||
expect_output(
|
expect_output(
|
||||||
bst <- xgboost(data = as.matrix(iris[, -5]), label = lb,
|
bst <- xgboost(data = as.matrix(iris[, -5]), label = lb,
|
||||||
max_depth = 3, eta = 0.5, nthread = 2, nrounds = 5,
|
max_depth = 3, eta = 0.5, nthread = 2, nrounds = 5,
|
||||||
objective = "multi:softmax", num_class = 3)
|
objective = "multi:softmax", num_class = 3, eval_metric = "merror")
|
||||||
, "train-merror")
|
, "train-merror")
|
||||||
expect_false(is.null(bst$evaluation_log))
|
expect_false(is.null(bst$evaluation_log))
|
||||||
expect_lt(bst$evaluation_log[, min(train_merror)], 0.025)
|
expect_lt(bst$evaluation_log[, min(train_merror)], 0.025)
|
||||||
@@ -167,7 +191,7 @@ test_that("train and predict RF", {
|
|||||||
lb <- train$label
|
lb <- train$label
|
||||||
# single iteration
|
# single iteration
|
||||||
bst <- xgboost(data = train$data, label = lb, max_depth = 5,
|
bst <- xgboost(data = train$data, label = lb, max_depth = 5,
|
||||||
nthread = 2, nrounds = 1, objective = "binary:logistic",
|
nthread = 2, nrounds = 1, objective = "binary:logistic", eval_metric = "error",
|
||||||
num_parallel_tree = 20, subsample = 0.6, colsample_bytree = 0.1)
|
num_parallel_tree = 20, subsample = 0.6, colsample_bytree = 0.1)
|
||||||
expect_equal(bst$niter, 1)
|
expect_equal(bst$niter, 1)
|
||||||
expect_equal(xgb.ntree(bst), 20)
|
expect_equal(xgb.ntree(bst), 20)
|
||||||
@@ -181,10 +205,8 @@ test_that("train and predict RF", {
|
|||||||
pred_err_20 <- sum((pred > 0.5) != lb) / length(lb)
|
pred_err_20 <- sum((pred > 0.5) != lb) / length(lb)
|
||||||
expect_equal(pred_err_20, pred_err)
|
expect_equal(pred_err_20, pred_err)
|
||||||
|
|
||||||
#pred <- predict(bst, train$data, ntreelimit = 1)
|
pred1 <- predict(bst, train$data, iterationrange = c(1, 2))
|
||||||
#pred_err_1 <- sum((pred > 0.5) != lb)/length(lb)
|
expect_equal(pred, pred1)
|
||||||
#expect_lt(pred_err, pred_err_1)
|
|
||||||
#expect_lt(pred_err, 0.08)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("train and predict RF with softprob", {
|
test_that("train and predict RF with softprob", {
|
||||||
@@ -193,7 +215,8 @@ test_that("train and predict RF with softprob", {
|
|||||||
set.seed(11)
|
set.seed(11)
|
||||||
bst <- xgboost(data = as.matrix(iris[, -5]), label = lb,
|
bst <- xgboost(data = as.matrix(iris[, -5]), label = lb,
|
||||||
max_depth = 3, eta = 0.9, nthread = 2, nrounds = nrounds,
|
max_depth = 3, eta = 0.9, nthread = 2, nrounds = nrounds,
|
||||||
objective = "multi:softprob", num_class = 3, verbose = 0,
|
objective = "multi:softprob", eval_metric = "merror",
|
||||||
|
num_class = 3, verbose = 0,
|
||||||
num_parallel_tree = 4, subsample = 0.5, colsample_bytree = 0.5)
|
num_parallel_tree = 4, subsample = 0.5, colsample_bytree = 0.5)
|
||||||
expect_equal(bst$niter, 15)
|
expect_equal(bst$niter, 15)
|
||||||
expect_equal(xgb.ntree(bst), 15 * 3 * 4)
|
expect_equal(xgb.ntree(bst), 15 * 3 * 4)
|
||||||
@@ -245,11 +268,12 @@ test_that("training continuation works", {
|
|||||||
expect_equal(bst$raw, bst2$raw)
|
expect_equal(bst$raw, bst2$raw)
|
||||||
expect_equal(dim(bst2$evaluation_log), c(2, 2))
|
expect_equal(dim(bst2$evaluation_log), c(2, 2))
|
||||||
# test continuing from a model in file
|
# test continuing from a model in file
|
||||||
xgb.save(bst1, "xgboost.model")
|
xgb.save(bst1, "xgboost.json")
|
||||||
bst2 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0, xgb_model = "xgboost.model")
|
bst2 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0, xgb_model = "xgboost.json")
|
||||||
if (!windows_flag && !solaris_flag)
|
if (!windows_flag && !solaris_flag)
|
||||||
expect_equal(bst$raw, bst2$raw)
|
expect_equal(bst$raw, bst2$raw)
|
||||||
expect_equal(dim(bst2$evaluation_log), c(2, 2))
|
expect_equal(dim(bst2$evaluation_log), c(2, 2))
|
||||||
|
file.remove("xgboost.json")
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("model serialization works", {
|
test_that("model serialization works", {
|
||||||
@@ -273,7 +297,7 @@ test_that("xgb.cv works", {
|
|||||||
expect_output(
|
expect_output(
|
||||||
cv <- xgb.cv(data = train$data, label = train$label, max_depth = 2, nfold = 5,
|
cv <- xgb.cv(data = train$data, label = train$label, max_depth = 2, nfold = 5,
|
||||||
eta = 1., nthread = 2, nrounds = 2, objective = "binary:logistic",
|
eta = 1., nthread = 2, nrounds = 2, objective = "binary:logistic",
|
||||||
verbose = TRUE)
|
eval_metric = "error", verbose = TRUE)
|
||||||
, "train-error:")
|
, "train-error:")
|
||||||
expect_is(cv, 'xgb.cv.synchronous')
|
expect_is(cv, 'xgb.cv.synchronous')
|
||||||
expect_false(is.null(cv$evaluation_log))
|
expect_false(is.null(cv$evaluation_log))
|
||||||
@@ -298,7 +322,7 @@ test_that("xgb.cv works with stratified folds", {
|
|||||||
eta = 1., nthread = 2, nrounds = 2, objective = "binary:logistic",
|
eta = 1., nthread = 2, nrounds = 2, objective = "binary:logistic",
|
||||||
verbose = TRUE, stratified = TRUE)
|
verbose = TRUE, stratified = TRUE)
|
||||||
# Stratified folds should result in a different evaluation logs
|
# Stratified folds should result in a different evaluation logs
|
||||||
expect_true(all(cv$evaluation_log[, test_error_mean] != cv2$evaluation_log[, test_error_mean]))
|
expect_true(all(cv$evaluation_log[, test_logloss_mean] != cv2$evaluation_log[, test_logloss_mean]))
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("train and predict with non-strict classes", {
|
test_that("train and predict with non-strict classes", {
|
||||||
@@ -328,7 +352,7 @@ test_that("train and predict with non-strict classes", {
|
|||||||
expect_error(pr <- predict(bst, train_dense), regexp = NA)
|
expect_error(pr <- predict(bst, train_dense), regexp = NA)
|
||||||
expect_equal(pr0, pr)
|
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')
|
class(bst) <- c('super.Booster', 'xgb.Booster')
|
||||||
expect_error(pr <- predict(bst, train_dense), regexp = NA)
|
expect_error(pr <- predict(bst, train_dense), regexp = NA)
|
||||||
expect_equal(pr0, pr)
|
expect_equal(pr0, pr)
|
||||||
@@ -343,7 +367,7 @@ test_that("max_delta_step works", {
|
|||||||
bst1 <- xgb.train(param, dtrain, nrounds, watchlist, verbose = 1)
|
bst1 <- xgb.train(param, dtrain, nrounds, watchlist, verbose = 1)
|
||||||
# model with restricted max_delta_step
|
# model with restricted max_delta_step
|
||||||
bst2 <- xgb.train(param, dtrain, nrounds, watchlist, verbose = 1, max_delta_step = 1)
|
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_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)
|
expect_lt(mean(bst1$evaluation_log$train_logloss) / mean(bst2$evaluation_log$train_logloss), 0.8)
|
||||||
})
|
})
|
||||||
@@ -382,3 +406,72 @@ test_that("Configuration works", {
|
|||||||
reloaded_config <- xgb.config(bst)
|
reloaded_config <- xgb.config(bst)
|
||||||
expect_equal(config, reloaded_config);
|
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)
|
||||||
|
})
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
require(xgboost)
|
require(xgboost)
|
||||||
require(data.table)
|
require(data.table)
|
||||||
|
require(titanic)
|
||||||
|
|
||||||
context("callbacks")
|
context("callbacks")
|
||||||
|
|
||||||
@@ -26,7 +27,8 @@ watchlist <- list(train = dtrain, test = dtest)
|
|||||||
|
|
||||||
err <- function(label, pr) sum((pr > 0.5) != label) / length(label)
|
err <- function(label, pr) sum((pr > 0.5) != label) / length(label)
|
||||||
|
|
||||||
param <- list(objective = "binary:logistic", max_depth = 2, nthread = 2)
|
param <- list(objective = "binary:logistic", eval_metric = "error",
|
||||||
|
max_depth = 2, nthread = 2)
|
||||||
|
|
||||||
|
|
||||||
test_that("cb.print.evaluation works as expected", {
|
test_that("cb.print.evaluation works as expected", {
|
||||||
@@ -105,7 +107,8 @@ test_that("cb.evaluation.log works as expected", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
param <- list(objective = "binary:logistic", max_depth = 4, nthread = 2)
|
param <- list(objective = "binary:logistic", eval_metric = "error",
|
||||||
|
max_depth = 4, nthread = 2)
|
||||||
|
|
||||||
test_that("can store evaluation_log without printing", {
|
test_that("can store evaluation_log without printing", {
|
||||||
expect_silent(
|
expect_silent(
|
||||||
@@ -173,16 +176,16 @@ test_that("cb.reset.parameters works as expected", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test_that("cb.save.model works as expected", {
|
test_that("cb.save.model works as expected", {
|
||||||
files <- c('xgboost_01.model', 'xgboost_02.model', 'xgboost.model')
|
files <- c('xgboost_01.json', 'xgboost_02.json', 'xgboost.json')
|
||||||
for (f in files) if (file.exists(f)) file.remove(f)
|
for (f in files) if (file.exists(f)) file.remove(f)
|
||||||
|
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, eta = 1, verbose = 0,
|
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, eta = 1, verbose = 0,
|
||||||
save_period = 1, save_name = "xgboost_%02d.model")
|
save_period = 1, save_name = "xgboost_%02d.json")
|
||||||
expect_true(file.exists('xgboost_01.model'))
|
expect_true(file.exists('xgboost_01.json'))
|
||||||
expect_true(file.exists('xgboost_02.model'))
|
expect_true(file.exists('xgboost_02.json'))
|
||||||
b1 <- xgb.load('xgboost_01.model')
|
b1 <- xgb.load('xgboost_01.json')
|
||||||
expect_equal(xgb.ntree(b1), 1)
|
expect_equal(xgb.ntree(b1), 1)
|
||||||
b2 <- xgb.load('xgboost_02.model')
|
b2 <- xgb.load('xgboost_02.json')
|
||||||
expect_equal(xgb.ntree(b2), 2)
|
expect_equal(xgb.ntree(b2), 2)
|
||||||
|
|
||||||
xgb.config(b2) <- xgb.config(bst)
|
xgb.config(b2) <- xgb.config(bst)
|
||||||
@@ -191,9 +194,9 @@ test_that("cb.save.model works as expected", {
|
|||||||
|
|
||||||
# save_period = 0 saves the last iteration's model
|
# save_period = 0 saves the last iteration's model
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, eta = 1, verbose = 0,
|
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, eta = 1, verbose = 0,
|
||||||
save_period = 0)
|
save_period = 0, save_name = 'xgboost.json')
|
||||||
expect_true(file.exists('xgboost.model'))
|
expect_true(file.exists('xgboost.json'))
|
||||||
b2 <- xgb.load('xgboost.model')
|
b2 <- xgb.load('xgboost.json')
|
||||||
xgb.config(b2) <- xgb.config(bst)
|
xgb.config(b2) <- xgb.config(bst)
|
||||||
expect_equal(bst$raw, b2$raw)
|
expect_equal(bst$raw, b2$raw)
|
||||||
|
|
||||||
@@ -236,7 +239,7 @@ test_that("early stopping xgb.train works", {
|
|||||||
test_that("early stopping using a specific metric works", {
|
test_that("early stopping using a specific metric works", {
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
expect_output(
|
expect_output(
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 20, watchlist, eta = 0.6,
|
bst <- xgb.train(param[-2], dtrain, nrounds = 20, watchlist, eta = 0.6,
|
||||||
eval_metric = "logloss", eval_metric = "auc",
|
eval_metric = "logloss", eval_metric = "auc",
|
||||||
callbacks = list(cb.early.stop(stopping_rounds = 3, maximize = FALSE,
|
callbacks = list(cb.early.stop(stopping_rounds = 3, maximize = FALSE,
|
||||||
metric_name = 'test_logloss')))
|
metric_name = 'test_logloss')))
|
||||||
@@ -252,6 +255,26 @@ test_that("early stopping using a specific metric works", {
|
|||||||
expect_equal(logloss_log, logloss_pred, tolerance = 1e-5)
|
expect_equal(logloss_log, logloss_pred, tolerance = 1e-5)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test_that("early stopping works with titanic", {
|
||||||
|
# This test was inspired by https://github.com/dmlc/xgboost/issues/5935
|
||||||
|
# It catches possible issues on noLD R
|
||||||
|
titanic <- titanic::titanic_train
|
||||||
|
titanic$Pclass <- as.factor(titanic$Pclass)
|
||||||
|
dtx <- model.matrix(~ 0 + ., data = titanic[, c("Pclass", "Sex")])
|
||||||
|
dty <- titanic$Survived
|
||||||
|
|
||||||
|
xgboost::xgboost(
|
||||||
|
data = dtx,
|
||||||
|
label = dty,
|
||||||
|
objective = "binary:logistic",
|
||||||
|
eval_metric = "auc",
|
||||||
|
nrounds = 100,
|
||||||
|
early_stopping_rounds = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
expect_true(TRUE) # should not crash
|
||||||
|
})
|
||||||
|
|
||||||
test_that("early stopping xgb.cv works", {
|
test_that("early stopping xgb.cv works", {
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
expect_output(
|
expect_output(
|
||||||
|
|||||||
21
R-package/tests/testthat/test_config.R
Normal file
21
R-package/tests/testthat/test_config.R
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
context('Test global configuration')
|
||||||
|
|
||||||
|
test_that('Global configuration works with verbosity', {
|
||||||
|
old_verbosity <- xgb.get.config()$verbosity
|
||||||
|
for (v in c(0, 1, 2, 3)) {
|
||||||
|
xgb.set.config(verbosity = v)
|
||||||
|
expect_equal(xgb.get.config()$verbosity, v)
|
||||||
|
}
|
||||||
|
xgb.set.config(verbosity = old_verbosity)
|
||||||
|
expect_equal(xgb.get.config()$verbosity, old_verbosity)
|
||||||
|
})
|
||||||
|
|
||||||
|
test_that('Global configuration works with use_rmm flag', {
|
||||||
|
old_use_rmm_flag <- xgb.get.config()$use_rmm
|
||||||
|
for (v in c(TRUE, FALSE)) {
|
||||||
|
xgb.set.config(use_rmm = v)
|
||||||
|
expect_equal(xgb.get.config()$use_rmm, v)
|
||||||
|
}
|
||||||
|
xgb.set.config(use_rmm = old_use_rmm_flag)
|
||||||
|
expect_equal(xgb.get.config()$use_rmm, old_use_rmm_flag)
|
||||||
|
})
|
||||||
@@ -47,7 +47,7 @@ test_that("custom objective with early stop works", {
|
|||||||
bst <- xgb.train(param, dtrain, 10, watchlist)
|
bst <- xgb.train(param, dtrain, 10, watchlist)
|
||||||
expect_equal(class(bst), "xgb.Booster")
|
expect_equal(class(bst), "xgb.Booster")
|
||||||
train_log <- bst$evaluation_log$train_error
|
train_log <- bst$evaluation_log$train_error
|
||||||
expect_true(all(diff(train_log)) <= 0)
|
expect_true(all(diff(train_log) <= 0))
|
||||||
})
|
})
|
||||||
|
|
||||||
test_that("custom objective using DMatrix attr works", {
|
test_that("custom objective using DMatrix attr works", {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ test_that("xgb.DMatrix: saving, loading", {
|
|||||||
# save to a local file
|
# save to a local file
|
||||||
dtest1 <- xgb.DMatrix(test_data, label = test_label)
|
dtest1 <- xgb.DMatrix(test_data, label = test_label)
|
||||||
tmp_file <- tempfile('xgb.DMatrix_')
|
tmp_file <- tempfile('xgb.DMatrix_')
|
||||||
|
on.exit(unlink(tmp_file))
|
||||||
expect_true(xgb.DMatrix.save(dtest1, tmp_file))
|
expect_true(xgb.DMatrix.save(dtest1, tmp_file))
|
||||||
# read from a local file
|
# read from a local file
|
||||||
expect_output(dtest3 <- xgb.DMatrix(tmp_file), "entries loaded from")
|
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)
|
dtest4 <- xgb.DMatrix(tmp_file, silent = TRUE)
|
||||||
expect_equal(dim(dtest4), c(3, 4))
|
expect_equal(dim(dtest4), c(3, 4))
|
||||||
expect_equal(getinfo(dtest4, 'label'), c(0, 1, 0))
|
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", {
|
test_that("xgb.DMatrix: getinfo & setinfo", {
|
||||||
@@ -64,8 +78,8 @@ test_that("xgb.DMatrix: getinfo & setinfo", {
|
|||||||
expect_true(setinfo(dtest, 'group', c(50, 50)))
|
expect_true(setinfo(dtest, 'group', c(50, 50)))
|
||||||
expect_error(setinfo(dtest, 'group', test_label))
|
expect_error(setinfo(dtest, 'group', test_label))
|
||||||
|
|
||||||
# providing character values will give a warning
|
# providing character values will give an error
|
||||||
expect_warning(setinfo(dtest, 'weight', rep('a', nrow(test_data))))
|
expect_error(setinfo(dtest, 'weight', rep('a', nrow(test_data))))
|
||||||
|
|
||||||
# any other label should error
|
# any other label should error
|
||||||
expect_error(setinfo(dtest, 'asdf', test_label))
|
expect_error(setinfo(dtest, 'asdf', test_label))
|
||||||
@@ -99,7 +113,7 @@ test_that("xgb.DMatrix: colnames", {
|
|||||||
dtest <- xgb.DMatrix(test_data, label = test_label)
|
dtest <- xgb.DMatrix(test_data, label = test_label)
|
||||||
expect_equal(colnames(dtest), colnames(test_data))
|
expect_equal(colnames(dtest), colnames(test_data))
|
||||||
expect_error(colnames(dtest) <- 'asdf')
|
expect_error(colnames(dtest) <- 'asdf')
|
||||||
new_names <- make.names(1:ncol(test_data))
|
new_names <- make.names(seq_len(ncol(test_data)))
|
||||||
expect_silent(colnames(dtest) <- new_names)
|
expect_silent(colnames(dtest) <- new_names)
|
||||||
expect_equal(colnames(dtest), new_names)
|
expect_equal(colnames(dtest), new_names)
|
||||||
expect_silent(colnames(dtest) <- NULL)
|
expect_silent(colnames(dtest) <- NULL)
|
||||||
|
|||||||
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -9,7 +9,8 @@ test_that("train and prediction when gctorture is on", {
|
|||||||
test <- agaricus.test
|
test <- agaricus.test
|
||||||
gctorture(TRUE)
|
gctorture(TRUE)
|
||||||
bst <- xgboost(data = train$data, label = train$label, max.depth = 2,
|
bst <- xgboost(data = train$data, label = train$label, max.depth = 2,
|
||||||
eta = 1, nthread = 2, nrounds = 2, objective = "binary:logistic")
|
eta = 1, nthread = 2, nrounds = 2, objective = "binary:logistic")
|
||||||
pred <- predict(bst, test$data)
|
pred <- predict(bst, test$data)
|
||||||
gctorture(FALSE)
|
gctorture(FALSE)
|
||||||
|
expect_length(pred, length(test$label))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ test_that("gblinear works", {
|
|||||||
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
||||||
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
||||||
|
|
||||||
param <- list(objective = "binary:logistic", booster = "gblinear",
|
param <- list(objective = "binary:logistic", eval_metric = "error", booster = "gblinear",
|
||||||
nthread = 2, eta = 0.8, alpha = 0.0001, lambda = 0.0001)
|
nthread = 2, eta = 0.8, alpha = 0.0001, lambda = 0.0001)
|
||||||
watchlist <- list(eval = dtest, train = dtrain)
|
watchlist <- list(eval = dtest, train = dtrain)
|
||||||
|
|
||||||
@@ -46,3 +46,31 @@ test_that("gblinear works", {
|
|||||||
expect_equal(dim(h), c(n, ncol(dtrain) + 1))
|
expect_equal(dim(h), c(n, ncol(dtrain) + 1))
|
||||||
expect_s4_class(h, "dgCMatrix")
|
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)
|
||||||
|
})
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user