xgboost 邏輯回歸:objective參數(reg:logistic,binary:logistic,binary:logitraw,)對比分析
一、問題
熟悉xgboost的小伙伴都知道,它在訓練模型時,有train()方法和fit()方法,兩種方法都是用於構建模型的,然而在使用過程中有什么不同的地方呢,這篇文章帶領大家一起來看一下。train方法使用如下:
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
train_pred=model.predict(xgb.DMatrix(x_test))
而fit方法是直接使用xgboost封裝好的XGBClassifier或者XGBRegressor時使用:
-
model = XGBClassifier(
-
learning_rate= 0.1,
-
n_estimators= 20,
-
max_depth= 4,
-
objective= 'binary:logistic',
-
seed= 27,
-
silent= 0
-
)
-
model.fit(x_train,y_train,verbose= True)
-
fit_pred=model.predict(x_test)
-
print fit_pred
相同的數據集,相同的參數得到的預測值卻是不一樣的,fit_pred的值是0,1的具體的預測標簽,train_pred的值是0-1之間的概率值;為什么結果是不一樣的呢?如何把0-1之間的概率值映射成0,1標簽呢?這個后面揭曉,我們先看下,xgboost中用於做邏輯回歸的objective的參數都有哪些,得到預測結果有什么不同!
二、objective參數比較
xgboost官方文檔關於邏輯回歸objective有三個參數,如下:
1、reg:logistic PK binary:logistic
實際上reg:logistic,binary:logistic都是輸出邏輯回歸的概率值,實驗過程如下:
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'binary:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
bin_log_pred=model.predict(xgb.DMatrix(x_test))
-
# print bin_log_pred
-
###################################
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
reg_log_pred=model.predict(xgb.DMatrix(x_test))
-
# print reg_log_pred
-
count= 0
-
for i in np.arange(0,len(reg_log_pred)):
-
if (reg_log_pred[i]==bin_log_pred[i]):
-
count+= 1
-
print "len:",len(reg_log_pred)
-
print "count:",count
-
if count==len(reg_log_pred):
-
print "true"
-
else:
-
print "false"
輸出結果:
2、reg:logistic PK binary:logitraw
然后我們再來看下binary:logitraw參數,由文檔可以看出這個參數得到的是集成樹模型最后輸出的得分,即轉換成概率值之前的值,我們知道xgboost這類集成樹算法用到的回歸樹,這就決定了它本身就是用來做回歸的,調整后可以用來做分類,這里的調整是指通過sigmoid函數處理后來做二分類,通過softmax函數處理后來做多分類。於是,我們定義一個sigmoid函數,把binary:logitraw參數輸出的得分通過sigmoid函數映射成概率值,對比下是否和reg:logistic參數得到的概率值是一樣的。
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
reg_log_pred=model.predict(xgb.DMatrix(x_test))
-
# print reg_log_pred
-
###################################
-
params ={ 'eta': 0.1,
-
'max_depth': 4,
-
'num_boost_round':20,
-
'objective': 'binary:logitraw',
-
# 'n_jobs': 4,
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train))
-
logitraw_pred=model.predict(xgb.DMatrix(x_test))
-
print logitraw_pred
-
def sigmoid(x):
-
return 1./(1.+np.exp(-x))
-
y=sigmoid(logitraw_pred)
-
print y
-
count= 0
-
for i in np.arange(0,len(reg_log_pred)):
-
if (reg_log_pred[i]==y[i]):
-
count+= 1
-
print len(reg_log_pred)
-
print count
-
if count==len(reg_log_pred):
-
print "true"
-
else:
-
print "false"
輸出結果:
3、總結
上述實驗,通過使用相同的數據集,相同的參數(除了objective參數,其他相同),研究了邏輯回歸的objective的三種不同參數的輸出結果,得到如下結論:
1、binary:logistic和 'objective': 'reg:logistic'的輸出是一樣的,都是預測的概率
2、binary:logitraw是輸出的得分,用sigmoid()函數處理后就和上述兩個概率值一致
三、XGBClassifier都做了些什么
回到我們一開始的問題,xgboost train()方法得到概率值之后,如何處理成最終的0,1標簽呢?
這個工作應該是在XGBClassifier中完成的,我們進行下列實驗進行驗證:
-
model = XGBClassifier(
-
learning_rate= 0.1,
-
n_estimators= 20,
-
max_depth= 4,
-
objective= 'binary:logistic',
-
seed= 27,
-
silent= 0
-
)
-
model.fit(x_train,y_train,verbose= True)
-
fit_pred=model.predict(x_test)
-
print fit_pred
-
#######################
-
params ={ 'learning_rate': 0.1,
-
'max_depth': 4,
-
'objective': 'reg:logistic',
-
'random_state': 27,
-
'silent':0
-
}
-
model = xgb.train(params,xgb.DMatrix(x_train, y_train),num_boost_round= 20)
-
train_pred=model.predict(xgb.DMatrix(x_test))
-
#概率值的閾值假設為0.5,小於等於0.5的預測為0,否則預測為1
-
for i in np.arange(0,len(train_pred)):
-
if train_pred[i]<0.5:
-
train_pred[i]= 0
-
else:
-
train_pred[i]= 1
-
print train_pred
-
print type(train_pred)
-
count= 0
-
for i in np.arange(0,len(train_pred)):
-
if (train_pred[i]==fit_pred[i]):
-
count+= 1
-
print len(train_pred)
-
print count
-
if count==len(train_pred):
-
print "true"
-
else:
-
print "false"
輸出的結果:
由此可見我們的假設是成立的,XGBClassifier里就是把預測的概率值,取閾值0.5,小於這個值的為0,大於這個值的為1,實驗過程中還發現並沒有等於0.5的概率值,我的設想是對於一個二分類問題,把概率預測成0.5沒有任何意義o(* ̄︶ ̄*)o
為了增加可信度,我們把訓練數據放到模型里進行預測,並對於,train和fit輸出的預測結果,結果如下: