์ถ๋ ฅ๊ณผ ๊ด๋ จํ์ฌ ํน์ ๊ธฐ๋ฅ์ ๋ํ ๋จ์กฐ ์ ์ฝ ์ง์์ ๋ํ ๋ช ๊ฐ์ง ์์ฒญ์ ๋ฐ์์ต๋๋ค.
์ฆ, ๋ค๋ฅธ ๊ธฐ๋ฅ์ด ๊ณ ์ ๋ ๊ฒฝ์ฐ ์์ธก์ด ํน์ ์ง์ ๋ ๊ธฐ๋ฅ์ ๋ํด ๋จ์กฐ ์ฆ๊ฐํ๋๋ก ํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ ๋ํ ์ผ๋ฐ์ ์ธ ๊ด์ฌ์ ๋ณด๊ธฐ ์ํด ์ด ํธ๋ฅผ ์ฝ๋๋ค. ์ด์ ๋ํ ๊ด์ฌ์ด ์ถฉ๋ถํ๋ฉด ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋ฒ ํ ๊ธฐ๋ฅ์ ํ ์คํธํ๊ณ ์ด ๊ธฐ๋ฅ ์ฌ์ฉ์ ๋ํ ๋ฌธ์ ๋ฐ ์์ต์๋ฅผ ์ ๊ณตํ๋ ค๋ฉด ์ปค๋ฎค๋ํฐ ์์ ๋ด์ฌ์์ ๋์์ด ํ์ํฉ๋๋ค. ๊ด์ฌ์ด ์๋ ๊ฒฝ์ฐ ๋ฌธ์ ์ ํ์ ํ์ญ์์ค.
์คํ ๋ฒ์ ์ https://github.com/dmlc/xgboost/pull/1516 ์์ ์ ๊ณต๋ฉ๋๋ค https://github.com/tqchen/xgboost ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ๋ณต์
๋ค์ ์ต์ ์ ์ผ์ญ์์ค(python, r API๋ฅผ ํตํด ๊ฐ๋ฅํจ).
monotone_constraints = "(0,1,1,0)"
๋ ๊ฐ์ง ์ฃผ์ฅ์ด ์์ต๋๋ค
monotone_constraints
๋ ๊ธฐ๋ฅ ์์ ๊ธธ์ด ๋ชฉ๋ก์ด๋ฉฐ, 1์ ๋จ์กฐ ์ฆ๊ฐ, -1์ ๊ฐ์, 0์ ์ ํ ์์์ ์๋ฏธํฉ๋๋ค. ๊ธฐ๋ฅ ์๋ณด๋ค ์งง์ผ๋ฉด 0์ด ์ฑ์์ง๋๋ค.ํ์ฌ๋ ๋ฉํฐ ์ฝ์ด์์ ์ ํํ ํ์ ์๊ณ ๋ฆฌ์ฆ๋ง ์ง์ํฉ๋๋ค. ์์ง ๋ฐฐํฌ ๋ฒ์ ์์ ์ฌ์ฉํ ์ ์์
@tqchen ์ ๋ ์ค๋ ์ง์ฅ์์ ๋ค๋ฅธ ๋ชจ๋ธ์ ์ฑ๋ฅ๊ณผ ๋น๊ตํ์ฌ ํ ์คํธํ๊ธฐ ์ํด ๋ชจ๋ ธํค ์ ์ฝ ์กฐ๊ฑด์ด ์๋ GBM์ ๊ตฌ์ถํด ๋ฌ๋ผ๋ ์์ฒญ์ ๋ฐ์์ต๋๋ค. ์ด๊ฒ์ tweedie ์ดํ๋ ์์ค๊ณผ ํจ๊ป์ด๋ฏ๋ก ์ค๋๋ ๊ณผ ๊ฐ์ด ์ฌ์ฉ์ ์ ์ ์์ค ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํ ๊ฒ์ ๋๋ค.
์ด์จ๋ ๋์์ ์ฃผ๊ณ ๋์์ ์ผ๋ถ ์์ ์ ์๋ฃํ ์ ์๋ ์ข์ ๊ธฐํ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌ๊ธฐ ์ด์ผ๊ธฐ๋ฅผ ๋ฐํ์ผ๋ก GBM(R ํจํค์ง)์ ๋จ์กฐ์ฑ์ ๋ก์ปฌ์์๋ง ์ํํฉ๋๋ค.
XGBoost๊ฐ ์ด๋ป๊ฒ ๋จ์กฐ๋ก์ด ์ ์ฝ์ ์ ์ฉํ๋์ง ๋ช
ํํ ํด์ฃผ์ค ์ ์์ต๋๊น?
XGBoost๊ฐ ์ ์ญ ์ ์ฝ ์กฐ๊ฑด์ ์ ์ฉํ ์ ์๋ค๋ฉด ์ข์ ๊ฒ์
๋๋ค.
๋ก์ปฌ ๋๋ ๊ธ๋ก๋ธ ์ ์ฝ์ด ๋ฌด์์ ์๋ฏธํ๋์ง ์ดํดํ์ง ๋ชปํฉ๋๋ค. ์์ธํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น?
์ฃ์กํฉ๋๋ค. ์๋ชป๋ ๋งํฌ๋ฅผ ๋ถ์ฌ๋ฃ์์ต๋๋ค. ์ฌ๊ธฐ์ ์ฌ๋ฐ๋ฅธ ๋งํฌ๊ฐ ์์ต๋๋ค (๋งํฌ).
๊ฐ ํธ๋ฆฌ๋ ๊ด์ฌ ์๋ ๊ธฐ๋ฅ์ ํน์ ํ์ ์งํฉ์์๋ง ๋จ์กฐ ์ ์ฝ์ ๋ฐ๋ฅผ ์ ์์ผ๋ฏ๋ก ๋ง์ ํธ๋ฆฌ ์์๋ธ์ด ํด๋น ๊ธฐ๋ฅ์ ์ ์ฒด ๋ฒ์์์ ์ ์ฒด ๋จ์กฐ์ฑ์ ์๋ฐํ ์ ์์ต๋๋ค.
๋ค, ์ ๊ฐ ์ดํดํ๊ธฐ๋ก๋ ์ ์ธ๊ณ์ ์ผ๋ก ์ํ๋๊ณ ์์ต๋๋ค. ๋น์ ์ ๊ทธ๊ฒ์ ์๋ํ๋ ๊ฒ์ ํ์ํฉ๋๋ค.
๋จ๋ณ๋ ํ๊ท์ ๋งฅ๋ฝ์์ ๋จ์กฐ์ฑ ์ ์ฝ ์กฐ๊ฑด์ ๋ํ ๋ช ๊ฐ์ง ๊ฐ๋จํ ํ ์คํธ๋ฅผ ์ํํ์ต๋๋ค. ์ฌ๊ธฐ์์ ์ฝ๋์ ๋งค์ฐ ๊ฐ๋จํ ๋ฌธ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
์ผ๋ถ ์ด๊ธฐ ๊ด์ฐฐ:
Constraint = -1 ๊ฒฝ์ฐ์ ๋ฒ๊ทธ๋ฅผ ๋์ ํ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค. ์์ ์ ํธ์ํ๋๋ฐ ์ต์ ๋ฒ์ ์ด ์ ์๋ํ๋์ง ํ์ธํ์ญ์์ค. ์ฌ๋ฌ ์ ์ฝ ์กฐ๊ฑด์ด ์๋ ๊ฒฝ์ฐ์๋ ์๋ํ๋์ง ํ์ธํ์ญ์์ค.
@tqchen ๊ฐ์ ๋ฒ๊ทธ์ ๋ํ ์์ ์ฌํญ์ ํ ์คํธํ๋๋ฐ ์ง๊ธ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ผ๋ถ ํ์ค ๋ฐ์ดํฐ ์ธํธ์์ ์๋ ๋ฒ์ ์ ๋นํด ์๋๊ฐ ๊ฐ์ํ๋์ง ํ์ธํ ๋ค์ ๋ณํฉํ ์ ์์ต๋๋ค.
@tqchen ๋ ๊ฐ์ ๋ณ์ ๋ชจ๋ธ์ ํ ์คํธํ์ต๋๋ค. ํ๋๋ ์ฆ๊ฐํ๋ ์ ์ฝ ์กฐ๊ฑด์ด ์๊ณ ๋ค๋ฅธ ํ๋๋ ๊ฐ์ํ๋ ์ ์ฝ ์กฐ๊ฑด์ด ์์ต๋๋ค.
params_constrained = params.copy()
params_constrained['updater'] = "grow_monotone_colmaker,prune"
params_constrained['monotone_constraints'] = "(1,-1)"
๊ฒฐ๊ณผ๋ ์ข๋ค
์ค๋ ์คํ์ ์ฝ๊ฐ์ ํ์ด๋ฐ ํ ์คํธ๋ฅผ ํ ์๊ฐ์ ์ฐพ๋๋ก ๋ ธ๋ ฅํ๊ฒ ์ต๋๋ค.
montone ์ต์
์ ์๋ ๊ฐ์ง๋ฅผ ํ์ฉํ๋๋ก #1516์ ์
๋ฐ์ดํธํ์ต๋๋ค. ์ด์ ์ฌ์ฉ์๋ monotone_constraints = "(0,1,1,0)"
๋ง ์ ๋ฌํ๋ฉด ๋ฉ๋๋ค. ์๋ํ๋์ง ํ์ธํ์ญ์์ค.
์๋ ํ ์คํธ๊ฐ ์ ์์ ์ผ๋ก ์งํ๋๋ฉด ์ด๊ฒ์ ๋ณํฉํ๊ณ ํํ ๋ฆฌ์ผ์ ์ถ๊ฐํ๋ ๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐ๋๋ก ํ๊ฒ ์ต๋๋ค.
@madrury @ XiaoxiaoWang87
์ฌ๊ธฐ์ ๋ค๋ณ์ ์ฌ๋ก์ ๋ํ ํ ์คํธ๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.
no constraint: 964.9 microseconds per iteration
with constraint: 861.7 microseconds per iteration
(์๋ ํ ์คํธ๋ฅผ ํ๋ ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค)
Check failed: (wleft) <= (wright)
๋ก ์ธํด ์ฝ๋ ์ถฉ๋์ด ๋ฐ์ํฉ๋๋ค.Jupyter ๋ ธํธ๋ถ์์ ๋ช ๊ฐ์ง ํ์ด๋ฐ ์คํ์ ์คํํ์ต๋๋ค.
์ฒซ ๋ฒ์งธ ํ ์คํธ: ๋ช ๊ฐ์ง ๊ฐ๋จํ ์๋ฎฌ๋ ์ด์ ๋ฐ์ดํฐ. ํ๋๋ ์ฆ๊ฐํ๊ณ ๋ค๋ฅธ ํ๋๋ ๊ฐ์ํ๋ ๋ ๊ฐ์ง ๊ธฐ๋ฅ์ด ์์ง๋ง ๊ฐ ๊ธฐ๋ฅ์ด ์ง์ ์ผ๋ก ๋จ์กฐ๋กญ์ง ์๋๋ก ์ค์ฒฉ๋ ์์ ์ฌ์ธํ๊ฐ ์์ต๋๋ค.
X = np.random.random(size=(N, K))
y = (5*X[:, 0] + np.sin(5*2*pi*X[:, 0])
- 5*X[:, 1] - np.cos(5*2*pi*X[:, 1])
+ np.random.normal(loc=0.0, scale=0.01, size=N))
๋ค์์ ๋ชจ๋ ธํค ์ ์ฝ ์กฐ๊ฑด์ด ์๊ฑฐ๋ ์๋ xgboost์ ํ์ด๋ฐ ๊ฒฐ๊ณผ์ ๋๋ค. ๋๋ ์กฐ๊ธฐ ์ค์ง๋ฅผ ๋๊ณ ๊ฐ๊ฐ์ ๋ํด ์ค์ ๋ ๋ฐ๋ณต ํ์๋ฅผ ๋๋ ธ์ต๋๋ค.
๋ชจ๋ ธํค ์ ์ฝ์ด ์๋ ์ฒซ ๋ฒ์งธ:
%%timeit -n 100
model_no_constraints = xgb.train(params, dtrain,
num_boost_round = 2500,
verbose_eval = False)
100 loops, best of 3: 246 ms per loop
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์ ๋จ์กฐ์ฑ ์ ์ฝ ์กฐ๊ฑด์ด ์์ต๋๋ค.
%%timeit -n 100
model_with_constraints = xgb.train(params_constrained, dtrain,
num_boost_round = 2500,
verbose_eval = False)
100 loops, best of 3: 196 ms per loop
๋ ๋ฒ์งธ ํ ์คํธ: sklearn์ ์บ๋ฆฌํฌ๋์ hHousing ๋ฐ์ดํฐ. ์ ์ฝ ์์ด
%%timeit -n 10
model_no_constraints = xgb.train(params, dtrain,
num_boost_round = 2500,
verbose_eval = False)
10 loops, best of 3: 5.9 s per loop
๋ค์์ ๋ด๊ฐ ์ฌ์ฉํ ์ ์ฝ ์กฐ๊ฑด์ ๋๋ค.
print(params_constrained['monotone_constraints'])
(1,1,1,0,0,1,0,0)
๊ทธ๋ฆฌ๊ณ ์ ์ฝ ๋ชจ๋ธ์ ํ์ด๋ฐ
%%timeit -n 10
model_no_constraints = xgb.train(params, dtrain,
num_boost_round = 2500,
verbose_eval = False)
10 loops, best of 3: 6.08 s per loop
@XiaoxiaoWang87 ๋๋ wleft์ wright์ ๋ํ ์ํ๋ฅผ ํ๊ธฐ ์ํด ๋ ๋ค๋ฅธ PR์ ํธ์ํ์ต๋๋ค. ์๋ํ๋์ง ํ์ธํ์ญ์์ค.
@madrury ์ ์ฝ ๊ธฐ๋ฅ์ด ์๋ ์ด์ ๋ฒ์ ์ XGBoost์๋ ๋น๊ตํ ์ ์์ต๋๊น?
@tqchen ๋ฌผ๋ก ์ ๋๋ค. ๋น๊ตํ ์ปค๋ฐ ํด์๋ฅผ ์ถ์ฒํ ์ ์์ต๋๊น? ๋ชจ๋ ธํค ์ ์ฝ ์กฐ๊ฑด์ ์ถ๊ฐํ๊ธฐ ์ ์ ์ปค๋ฐ์ ์ฌ์ฉํด์ผ ํฉ๋๊น?
์ ์ด์ ๊ฒ์ด ํ ๊ฒ์ ๋๋ค
@tqchen ์ ๋ฐ์ดํธ๋ ๋ฒ์ ์ ๋ค์ ๋น๋ํ ๋ ์ด์ ์ ์์๋ ๋ช ๊ฐ์ง ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋๋ ๊ทธ ์ด์ ๊ฐ ๋น์ ์๊ฒ ๋ช ํํ๊ฒ ๋๋ฌ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ด์ ๊ณผ ๋์ผํ ์ฝ๋๋ฅผ ์คํํ๋ ค๊ณ ํ๋ฉด ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ ์ฒด ์ญ์ถ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
XGBoostError Traceback (most recent call last)
<ipython-input-14-63a9f6e16c9a> in <module>()
8 model_with_constraints = xgb.train(params, dtrain,
9 num_boost_round = 1000, evals = evallist,
---> 10 early_stopping_rounds = 10)
/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/training.pyc in train(params, dtrain, num_boost_round, evals, obj, feval, maximize, early_stopping_rounds, evals_result, verbose_eval, learning_rates, xgb_model, callbacks)
201 evals=evals,
202 obj=obj, feval=feval,
--> 203 xgb_model=xgb_model, callbacks=callbacks)
204
205
/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/training.pyc in _train_internal(params, dtrain, num_boost_round, evals, obj, feval, xgb_model, callbacks)
72 # Skip the first update if it is a recovery step.
73 if version % 2 == 0:
---> 74 bst.update(dtrain, i, obj)
75 bst.save_rabit_checkpoint()
76 version += 1
/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/core.pyc in update(self, dtrain, iteration, fobj)
804
805 if fobj is None:
--> 806 _check_call(_LIB.XGBoosterUpdateOneIter(self.handle, iteration, dtrain.handle))
807 else:
808 pred = self.predict(dtrain)
/Users/matthewdrury/anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/core.pyc in _check_call(ret)
125 """
126 if ret != 0:
--> 127 raise XGBoostError(_LIB.XGBGetLastError())
128
129
XGBoostError: [14:08:41] src/tree/tree_updater.cc:18: Unknown tree updater grow_monotone_colmaker
๊ตฌํํ ํค์๋ ์ธ์์ ๋ํด ๋ชจ๋ ๊ฒ์ ๋ฐ๊พธ๋ฉด ์ค๋ฅ๋ ๋ฐ์ํฉ๋๋ค.
TypeError Traceback (most recent call last)
<ipython-input-15-ef7671f72925> in <module>()
8 monotone_constraints="(1)",
9 num_boost_round = 1000, evals = evallist,
---> 10 early_stopping_rounds = 10)
TypeError: train() got an unexpected keyword argument 'monotone_constraints'
์ ๋ฐ์ดํฐ ์ธ์๋ฅผ ์ ๊ฑฐํ๊ณ ๋ชจ๋ ธํค ์ ์ฝ ์กฐ๊ฑด ์ธ์๋ฅผ ๋งค๊ฐ๋ณ์์ ์ ์งํฉ๋๋ค. ์ด์ ๋ชจ๋ ธํค ์ ์ฝ ์กฐ๊ฑด์ด ํ์๋ ๋ ๋ชจ๋ ธํค ์ ์ฝ ์ ๋ฐ์ดํฐ๊ฐ ์๋์ผ๋ก ํ์ฑํ๋ฉ๋๋ค.
@tqchen ๋ด ์น๊ตฌ @amontz ๊ฐ ๋ด๊ฐ ๋ฉ์์ง๋ฅผ ๊ฒ์ํ ์งํ์ ๊ทธ๊ฒ์ ์์ monotone_constraints
๋ฅผ .train
kwarg๋ก ์ ๋ฌํ๋ ๊ฒ์ผ๋ก ํด์ํ์ต๋๋ค.
์ด๋ฌํ ์กฐ์ ๊ณผ ํจ๊ป ์๋ํฉ๋๋ค. ๊ฐ์ฌ ํด์.
@madrury ์๋๋ฅผ ํ์ธํ ์ ์์ต๋๊น?
๋ํ @madrury ์ @XiaoxiaoWang87 ์ ์ด ๊ธฐ๋ฅ์ด ์ด์ ๊ฑฐ์ ๋ณํฉ๋๊ธฐ ๋๋ฌธ์ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉ์์๊ฒ ์๊ฐํ๋ ์์ต์๋ฅผ ๋ง๋ค๋๋ก ์กฐ์ ํ ์ ์๋ค๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
์ฐ๋ฆฌ๋ ipy ๋ ธํธ๋ถ์ ๋ฉ์ธ ์ ์ฅ์๋ก ์ง์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ฏธ์ง๋ https://github.com/dmlc/web-data/tree/master/xgboost ๋ก ํธ์ํ๊ณ ๊ธฐ๋ณธ ๋ฆฌํฌ์งํ ๋ฆฌ๋ก ๋งํฌ๋ค์ดํ ์ ์์ต๋๋ค.
๋ํ int ํํ์ ๋ฐฑ์๋์์ ํ์ฉํ ์ ์๋ ๋ฌธ์์ด ํํ ํ์์ผ๋ก ๋ณํํ ์ ์๋๋ก ํ๋ฐํธ ์๋ ์ธํฐํ์ด์ค ๋ฌธ์์ด ๋ณํ์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
@hetong007 R์ ๋ณ๊ฒฝ ์ฌํญ ๋ฐ @slundberg ์ Julia
@tqchen Julia๋ ํ์ฌ 0.4 ๋ฒ์ ์ XGBoost์ ์ฐ๊ฒฐ๋์ด ์์ผ๋ฏ๋ก ๋ค์์ ์ฌ์ฉํด์ผ ํ๊ณ ์๊ฐ์ด ์์ ๋ ๋ค๋ฅธ ์ฌ๋์ด ์๋ ๊ฒฝ์ฐ ๋ฐ์ธ๋ฉ์ ์ ๋ฐ์ดํธํ๊ฒ ์ต๋๋ค. ์ด ์์ ์์ ์ด ๋ณ๊ฒฝ ์ฌํญ์ ์ถ๊ฐํ ์๋ ์์ต๋๋ค.
๋ค์์ ๊ตฌํ ์ด์ ๋ถํฐ ์ดํ๊น์ง ๋ชจ๋ ธํค ์ ์ฝ์ด _์๋_ ๋ชจ๋ธ ๊ฐ์ ๋น๊ต์ ๋๋ค.
Commit 8cac37 : ๋ชจ๋
ธํค ์ ์ฝ์ ๊ตฌํํ๊ธฐ ์ .'
์๋ฎฌ๋ ์ด์
๋ฐ์ดํฐ : 100 loops, best of 3: 232 ms per loop
์บ๋ฆฌํฌ๋์ ๋ฐ์ดํฐ : 10 loops, best of 3: 5.89 s per loop
Commit b1c224 : ๋ชจ๋
ธํค ์ ์ฝ์ ๊ตฌํํ ํ.
์๋ฎฌ๋ ์ด์
๋ฐ์ดํฐ : 100 loops, best of 3: 231 ms per loop
์บ๋ฆฌํฌ๋์ ๋ฐ์ดํฐ : 10 loops, best of 3: 5.61 s per loop
๊ตฌํ ํ ์บ๋ฆฌํฌ๋์์ ์๋ ํฅ์์ด ์์ฌ์ค๋ฌ์ ๋ณด์ด์ง๋ง ๊ฐ ๋ฐฉ๋ฒ์ผ๋ก ๋ ๋ฒ ์๋ํ์ผ๋ฉฐ ์ผ๊ด๋์์ต๋๋ค.
ํํ ๋ฆฌ์ผ์ ์์ฑํ๋ ๊ธฐํ๋ฅผ ๊ฐ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ๋๋ ๊ธฐ์กด ๋ฌธ์๋ฅผ ๋๋ฌ๋ณด๊ณ ์์ผ๋ก ๋ฉฐ์น ์์ ๋ฌด์ธ๊ฐ๋ฅผ ์ ๋ฆฌํ ๊ฒ์ ๋๋ค.
ํ๋ฅญํฉ๋๋ค. ์ด์ PR์ด ๊ณต์์ ์ผ๋ก ๋ง์คํฐ์ ๋ณํฉ๋์์ต๋๋ค. ํํ ๋ฆฌ์ผ์ ๋ณผ ์ ์๊ธฐ๋ฅผ ๊ธฐ๋ํฉ๋๋ค
@madrury๋ ๊ฐ์ฌํฉ๋๋ค. ๊ทธ๊ฒ์ ๊ธฐ๋ํ๋ค. ๋ด๊ฐ ๋ฌด์์ ๋์ธ ์ ์๋์ง ์๋ ค์ฃผ์ธ์. ๋๋ ํ์คํ ์ด ์ฃผ์ ์ ๋ํด ๋ ๋ง์ ์ฐ๊ตฌ๋ฅผ ํ ์ํฅ์ด ์์ต๋๋ค.
๋ด์ผ ๊ฐํํ๊ฒ ์ต๋๋ค. ๋ฐฐ์ด ๋์ ๋ฌธ์์ด์ ํตํด C++์ ํต์ ํ๋ ์ด์ ๊ฐ ๊ถ๊ธํฉ๋๋ค.
๋๋ R์์ ํ ์คํธํ๊ณ ์์ต๋๋ค. ๋๋ ๋ฌด์์๋ก ๋ ๊ฐ์ ๋ณ์ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๊ณ ์์ธก์ ์๋ํฉ๋๋ค.
๊ทธ๋ฌ๋ ๋๋ ๊ทธ๊ฒ์ ๋ฐ๊ฒฌํ๋ค.
monotone_constraints
๋งค๊ฐ๋ณ์๋ ์์ธก์ ์ฝ๊ฐ ๋ค๋ฅด๊ฒ ๋ง๋ญ๋๋ค.์ ๊ฐ ์ค์ํ ๋ถ๋ถ์ด ์์ผ๋ฉด ์ง์ ํด์ฃผ์ธ์.
๊ทธ๊ฒ์ ์ฌํํ๋ ์ฝ๋ ( drat
์๋ ์ต์ github ๋ฒ์ ์์ ํ
์คํธ):
set.seed(1024)
x1 = rnorm(1000, 10)
x2 = rnorm(1000, 10)
y = -1*x1 + rnorm(1000, 0.001) + 3*sin(x2)
train = cbind(x1, x2)
bst = xgboost(data = train, label = y, max_depth = 2,
eta = 0.1, nthread = 2, nrounds = 10,
monotone_constraints = '(1,-1)')
pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'with constraint')
pred.ord = pred[order(train[,1])]
lines(pred.ord)
bst = xgboost(data = train, label = y, max_depth = 2,
eta = 0.1, nthread = 2, nrounds = 10)
pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'without constraint')
pred.ord = pred[order(train[,1])]
lines(pred.ord)
์ ์ฝ์ ๋ถ๋ถ ์ฃผ๋ฌธ์ ๋ํด ์ํ๋์์ต๋๋ค. ๋ฐ๋ผ์ ์ ์ฝ ์กฐ๊ฑด์ montone ์ถ์ ์ด๋ํ๊ณ ๋ค๋ฅธ ์ถ์ ๊ณ ์ ๋ ์ํ๋ก ์ ์งํ๋ ๊ฒฝ์ฐ์๋ง ์ ์ฉ๋ฉ๋๋ค.
@hetong007 ๋ด ์๋ชจ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋๋
seq
๋ฅผ ์ฌ์ฉํฉ๋๋ค.colmeans
์ ๊ฐ์ต๋๋ค.์ฌ๊ธฐ์ ๋ด๊ฐ ์์ ํฌํจ๋ ํ๋กฏ์ ์ฌ์ฉํ ํ์ด์ฌ ์ฝ๋๊ฐ ์์ต๋๋ค. ๋๋ฑํ R ์ฝ๋๋ก ๊ฝค ์ฝ๊ฒ ๋ณํ๋์ด์ผ ํฉ๋๋ค.
def plot_one_feature_effect(model, X, y, idx=1):
x_scan = np.linspace(0, 1, 100)
X_scan = np.empty((100, X.shape[1]))
X_scan[:, idx] = x_scan
left_feature_means = np.tile(X[:, :idx].mean(axis=0), (100, 1))
right_feature_means = np.tile(X[:, (idx+1):].mean(axis=0), (100, 1))
X_scan[:, :idx] = left_feature_means
X_scan[:, (idx+1):] = right_feature_means
X_plot = xgb.DMatrix(X_scan)
y_plot = model.predict(X_plot, ntree_limit=bst.best_ntree_limit)
plt.plot(x_scan, y_plot, color = 'black')
plt.plot(X[:, idx], y, 'o', alpha = 0.25)
๋ค์์ ๋ถ๋ถ ์ข ์์ฑ ํ๋กฏ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋๋ค(์์ ๋ชจ๋ธ์ ๊ฒฝ์ฐ).
์ํธ:
def plot_partial_dependency(bst, X, y, f_id):
X_temp = X.copy()
x_scan = np.linspace(np.percentile(X_temp[:, f_id], 0.1), np.percentile(X_temp[:, f_id], 99.5), 50)
y_partial = []
for point in x_scan:
X_temp[:, f_id] = point
dpartial = xgb.DMatrix(X_temp[:, feature_ids])
y_partial.append(np.average(bst.predict(dpartial)))
y_partial = np.array(y_partial)
# Plot partial dependence
fig, ax = plt.subplots()
fig.set_size_inches(5, 5)
plt.subplots_adjust(left = 0.17, right = 0.94, bottom = 0.15, top = 0.9)
ax.plot(x_scan, y_partial, '-', color = 'black', linewidth = 1)
ax.plot(X[:, f_id], y, 'o', color = 'blue', alpha = 0.02)
ax.set_xlim(min(x_scan), max(x_scan))
ax.set_xlabel('Feature X', fontsize = 10)
ax.set_ylabel('Partial Dependence', fontsize = 12)
์๋ดํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค! ๋๋ ๋ด๊ฐ ์ค๊ฑฐ๋ฆฌ์์ ์ด๋ฆฌ์์ ์ค์๋ฅผ ์ ์ง๋ ๋ค๋ ๊ฒ์ ๊นจ๋ฌ์๋ค. ๋ค์์ ์ผ๋ณ๋ ๋ฐ์ดํฐ์ ๋ํ ๋ ๋ค๋ฅธ ํ ์คํธ์ ๋๋ค. ํ๋กฏ์ ๊ด์ฐฎ์ ๋ณด์ ๋๋ค.
set.seed(1024)
x = rnorm(1000, 10)
y = -1*x + rnorm(1000, 0.001) + 3*sin(x)
train = matrix(x, ncol = 1)
bst = xgboost(data = train, label = y, max_depth = 2,
eta = 0.1, nthread = 2, nrounds = 100,
monotone_constraints = '(-1)')
pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'with constraint', pch=20)
lines(train[ind,1], pred.ord, col=2, lwd = 5)
bst = xgboost(data = train, label = y, max_depth = 2,
eta = 0.1, nthread = 2, nrounds = 100)
pred = predict(bst, train)
ind = order(train[,1])
pred.ord = pred[ind]
plot(train[,1], y, main = 'without constraint', pch=20)
lines(train[ind,1], pred.ord, col=2, lwd = 5)
@hetong007 ๋ฐ๋ผ์ R ์ธํฐํ์ด์ค์ ๋ชฉํ๋ ์ฌ์ฉ์๊ฐ ๋ฌธ์์ด ์ธ์ R ๋ฐฐ์ด์ ์ ๋ฌํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๋๋ค.
monotone_constraints=c(1,-1)
PR ํํ ๋ฆฌ์ผ์ด ๋๋ฉด ์๋ ค์ฃผ์ธ์.
@hetong007 r-blogger ๋ฒ์ ์
@tqchen ์ฃ์กํฉ๋๋ค ์ฌ๋ฌ๋ถ, ์ ๋ ์ผ์ฃผ์ผ ๋์ ์ถ์ฅ์
๋๋ monotonic constraint tutorial์ ๋ํ ๋ช ๊ฐ์ง pull ์์ฒญ์ ๋ณด๋์ต๋๋ค. ๋น์ ์ ์๊ฐ์ ์๋ ค์ฃผ์ธ์. ์ด๋ค ๋นํ์ด๋ ๋นํ๋ ํ์ํฉ๋๋ค.
์ฌ๊ธฐ์์ ์ง๋ฌธํ๋ ๊ฒ์ด ์ ์ ํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ์ผ๋ฐ์ ์ธ git clone --recursive https://github.com/dmlc/xgboost
์ฌ์ฉํ์ฌ ์
๋ฐ์ดํธํ๋ฉด ์ด๊ฒ์ด ์๋ํ ๊น์?
์๋ก์ด ํํ ๋ฆฌ์ผ์ ๋ณด์์ ๋ ๋ฌป์ง๋ง ์ฝ๋ ์์ฒด์ ๋ณ๊ฒฝ์ ๋ํด์๋ ์๋ก์ด ๊ฒ์ด ์์ต๋๋ค. ๋ชจ๋ ๊ฐ์ฌํฉ๋๋ค!
์, ํํ ๋ฆฌ์ผ์ด ๋ณํฉ๋๊ธฐ ์ ์ ์ ๊ธฐ๋ฅ์ด ๋ณํฉ๋ฉ๋๋ค.
์๋ ํ์ธ์,
๋๋ ๋น์ ์ด ๋น์ ์ ์ฝ๋์์ ๋ณธ ๊ฒ๊ณผ ๊ฐ์ด ์ ์ญ์ ๋จ์กฐ๋ก์์ ์ฑ๊ณต์ ์ผ๋ก ๊ตฌํํ๋์ง ํ์ ํ ์ ์์ต๋๋ค. ๊ทธ๊ฒ์ ์ง์ญ์ ๋จ์กฐ๋ก์์ ๋ ๊ฐ๊น์ต๋๋ค.
๋ค์์ ๋จ์กฐ๋ก์์ ๊นจ๋ ๊ฐ๋จํ ์์ ๋๋ค.
`
df <- data.frame(y = c(2,rep(6,100),1,rep(11,100)),
x1= c(rep(1,101),rep(2,101)),x2 = c(1,rep(2,100),1,rep(2,100)))
๋ผ์ด๋ธ๋ฌ๋ฆฌ(xgboost)
set.seed(0)
XGB <- xgboost(data=data.matrix(df[,-1]),label=df[,1],
๋ชฉ์ =" ๋ฑ๋ก:์ ํ ",
bag.fraction=1,nround=100,monotone_constraints=c(1,0),
์ํ=0.1 )
sans_corr <- data.frame(x1=c(1,2,1,2),x2=c(1,1,2,2))
sans_corr$prediction <- predict(XGB,data.matrix(sans_corr))
`
๊ทํ์ ์ฝ๋์ ์์ ๋ํ ์ ์ดํด๊ฐ ๊ฑฐ์ง์ด ์๋๊ธธ ๋ฐ๋๋๋ค.
ํ์ฌ ์ด ๊ธฐ๋ฅ์ Sklearn API์ ์์ต๋๋ค. ๋น์ ์ด๋ ๋๊ตฐ๊ฐ๊ฐ ๊ทธ๊ฒ์ ์ถ๊ฐํ๋ ๋ฐ ๋์์ ์ฃผ์๊ฒ ์ต๋๊น? ๊ฐ์ฌ ํด์!
์ฆ๊ฐ ๋๋ ๊ฐ์ ์ฌ๋ถ๋ฅผ ์ง์ ํ์ง ์๊ณ ๋ณ์์ ์ผ๋ฐ์ ์ธ ๋จ์กฐ์ฑ์ ์ ์ฉํ ์ ์์ต๋๊น?
@davidADSP ์ํ๋ ์์ธก ๋ณ์์ ๋์์ ๋ํด ์คํผ์ด๋งจ ์๊ด ๊ด๊ณ ๊ฒ์ฌ๋ฅผ ์ํํ์ฌ ์ฆ๊ฐ ๋๋ ๊ฐ์๊ฐ ์ ์ ํ์ง ํ์ธํ ์ ์์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ 'tree_method':'hist'์ผ ๋ ์ ํจํ์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค. @tqchen ๋์์ด
์ ์ฝ ์กฐ๊ฑด์ mlogloss์ ๊ฐ์ ๋ค์ค ํด๋์ค ๋ชฉํ์ ๋ํด ์ด๋ป๊ฒ ์๋ํฉ๋๊น? ๋ค์ค ํด๋์ค ์์ค์ ๋ํด ๋จ์กฐ์ฑ ์ ์ฝ์ด ์ง์๋ฉ๋๊น? ๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์ํ๋ฉ๋๊น? (๊ฐ ํด๋์ค์๋ ๋๋ฌด๊ฐ ์์ต๋๋ค)
XGBOOST์ ์ ์ฉ๋ Monoticity Algorithm์ ๋ํ ๋ฐฑ์๊ฐ ์์ต๋๊น? ๊ธ๋ก๋ฒ ๋๋ ๋ก์ปฌ์ ๋๊น? ๋ก์ปฌ์ ํน์ ๋ ธ๋์ ํน์ ํ ๊ฒ์ ์๋ฏธํ์ง๋ง ํธ๋ฆฌ์ ๋ค๋ฅธ ๋ถ๋ถ์ ์๋ ๋ ธ๋๋ ์ ์ฒด ๋จ์กฐ์ฑ์ ์๋ฐํ ์ ์์ต๋๋ค. ๋ํ ๋๊ตฌ๋ ์ง L412-417 ์ค์ ์ดํดํ๋ ๋ฐ ๋์์ ์ฃผ์ธ์. "w"๊ฐ ์์ชฝ๊ณผ ์๋์ชฝ์ผ๋ก ์ ํ๋๋ ์ด์ . ์ด๊ฒ์ด ์ด๋ป๊ฒ ๋จ์กฐ์ฑ์ ์ ์งํ๋ ๋ฐ ๋์์ด ๋๋์ง. 457ํ - "mid"๊ฐ ์ฌ์ฉ๋๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
ํ์ฌ ์ด ๊ธฐ๋ฅ์ Sklearn API์ ์์ต๋๋ค. ๋น์ ์ด๋ ๋๊ตฐ๊ฐ๊ฐ ๊ทธ๊ฒ์ ์ถ๊ฐํ๋ ๋ฐ ๋์์ ์ฃผ์๊ฒ ์ต๋๊น? ๊ฐ์ฌ ํด์!