天天看點

機器學習內建學習進階Xgboost算法案例分析

目錄

  • ​​1 xgboost算法api介紹​​
  • ​​1.1 xgboost的安裝​​
  • ​​2 xgboost參數介紹​​
  • ​​2.1 通用參數(general parameters)​​
  • ​​2.2 Booster 參數(booster parameters)​​
  • ​​2.2.1 Parameters for Tree Booster​​
  • ​​2.2.2 Parameters for Linear Booster​​
  • ​​2.3 學習目标參數(task parameters)​​
  • ​​3 xgboost案例介紹​​
  • ​​3.1 案例背景​​
  • ​​3.2 步驟分析​​
  • ​​3.3 代碼實作​​
  • ​​4 otto案例介紹​​
  • ​​4.1 背景介紹​​
  • ​​4.22 思路分析​​
  • ​​4.3 部分代碼實作​​

1 xgboost算法api介紹

1.1 xgboost的安裝

官網連結:https://xgboost.readthedocs.io/en/latest/

pip3 install xgboost      

2 xgboost參數介紹

xgboost雖然被稱為kaggle比賽神奇,但是,我們要想訓練出不錯的模型,必須要給參數傳遞合适的值。

xgboost中封裝了很多參數,主要由三種類型構成:通用參數(general parameters),Booster 參數(booster parameters)和學習目标參數(task parameters)

  • 通用參數:主要是宏觀函數控制;
  • Booster參數:取決于選擇的Booster類型,用于控制每一步的booster(tree, regressiong);
  • 學習目标參數:控制訓練目标的表現。

2.1 通用參數(general parameters)

  1. booster [預設值=gbtree]
  2. 決定使用哪個booster,可以是gbtree,gblinear或者dart。
  • gbtree和dart使用基于樹的模型(dart 主要多了 Dropout),而gblinear 使用線性函數.
  1. silent [預設值=0]
  • 設定為0列印運作資訊;設定為1靜默模式,不列印
  1. nthread [預設值=設定為最大可能的線程數]
  • 并行運作xgboost的線程數,輸入的參數應該<=系統的CPU核心數,若是沒有設定算法會檢測将其設定為CPU的全部核心數
下面的兩個參數不需要設定,使用預設的就好了
  1. num_pbuffer [xgboost自動設定,不需要使用者設定]
  • 預測結果緩存大小,通常設定為訓練執行個體的個數。該緩存用于儲存最後boosting操作的預測結果。
  1. num_feature [xgboost自動設定,不需要使用者設定]
  • 在boosting中使用特征的次元,設定為特征的最大次元

2.2 Booster 參數(booster parameters)

2.2.1 Parameters for Tree Booster

  1. eta [預設值=0.3,别名:learning_rate]
  • 更新中減少的步長來防止過拟合。
  • 在每次boosting之後,可以直接獲得新的特征權值,這樣可以使得boosting更加魯棒。
  • 範圍: [0,1]
  1. gamma [預設值=0,别名: min_split_loss](分裂最小loss)
  • 在節點分裂時,隻有分裂後損失函數的值下降了,才會分裂這個節點。
  • Gamma指定了節點分裂所需的最小損失函數下降值。 這個參數的值越大,算法越保守。這個參數的值和損失函數息息相關,是以是需要調整的。
  • 範圍: [0,∞]
  1. max_depth [預設值=6]
  • 這個值為樹的最大深度。 這個值也是用來避免過拟合的。max_depth越大,模型會學到更具體更局部的樣本。設定為0代表沒有限制
  • 範圍: [0,∞]
  1. min_child_weight [預設值=1]
  • 決定最小葉子節點樣本權重和。XGBoost的這個參數是最小樣本權重的和.
  • 當它的值較大時,可以避免模型學習到局部的特殊樣本。 但是如果這個值過高,會導緻欠拟合。這個參數需要使用CV來調整。.
  • 範圍: [0,∞]
  1. subsample [預設值=1]
  • 這個參數控制對于每棵樹,随機采樣的比例。
  • 減小這個參數的值,算法會更加保守,避免過拟合。但是,如果這個值設定得過小,它可能會導緻欠拟合。
  • 典型值:0.5-1,0.5代表平均采樣,防止過拟合.
  • 範圍: (0,1]
  1. colsample_bytree [預設值=1]
  • 用來控制每棵随機采樣的列數的占比(每一列是一個特征)。
  • 典型值:0.5-1
  • 範圍: (0,1]
  1. colsample_bylevel [預設值=1]
  • 用來控制樹的每一級的每一次分裂,對列數的采樣的占比。
  • 我個人一般不太用這個參數,因為subsample參數和colsample_bytree參數可以起到相同的作用。但是如果感興趣,可以挖掘這個參數更多的用處。
  • 範圍: (0,1]
  1. lambda [預設值=1,别名: reg_lambda]
  • 權重的L2正則化項(和Ridge regression類似)。
  • 這個參數是用來控制XGBoost的正則化部分的。雖然大部分資料科學家很少用到這個參數,但是這個參數
  • 在減少過拟合上還是可以挖掘出更多用處的。.
  1. alpha [預設值=0,别名: reg_alpha]
  • 權重的L1正則化項。(和Lasso regression類似)。 可以應用在很高次元的情況下,使得算法的速度更快。
  1. scale_pos_weight[預設值=1]
  • 在各類别樣本十分不平衡時,把這個參數設定為一個正值,可以使算法更快收斂。通常可以将其設定為負
  • 樣本的數目與正樣本數目的比值。

2.2.2 Parameters for Linear Booster

linear booster一般很少用到。
  1. lambda [預設值=0,别稱: reg_lambda]
  • L2正則化懲罰系數,增加該值會使得模型更加保守。
  1. alpha [預設值=0,别稱: reg_alpha]
  • L1正則化懲罰系數,增加該值會使得模型更加保守。
  1. lambda_bias [預設值=0,别稱: reg_lambda_bias]
  • 偏置上的L2正則化(沒有在L1上加偏置,因為并不重要)

2.3 學習目标參數(task parameters)

  1. objective [預設值=reg:linear]
  1. “reg:linear” – 線性回歸
  2. “reg:logistic” – 邏輯回歸
  3. “binary:logistic” – 二分類邏輯回歸,輸出為機率
  4. “multi:softmax” – 使用softmax的多分類器,傳回預測的類别(不是機率)。在這種情況下,你還需要多設一個參數:num_class(類别數目)
  5. “multi:softprob” – 和multi:softmax參數一樣,但是傳回的是每個資料屬于各個類别的機率。
  1. eval_metric [預設值=通過目标函數選擇]

    可供選擇的如下所示:

  1. “rmse”: 均方根誤差
  2. “mae”: 平均絕對值誤差
  3. “logloss”: 負對數似然函數值
  4. 二分類錯誤率。

  • 其值通過錯誤分類數目與全部分類數目比值得到。對于預測,預測值大于0.5被認為是正類,其它歸為負類。
  1. “error@t”: 不同的劃分門檻值可以通過 ‘t’進行設定
  2. “merror”: 多分類錯誤率,計算公式為(wrong cases)/(all cases)
  3. “mlogloss”: 多分類log損失
  4. “auc”: 曲線下的面積
  1. seed [預設值=0]
  • 随機數的種子
- 設定它可以複現随機資料的結果,也可以用于調整參數      

3 xgboost案例介紹

3.1 案例背景

該案例和前面決策樹中所用案例一樣。

泰坦尼克号沉沒是曆史上最臭名昭着的沉船事件之一。1912年4月15日,在她的處女航中,泰坦尼克号在與冰山相撞後沉沒,在2224名乘客和機組人員中造成1502人死亡。這場聳人聽聞的悲劇震驚了國際社會,并為船舶制定了更好的安全規定。 造成海難失事的原因之一是乘客和機組人員沒有足夠的救生艇。盡管幸存下沉有一些運氣因素,但有些人比其他人更容易生存,例如婦女,兒童和上流社會。 在這個案例中,我們要求您完成對哪些人可能存活的分析。特别是,我們要求您運用機器學習工具來預測哪些乘客幸免于悲劇。

案例:https://www.kaggle.com/c/titanic/overview

我們提取到的資料集中的特征包括票的類别,是否存活,乘坐班次,年齡,登陸home.dest,房間,船和性别等。

資料:http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt
機器學習內建學習進階Xgboost算法案例分析

經過觀察資料得到:

  • 1 乘坐班是指乘客班(1,2,3),是社會經濟階層的代表。
  • 2 其中age資料存在缺失。

3.2 步驟分析

  • 1.擷取資料
  • 2.資料基本處理
  • 2.1 确定特征值,目标值
  • 2.2 缺失值處理
  • 2.3 資料集劃分
  • 3.特征工程(字典特征抽取)
  • 4.機器學習(xgboost)
  • 5.模型評估

3.3 代碼實作

  • 導入需要的子產品
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split      
  • 1.擷取資料
# 1、擷取資料
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")      
  • 2.資料基本處理
  • 2.1 确定特征值,目标值
x = titan[["pclass", "age", "sex"]]
y = titan["survived"]      
  • 2.2 缺失值處理
# 缺失值需要處理,将特征當中有類别的這些特征進行字典特征抽取
x['age'].fillna(x['age'].mean(), inplace=True)      
  • 2.3 資料集劃分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)      
  • 3.特征工程(字典特征抽取)

特征中出現類别符号,需要進行one-hot編碼處理(DictVectorizer)

x.to_dict(orient=“records”) 需要将數組特征轉換成字典資料

# 對于x轉換成字典資料x.to_dict(orient="records")
# [{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]

transfer = DictVectorizer(sparse=False)

x_train = transfer.fit_transform(x_train.to_dict(orient="records"))
x_test = transfer.fit_transform(x_test.to_dict(orient="records"))      
  • 4.xgboost模型訓練和模型評估
# 模型初步訓練
from xgboost import XGBClassifier
xg = XGBClassifier()

xg.fit(x_train, y_train)

xg.score(x_test, y_test)
# 針對max_depth進行模型調優
depth_range = range(10)
score = []
for i in depth_range:
    xg = XGBClassifier(eta=1, gamma=0, max_depth=i)
    xg.fit(x_train, y_train)
    s = xg.score(x_test, y_test)
    print(s)
    score.append(s)
# 結果可視化
import matplotlib.pyplot as plt

plt.plot(depth_range, score)

plt.show()      
機器學習內建學習進階Xgboost算法案例分析

4 otto案例介紹

– Otto Group Product Classification Challenge【xgboost實作】

4.1 背景介紹

奧托集團是世界上最大的電子商務公司之一,在20多個國家設有子公司。該公司每天都在世界各地銷售數百萬種産品,是以對其産品根據性能合理的分類非常重要。

不過,在實際工作中,從業人員發現,許多相同的産品得到了不同的分類。本案例要求,你對奧拓集團的産品進行正确的分分類。盡可能的提供分類的準确性。

連結:https://www.kaggle.com/c/otto-group-product-classification-challenge/overview

機器學習內建學習進階Xgboost算法案例分析

4.22 思路分析

  • 1.資料擷取
  • 2.資料基本處理
  • 2.1 截取部分資料
  • 2.2 把标簽紙轉換為數字
  • 2.3 分割資料(使用StratifiedShuffleSplit)
  • 2.4 資料标準化
  • 2.5 資料pca降維
  • 3.模型訓練
  • 3.1 基本模型訓練
  • 3.2 模型調優
  • 3.2.1 調優參數:
  • n_estimator,
  • max_depth,
  • min_child_weights,
  • subsamples,
  • consample_bytrees,
  • etas
  • 3.2.2 确定最後最優參數

4.3 部分代碼實作

  • 2.資料基本處理
  • 2.1 截取部分資料
  • 2.2 把标簽值轉換為數字
  • 2.3 分割資料(使用StratifiedShuffleSplit)
# 使用StratifiedShuffleSplit對資料集進行分割
from sklearn.model_selection import StratifiedShuffleSplit

sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=0)
for train_index, test_index in sss.split(X_resampled.values, y_resampled):
    print(len(train_index))
    print(len(test_index))

    x_train = X_resampled.values[train_index]
    x_val = X_resampled.values[test_index]

    y_train = y_resampled[train_index]
    y_val = y_resampled[test_index]
# 分割資料圖形可視化
import seaborn as sns

sns.countplot(y_val)

plt.show()      
  • 2.4 資料标準化
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(x_train)

