νλ ¨λ XGBoost νΈλ¦¬λ₯Ό λ€ννλ €κ³ νλ©΄ λ€μ νμμΌλ‘ νμλ©λλ€.
0:[f37<39811]
1:[f52<199.5]
3:leaf=-0.021461
4:[f2<0.00617284]
9:leaf=-0.0118755
10:[f35<-83.548]
19:[f13<0.693844]
23:[f37<1831]
29:leaf=-0
30:leaf=0.123949
24:leaf=0.0108628
20:[f35<-74.6198]
25:leaf=-0.0175897
26:leaf=0.051898
2:leaf=-0.0239901
νΈλ¦¬ κ΅¬μ‘°κ° λ¬΄μμΈμ§λ λΆλͺ νμ§λ§ 리ν κ°μ ν΄μνλ λ°©λ²μ λͺ ννμ§ μμ΅λλ€. _ μ΄μ§ _ λΆλ₯ λ¬Έμ λ° λ‘κ·Έ μμ€ λΉμ© ν¨μμ κ²½μ° λ‘μ§μ€ν± ν¨μλ₯Ό μ¬μ©νμ¬ λ¦¬ν κ°μ ν΄λμ€ νλ₯ λ‘ λ³νν μ μμ΅λλ€: 1/(1+exp(value)). κ·Έλ¬λ _multiclass_ λΆλ₯ λ¬Έμ μ κ²½μ° ν΄λΉ κ°μ΄ μν ν΄λμ€μ λν μ λ³΄κ° μμΌλ©° ν΄λΉ μ λ³΄κ° μμΌλ©΄ ν΄λμ€ νλ₯ μ κ³μ°νλ λ°©λ²μ΄ λͺ ννμ§ μμ΅λλ€.
μ΄λ€ μμ΄λμ΄? μλλ©΄ νλ ¨λ νΈλ¦¬μμ ν΄λΉ μ 보λ₯Ό κ°μ Έμ€λ λ€λ₯Έ κΈ°λ₯μ΄ μμ΅λκΉ?
μ λ κ°μ μ§λ¬Έμ΄ μμ΅λλ€. λ΄κ° μμμ°¨λ¦° κ²μ 20κ°μ ν΄λμ€κ° μκ³ μΆμ κΈ°μ μλ₯Ό 100μΌλ‘ μ€μ νλ©΄ λͺ¨λΈμ 20*100=2000κ°μ λλ¬΄κ° μΈμλλ€λ κ²μ λλ€. μ΄μ λ΄ μΆμΈ‘μΌλ‘λ μ²μ 100λͺ μ μΆμ μκ° μΌλ±κ³Ό λ€λ₯Έ μ¬λμ λΆλ₯νλ€λ κ²μ λλ€. λ€μ 100κ°μ μΆμ κΈ°λ λ λ²μ§Έ ν΄λμ€μ λ€λ₯Έ ν΄λμ€λ₯Ό λΆλ₯ν©λλ€.
νμΈν μλ μμ§λ§ μλ§λ μ΄μ κ°μ μ μμ΅λκΉ?
κ·Έκ²μ λ΄κ° μ μ λμΉμ±μ§ λͺ»νλ μμ£Ό μ’μ κ΄μ°°μ λλ€. μ¬μ€, λͺ¨λΈμ νΈλ¦¬ μλ n_estimator x n_class μ λλ€. κ·Έλ¬λ λ무μ μμλ₯Ό νμ νκΈ° μν΄ λ€μκ³Ό κ°μ μ₯λκ° μλ₯Ό μ¬μ©νμ΅λλ€.
x = np.concatenate([np.ones([10,1])*np.array([1,0,0]),np.ones([10,1])*np.array([0,1,0]),np.ones([10,1])*np.array([0,0,1])], axis=0)
y = np.array([['a']*10+['c']*10+['b']*10]).reshape([30,1])
model = xgb.XGBClassifier(n_estimators=2, objective='mlogloss').fit(x, y)
model.booster().dump_model('trees.txt')
κΈ°λ³Έμ μΌλ‘ [1,0,0]μ΄ 'a'μ 맀νλκ³ , [0,1,0]μ΄ 'c'μ 맀νλκ³ , [0,0,1]μ΄ 'b'μ 맀νλλ νλ ¨ λ°μ΄ν° μΈνΈλ₯Ό μμ±ν©λλ€. λλ μλμ μΌλ‘ 'b'μ 'c'μ μμλ₯Ό λ°κΏ xgboostκ° λ무λ₯Ό λ€ννκΈ° μ μ λ μ΄λΈμ κΈ°λ°μΌλ‘ ν΄λμ€λ₯Ό μ λ ¬νλμ§ νμΈνμ΅λλ€.
λ€μμ λ€νλ λͺ¨λΈμ λλ€.
booster[0]:
0:[f0<0.5] yes=1,no=2,missing=1
1:leaf=-0.0674157
2:leaf=0.122449
booster[1]:
0:[f2<0.5] yes=1,no=2,missing=1
1:leaf=-0.0674157
2:leaf=0.122449
booster[2]:
0:[f1<0.5] yes=1,no=2,missing=1
1:leaf=-0.0674157
2:leaf=0.122449
booster[3]:
0:[f0<0.5] yes=1,no=2,missing=1
1:leaf=-0.0650523
2:leaf=0.10941
booster[4]:
0:[f2<0.5] yes=1,no=2,missing=1
1:leaf=-0.0650523
2:leaf=0.10941
booster[5]:
0:[f1<0.5] yes=1,no=2,missing=1
1:leaf=-0.0650523
2:leaf=0.10941
κ²°λ‘ μ λ€μκ³Ό κ°μ΅λλ€.
numpy.unique()
λ°ννλ κ²κ³Ό μΌμΉνλ κ² κ°μ΅λλ€. μ¬κΈ°μμλ μνλ²³μμ΄λ―λ‘ μ²« λ²μ§Έ νΈλ¦¬λ f0 μ μ¬μ©νκ³ λ λ²μ§Έ νΈλ¦¬λ f2 λ₯Ό μ¬μ©νλ μ΄μ μ
λλ€.μ΄λ¬ν μ λ³΄κ° xgboost λ¬Έμμ μΆκ°λλ©΄ μ’μ κ²μ λλ€.
μ§κΈ μ΄ λ¬Έμ λ₯Ό λ«κ³ μμ΅λλ€.
μ¬κΈ°μ μμ§ μκ²¬μ΄ μμ΅λλ€. λ€μ€ ν΄λμ€μ κ²½μ° νΈλ¦¬κ° ꡬ쑰νλλ λ°©μμ λμν©λλ€. κ·Έλ¬λ 리ν κ°μ μ΄λ»κ² νλ₯ λ‘ λ³νλ©λκΉ?
λ°μ΄λ리 μΌμ΄μ€μ κ²½μ° 1/(1+exp(value))λ₯Ό μ μ©ν΄μΌ νλ λ°λ©΄, λ€μ€ ν΄λμ€ μΌμ΄μ€μ κ²½μ° 1/(1+exp(-value))λ₯Ό μ μ©ν΄μΌ νλ κ²μ²λΌ 보μ λλ€.
μ¬λ‘λ₯Ό 보면 λ§λ κ² κ°μ΅λλ€. ν κ³ λ§μ!
κ·Έλ¬λ μ΄κ²μ΄ λ°μ΄λ리 λ° λ€μ€ ν΄λμ€ μ¬λ‘μ λν΄ λ€λ₯΄κ² μ μλλ μ΄μ λ₯Ό μ΄ν΄νμ§ λͺ»ν©λλ€.
λ€, μ°ΈμΌλ‘ λ§ν΄μ λ§€μ° μ΄μνκ³ νΌλμ€λ½μ΅λλ€.
λλ UCI Car Dataset(μλμ°¨λ₯Ό νμ© λΆκ°, νμ© κ°λ₯, μνΈ λλ λ§€μ° μ°μλ‘ λΆλ₯νλ κ³³)μμ ν μ€νΈνμ¬ κ·Έ κ²°λ‘ μ λλ¬νμ΅λλ€.
νΈλ¦¬λ₯Ό sklearn νΈλ¦¬ λλ μ΄μ μ μ¬ν κ²μΌλ‘ λ³νν μ μλ μΆκ° κΈ°λ₯μ΄ μμΌλ©΄ μ’μ κ²μ λλ€. νμ, sklearn λ무 μ€μμ λλ μ΄κ²μ΄ μ¬λ°λ₯΄κ² λ³νλμλ€κ³ μ μ΄λ 100% νμ ν©λλ€. xGB νΈλ¦¬μ κ²½μ° μμ¬μ΄ λ¨μ μμ΅λλ€.
νλ₯ν κΈ°λ₯μ΄ λ κ²μ΄λΌλ λ° λμν©λλ€.
@GillesVandewiele @sosata : κ·Έλμ κ·Έ λ‘μ§μ€ν±μμ (ν΄λμ€ i
) [ 1/(1+exp(-value))
] , value
λ ν΄λΉ νΉμ ν΄λμ€μ νΈλ¦¬ κ΄λ ¨ νλͺ©μ ν΄λΉνλ λͺ¨λ 리ν μ μμ ν©κ³μ
λλ€. μνλ‘?
λ΄ μ΄κΈ° μ견μ μμμ [1 0 0]μ λν ν΄λμ€ νλ₯ μ μμΈ‘νλ €κ³ νλ©΄:
print(model.predict_proba(np.array([[1,0,0]])))
λ€μ κ²°κ³Όλ₯Ό μμ±ν©λλ€.
[[ 0.41852772 0.29073614 0.29073614]]
1/(1+exp(-value))
κ° μ΄κ²μ μμ±ν λ°©λ²μ΄ μμ΅λλ€. μ μΌν λ°©λ²μ μ΄λ¬ν νλ₯ μ΄ ν΄λμ€ μ 체μμ ν©μ°λ κ°μ _softmax_ ν¨μμ μν΄ μμ±λλ€λ κ²μ
λλ€.
p[i] = exp(val[i])/(exp(val[1])+exp(val[2])+...+exp(val[N]))
μ¬κΈ°μ iλ λμ ν΄λμ€(N ν΄λμ€ μ€)μ΄κ³ val[i]λ ν΄λΉ ν΄λμ€μ μν νΈλ¦¬μμ μμ±λ λͺ¨λ κ°μ ν©μ
λλ€.
μ°λ¦¬μ μμμ:
print(np.exp(+0.122449+0.10941)/(np.exp(+0.122449+0.10941)+np.exp(-0.0674157-0.0650523)+np.exp(-0.0674157-0.0650523)))
print(np.exp(-0.0674157-0.0650523)/(np.exp(+0.122449+0.10941)+np.exp(-0.0674157-0.0650523)+np.exp(-0.0674157-0.0650523)))
print(np.exp(-0.0674157-0.0650523)/(np.exp(+0.122449+0.10941)+np.exp(-0.0674157-0.0650523)+np.exp(-0.0674157-0.0650523)))
λ€μμ μμ±ν©λλ€:
0.418527719063
0.290736140469
0.290736140469
μ΄κ²μ΄ λ°λ‘ predict_proba() ν¨μκ° μ 곡ν κ²μ λλ€.
λ§λ κ² κ°μ΅λλ€ @sosata
μ κ²½μ°μλ κ° λ무λ₯Ό κ°λ³μ μΌλ‘ λ³ννκ³ μΆμμ΅λλ€(λ°λΌμ λ€λ₯Έ λ무μ μ κ°μ μ¬μ©νμ§ μμ). κ±°κΈ°μμ μκ·Έλͺ¨μ΄λ ν¨μκ° κ·Έ μΌμ νλ κ²μ²λΌ 보μμ΅λλ€.
@sosata μ΄μ¨λ ν΄λμ€λ³λ‘ κΈ°λ₯ μ€μλλ₯Ό μ»μ μ μμ΅λκΉ? νμ¬ κ΅¬νμ λͺ¨λ ν΄λμ€μ λν λͺ¨λ κΈ°μ¬λ₯Ό ν©μ°ν κ²μ΄λΌκ³ μκ°ν©λλ€. κ·Έλ¬λ R APIμλ μ΄μ λν 맀κ°λ³μκ° μλ κ² κ°μ΅λλ€(https://github.com/CodingCat/xgboost/commit/e9405236a01715be1550a7e3809f36fc69ad4e8a μ°Έμ‘°).
@mlxai λν Python APIλ§ μλνλλ° ν΄λμ€λ³λ‘ μ»μ μ μμλ κΈ°μ΅μ΄ μμ΅λλ€.
κ·Έλ¬λ μ μκ°μλ XGBoostμ κΈ°λ₯ μ€μλλ₯Ό ν΄λΉ κΈ°λ₯μ λν μ΄ λΆν μλ‘ μ μνλ κ²μ λ€μ λ¨μν©λλ€. κ°μΈμ μΌλ‘ μ λ κΈ°λ₯ μΈνΈμμ ν΄λΉ κΈ°λ₯μ μ κ±°νκ³ ν΄λΉ κΈ°λ₯ μμ΄ λͺ¨λΈμ νλ ¨νκ³ ν μ€νΈν λ μ νλμ κ²°κ³Ό κ°μ(λλ μ¦κ°)λ₯Ό κ³μ°νμ¬ κΈ°λ₯ μ€μλλ₯Ό κ³μ°ν©λλ€. μ λ λͺ¨λ κΈ°λ₯μ λν΄ μ΄ μμ μ μννκ³ "κΈ°λ₯ μ€μλ"λ₯Ό μ νλμ κ°μ(λλ λ§μ΄λμ€ μ¦κ°)μ μμΌλ‘ μ μν©λλ€. κ° κΈ°λ₯ μ κ±°μ λν΄ λ€λ₯Έ νμ΅/ν μ€νΈ νμ μ§ν©μ μ¬μ©νμ¬ κ΅μ‘ λ° ν μ€νΈλ₯Ό μ¬λ¬ λ² μνν μ μμΌλ―λ‘ κΈ°λ₯ μ€μλμ μ λ’° ꡬκ°λ μΆμ ν μ μμ΅λλ€. λν ν΄λμ€λ³λ‘ μ€μλλ₯Ό λ³λλ‘ κ³μ°νμ¬ ν΄λμ€λ³ κΈ°λ₯ μ€μλλ₯Ό μ»μ΅λλ€. μ΄κ²μ λΆν μλ₯Ό κ³μ°νλ κ²λ³΄λ€ λ΄ νλ‘μ νΈμμ λ μλ―Έ μλ κ²°κ³Όλ₯Ό μμ±νμ΅λλ€.
@sosata κ·νμ μλ λ§€μ° μ§κ΄μ μ΄μ§λ§ κ° ν΄λμ€μ μ μλ₯Ό μ΄λ»κ² μ°μΆνλμ§ μμ§ μ λͺ¨λ₯΄κ² μ΅λλ€. μ‘°κΈ μ€λͺ
@chrisplyn νΉμ ν΄λμ€μ μνλ μμλΈμ λͺ¨λ κ²°μ νΈλ¦¬λ₯Ό νκ°νκ³ κ²°κ³Ό μ μλ₯Ό ν©μ°ν©λλ€.
μμμ @sosata κ° μ¬λ°λ₯΄κ² μΈκΈνλ―μ΄ μμλΈμ λ무 μλ n_esimators * n_classes
@sosata κ·νμ μλ λ§€μ° λͺ νν©λλ€. λ§€μ° κ°μ¬ν©λλ€!
@chrisplyn μμΈ‘ μΈμ€ν΄μ€ [1,0,0]μ λΆμ€ν°[0~5]λ‘ λΆλ₯λκ³ κ°κ° 리ν κ° [0.122449, -0.0674157, -0.0674157, 0.10941, -0.0650523, -0.0650523]μ μ»μ΅λλ€.
λΆμ€ν°[0, 3]μ ν΄λμ€ 0μ μνκ³ , λΆμ€ν°[1, 4]λ ν΄λμ€ 1μ μνκ³ , λΆμ€ν°[2, 5]λ ν΄λμ€ 2μ μνλ―λ‘ val[0] =(0.122449 + 0.10941), val[1 ] = (-0.0674157 + -0.0650523), val[2] = (-0.0674157 + -0.0650523).
λ λͺ
νν©λκΉ?
κ°μ₯ μ μ©ν λκΈ
κ·Έκ²μ λ΄κ° μ μ λμΉμ±μ§ λͺ»νλ μμ£Ό μ’μ κ΄μ°°μ λλ€. μ¬μ€, λͺ¨λΈμ νΈλ¦¬ μλ n_estimator x n_class μ λλ€. κ·Έλ¬λ λ무μ μμλ₯Ό νμ νκΈ° μν΄ λ€μκ³Ό κ°μ μ₯λκ° μλ₯Ό μ¬μ©νμ΅λλ€.
κΈ°λ³Έμ μΌλ‘ [1,0,0]μ΄ 'a'μ 맀νλκ³ , [0,1,0]μ΄ 'c'μ 맀νλκ³ , [0,0,1]μ΄ 'b'μ 맀νλλ νλ ¨ λ°μ΄ν° μΈνΈλ₯Ό μμ±ν©λλ€. λλ μλμ μΌλ‘ 'b'μ 'c'μ μμλ₯Ό λ°κΏ xgboostκ° λ무λ₯Ό λ€ννκΈ° μ μ λ μ΄λΈμ κΈ°λ°μΌλ‘ ν΄λμ€λ₯Ό μ λ ¬νλμ§ νμΈνμ΅λλ€.
λ€μμ λ€νλ λͺ¨λΈμ λλ€.
κ²°λ‘ μ λ€μκ³Ό κ°μ΅λλ€.
numpy.unique()
λ°ννλ κ²κ³Ό μΌμΉνλ κ² κ°μ΅λλ€. μ¬κΈ°μμλ μνλ²³μμ΄λ―λ‘ μ²« λ²μ§Έ νΈλ¦¬λ f0 μ μ¬μ©νκ³ λ λ²μ§Έ νΈλ¦¬λ f2 λ₯Ό μ¬μ©νλ μ΄μ μ λλ€.μ΄λ¬ν μ λ³΄κ° xgboost λ¬Έμμ μΆκ°λλ©΄ μ’μ κ²μ λλ€.