xgboost 多分類:objective參數(reg:linear,multi:softmax,multi:softprob)對比分析

一、問題

上篇文章中我們已經搞明白了邏輯迴歸的問題中,xgboost的train(),fit()方法以及不同參數的objective的對應的輸出結果和關係,這篇文章我們就來研究下xgboost再做多分類時,train(),fit()建模後輸出的值是怎麼樣的,它都有那些objective的參數,並且分別對應着怎樣的輸出?

二、objective參數比較

xgboost的官方文檔關於多分類的objective如下:


從文檔中我們可以看出,multi:softmax是使用softmax後產生的分類結果,而multi:softprob是輸出的概率矩陣。我們這裏以標籤爲0,1,2的三分類數據爲例,前者輸出的結果是一維數據,0,1,2的分類標籤;後者輸出的是n*3的概率矩陣(n爲測試數據的條數)。

這兩個參數之間有什麼關係呢?


從這裏我們可以看出,最終的分類標籤是從概率矩陣中得到的,在n*3的概率矩陣中(如下圖):


我們可以看出概率矩陣中每行數據的數值相加得1,我們取每行數據中概率值最大數值的下標作爲最終的分類標籤,然後給multi:softmax的輸出結果做對比看是否一致。

xgb_params = {
    'learning_rate': 0.1,  # 步長
    'n_estimators': 10,
    'max_depth': 5,  # 樹的最大深度
    'objective': 'multi:softprob',
    'num_class': 3,
    'min_child_weight': 1,  # 決定最小葉子節點樣本權重和,如果一個葉子節點的樣本權重和小於min_child_weight則拆分過程結束。
    'gamma': 0,  # 指定了節點分裂所需的最小損失函數下降值。這個參數的值越大,算法越保守
    'silent': 0,  # 輸出運行信息
    'subsample': 0.8,  # 每個決策樹所用的子樣本佔總樣本的比例(作用於樣本)
    'colsample_bytree': 0.8,  # 建立樹時對特徵隨機採樣的比例(作用於特徵)典型值:0.5-1
    'nthread': 4,
    'seed': 27}
print "training..."
model = xgb.train(xgb_params, xgb.DMatrix(x_train, y_train))
softprob_pred = model.predict(xgb.DMatrix(x_test))
print softprob_pred
# 處理概率矩陣-得到最終的預測標籤
indexlist = []
for item in softprob_pred:
    maxnum = max(item)
    item = np.where(item == maxnum)
    indexlist.append(item[0].item())
################################
xgb_params = {
    'learning_rate': 0.1,  # 步長
    'n_estimators': 20,
    'max_depth': 5,  # 樹的最大深度
    'objective': 'multi:softmax',
    'num_class': 3,
    'min_child_weight': 1,  # 決定最小葉子節點樣本權重和,如果一個葉子節點的樣本權重和小於min_child_weight則拆分過程結束。
    'gamma': 0,  # 指定了節點分裂所需的最小損失函數下降值。這個參數的值越大,算法越保守
    'silent': 0,  # 輸出運行信息
    'subsample': 0.8,  # 每個決策樹所用的子樣本佔總樣本的比例(作用於樣本)
    'colsample_bytree': 0.8,  # 建立樹時對特徵隨機採樣的比例(作用於特徵)典型值:0.5-1
    'nthread': 4,
    'seed': 27}
print "training..."
model = xgb.train(xgb_params, xgb.DMatrix(x_train, y_train))
softmax_pred = model.predict(xgb.DMatrix(x_test))
count = 0
for i in np.arange(0, len(softmax_pred)):
    if (softmax_pred[i] == indexlist[i]):
        count += 1
print "len:", len(softmax_pred)
print "count:", count
if count == len(softmax_pred):
    print "true"
else:
    print "false"

輸出的結果:


由此可見,最終的預測標籤就是通過取概率矩陣的每行數據最大值的下標獲得的。

那麼問題來了,我們知道像xgboost這類集成樹算法,他本身用到的是迴歸樹,這就決定了它本身就是用來做迴歸的,調整後可以用來做分類,對於多分類來說是通過softmax函數把迴歸結果映射成最終的多分類標籤的。我們把objective改成線性迴歸的參數(reg:linear),看下結果如何?如何通過softmax函數轉換成最終分類標籤?

輸出結果如下:


得到的是一個一維0-2之間的預測值,怎麼映射成一個831*3的矩陣呢?

對於softmax函數它的輸入和輸出是相同的shape,對於一個831*1的數據,得到的也是一個值都在0-1之間的831*1的數據,根本無法直接這樣得到概率矩陣。這個問題有想法的同學可以加QQ羣:821675528交流!

三、多分類問題中fit()和train()的結果

用相同的數據,相同的參數(objective:multi:softmax),分別用fit()和train()方法得到的輸出結果是一致的,都是預測的0,1,2的標籤,實驗過程如下:

clf = XGBClassifier(
    n_estimators=20,  # 迭代次數
    learning_rate=0.1,  # 步長
    max_depth=5,  # 樹的最大深度
    min_child_weight=1,  # 決定最小葉子節點樣本權重和
    silent=1,  # 輸出運行信息
    subsample=0.8,  # 每個決策樹所用的子樣本佔總樣本的比例(作用於樣本)
    colsample_bytree=0.8,  # 建立樹時對特徵隨機採樣的比例(作用於特徵)典型值:0.5-1
    objective='multi:softmax',  # 多分類!!!!!!
    num_class=3,
    nthread=4,
    seed=27)
print "training..."
clf.fit(x_train, y_train, verbose=True)
fit_pred = clf.predict(x_test)
print fit_pred
xgb_params = {
    'learning_rate': 0.1,  # 步長
    'max_depth': 5,  # 樹的最大深度
    'objective': 'multi:softmax',
    'num_class': 3,
    'min_child_weight': 1,  # 決定最小葉子節點樣本權重和,如果一個葉子節點的樣本權重和小於min_child_weight則拆分過程結束。
    'silent': 0,  # 輸出運行信息
    'subsample': 0.8,
    'colsample_bytree': 0.8,  # 建立樹時對特徵隨機採樣的比例(作用於特徵)典型值:0.5-1
    'nthread': 4,
    'seed': 27}
print "training..."
model = xgb.train(xgb_params, xgb.DMatrix(x_train, y_train), num_boost_round=20)
train_pred = model.predict(xgb.DMatrix(x_test))
count = 0
print train_pred
# 判斷train_pred和fit_pred是否一致
for i in np.arange(0, len(train_pred)):
    if (train_pred[i] == fit_pred[i]):
        count += 1
print "len:", len(train_pred)
print "count:", count
if count == len(train_pred):
    print "true"
else:
    print "false"

實驗結果如下:


總結:綜上我們可以看出xgboost多分類問題就是通過softmax函數做映射得到最終的分類標籤,只是怎麼把迴歸的結果映射成概率矩陣,我還沒有搞清楚,有好的想法或者同樣疑問的同學可以加QQ羣:821675528交流!!





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章