x_train_scaled = scaler.transform(x_train)
x_val_scaled = scaler.transform(x_val)      
  • 2.5 資料pca降維
print(x_train_scaled.shape)
# (13888, 93)

from sklearn.decomposition import PCA

pca = PCA(n_components=0.9)
x_train_pca = pca.fit_transform(x_train_scaled)
x_val_pca = pca.transform(x_val_scaled)

print(x_train_pca.shape, x_val_pca.shape)
(13888, 65) (3473, 65)      

從上面輸出的資料可以看出,隻選擇65個元素,就可以表達出特征中90%的資訊

# 降維資料可視化
plt.plot(np.cumsum(pca.explained_variance_ratio_))

plt.xlabel("元素數量")
plt.ylabel("可表達資訊的百分占比")

plt.show()      
  • 3.模型訓練
  • 3.1 基本模型訓練
from xgboost import XGBClassifier

xgb = XGBClassifier()
xgb.fit(x_train_pca, y_train)

# 改變預測值的輸出模式,讓輸出結果為百分占比,降低logloss值
y_pre_proba = xgb.predict_proba(x_val_pca)
# logloss進行模型評估
from sklearn.metrics import log_loss
log_loss(y_val, y_pre_proba, eps=1e-15, normalize=True)

xgb.get_params      
  • 3.2 模型調優
  • 3.2.1 調優參數:
  • 1) n_estimator
scores_ne = []
n_estimators = [100,200,400,450,500,550,600,700]

for nes in n_estimators:
    print("n_estimators:", nes)
    xgb = XGBClassifier(max_depth=3, 
                        learning_rate=0.1, 
                        n_estimators=nes, 
                        objective="multi:softprob", 
                        n_jobs=-1, 
                        nthread=4, 
                        min_child_weight=1, 
                        subsample=1, 
                        colsample_bytree=1,
                        seed=42)

    xgb.fit(x_train_pca, y_train)
    y_pre = xgb.predict_proba(x_val_pca)
    score = log_loss(y_val, y_pre)
    scores_ne.append(score)
    print("測試資料的logloss值為:{}".format(score))
# 資料變化可視化
plt.plot(n_estimators, scores_ne, "o-")

plt.ylabel("log_loss")
plt.xlabel("n_estimators")
print("n_estimators的最優值為:{}".format(n_estimators[np.argmin(scores_ne)]))      
  • 2)max_depth
scores_md = []
max_depths = [1,3,5,6,7]

for md in max_depths:  # 修改
    xgb = XGBClassifier(max_depth=md, # 修改
                        learning_rate=0.1, 
                        n_estimators=n_estimators[np.argmin(scores_ne)],   # 修改 
                        objective="multi:softprob", 
                        n_jobs=-1, 
                        nthread=4, 
                        min_child_weight=1, 
                        subsample=1, 
                        colsample_bytree=1,
                        seed=42)

    xgb.fit(x_train_pca, y_train)
    y_pre = xgb.predict_proba(x_val_pca)
    score = log_loss(y_val, y_pre)
    scores_md.append(score)  # 修改
    print("測試資料的logloss值為:{}".format(log_loss(y_val, y_pre)))
# 資料變化可視化
plt.plot(max_depths, scores_md, "o-")  # 修改

plt.ylabel("log_loss")
plt.xlabel("max_depths")  # 修改
print("max_depths的最優值為:{}".format(max_depths[np.argmin(scores_md)]))  # 修改      
  • 3) min_child_weights,
  • 依據上面模式進行調整
  • 4) subsamples,
  • 5) consample_bytrees,
  • 6) etas
  • 3.2.2 确定最後最優參數
xgb = XGBClassifier(learning_rate =0.1, 
                    n_estimators=550, 
                    max_depth=3, 
                    min_child_weight=3, 
                    subsample=0.7, 
                    colsample_bytree=0.7, 
                    nthread=4, 
                    seed=42, 
                    objective='multi:softprob')
xgb.fit(x_train_scaled, y_train)

y_pre = xgb.predict_proba(x_val_scaled)

print("測試資料的logloss值為 : {}".format(log_loss(y_val, y_pre, eps=1e-15, normalize=True)))      

繼續閱讀