久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    100天搞定機器學習|Day61 手算+可視化,終于徹底理解了 XGBoost

     ml_Py 2021-12-08

    我們已經學習了XGBoost淵源及優點、模型原理及優化推導、模型參數解析:100天搞定機器學習|Day60 遇事不決,XGBoost,文章有點太枯燥,大家可能對其中的公式推導和參數還不甚理解。

    今天我們以西瓜數據集為例,配合手算,拆開揉碎,深入理解公式與代碼之間的內在聯系,然后用可視化的方式更形象地看透 XGBoost 的原理

    本文又硬又干,歡迎同學們來個素質三連:在看、收藏、轉發,沒有關注的同學也來個關注下哈↓↓↓↓↓↓

    #本文用到的庫
    import numpy as np
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn import preprocessing
    from xgboost.sklearn import XGBClassifier
    from xgboost import plot_tree
    import matplotlib.pyplot as plt
    from xgboost import plot_importance
    from sklearn.model_selection import GridSearchCV
    from sklearn.metrics import classification_report, precision_recall_curve

    西瓜數據集及預處理

    def getDataSet():
        dataSet = [
            ['青綠''蜷縮''濁響''清晰''凹陷''硬滑', 0.697, 0.460, 1],
            ['烏黑''蜷縮''沉悶''清晰''凹陷''硬滑', 0.774, 0.376, 1],
            ['烏黑''蜷縮''濁響''清晰''凹陷''硬滑', 0.634, 0.264, 1],
            ['青綠''蜷縮''沉悶''清晰''凹陷''硬滑', 0.608, 0.318, 1],
            ['淺白''蜷縮''濁響''清晰''凹陷''硬滑', 0.556, 0.215, 1],
            ['青綠''稍蜷''濁響''清晰''稍凹''軟粘', 0.403, 0.237, 1],
            ['烏黑''稍蜷''濁響''稍糊''稍凹''軟粘', 0.481, 0.149, 1],
            ['烏黑''稍蜷''濁響''清晰''稍凹''硬滑', 0.437, 0.211, 1],
            ['烏黑''稍蜷''沉悶''稍糊''稍凹''硬滑', 0.666, 0.091, 0],
            ['青綠''硬挺''清脆''清晰''平坦''軟粘', 0.243, 0.267, 0],
            ['淺白''硬挺''清脆''模糊''平坦''硬滑', 0.245, 0.057, 0],
            ['淺白''蜷縮''濁響''模糊''平坦''軟粘', 0.343, 0.099, 0],
            ['青綠''稍蜷''濁響''稍糊''凹陷''硬滑', 0.639, 0.161, 0],
            ['淺白''稍蜷''沉悶''稍糊''凹陷''硬滑', 0.657, 0.198, 0],
            ['烏黑''稍蜷''濁響''清晰''稍凹''軟粘', 0.360, 0.370, 0],
            ['淺白''蜷縮''濁響''模糊''平坦''硬滑', 0.593, 0.042, 0],
            ['青綠''蜷縮''沉悶''稍糊''稍凹''硬滑', 0.719, 0.103, 0]
        ]

        features = ['color''root''knocks''texture''navel''touch''density''sugar','good']
        dataSet = np.array(dataSet)
        df = pd.DataFrame(dataSet,columns=features)
        for feature in features[0:6]:
            le = preprocessing.LabelEncoder()
            le = le.fit(df[feature])
            df[feature] = le.transform(df[feature])
        df.iloc[:,6:8]=df.iloc[:,6:8].astype(float)
        df['good']=df['good'].astype(int)
        return df

    本文中,我們使用sklearn風格的接口,并使用sklearn風格的參數。xgboost.XGBClassifier實現了scikit-learn 的分類模型API:

    xgboost.XGBClassifier(max_depth=3, learning_rate=0.1, n_estimators=100, 
         silent=True, objective='binary:logistic', booster='gbtree', n_jobs=1,
         nthread=None, gamma=0, min_child_weight=1, max_delta_step=0, subsample=1,
         colsample_bytree=1, colsample_bylevel=1, reg_alpha=0, reg_lambda=1,
         scale_pos_weight=1, base_score=0.5, random_state=0, seed=None, 
         missing=None, **kwargs)

    為方便手算,我們設n_estimators=2,即XGBoost僅2棵樹,正則項,系數=1,gamma=0。

    #訓練模型
    df = getDataSet()
    X, y = df[df.columns[:-1]],df['good']
    X_train, X_test, y_train, y_test = train_test_split(X,y, random_state=0)
    sklearn_model_new = XGBClassifier(n_estimators=2,max_depth=5,learning_rate= 0.1, verbosity=1, objective='binary:logistic',random_state=1)
    sklearn_model_new.fit(X_train, y_train)
    model.fit(X_train, y_train)

    XGBoost可視化

    現在看一下XGBoost的內部結構,看看樹的形狀。XGBoost可視化可使用xgboost.plot_tree方法:

    xgboost.plot_tree(booster, fmap='', num_trees=0, rankdir='UT', ax=None, **kwargs)

    參數:

    booster:一個Booster對象, 一個 XGBModel 對象
    fmap:一個字符串,給出了feature map 文件的文件名
    num_trees:一個整數,制定了要繪制的子數的編號。默認為 0
    rankdir:一個字符串,它傳遞給graphviz的graph_attr
    ax:一個matplotlib Axes 對象。特征重要性將繪制在它上面。如果為None,則新建一個Axes
    kwargs:關鍵字參數,用于傳遞給graphviz 的graph_attr

    XGBoost很多函數會用的一個參數fmap (也就是feature map),但是文檔里面基本沒解釋這個fmap是怎么產生的,Kaggle上有好心人提供了解決方案: https://www./mmueller/xgb-feature-importance-python

    def ceate_feature_map(features):
        outfile = open('xgb.fmap''w')
        i = 0
        for feat in features:
            outfile.write('{0}\t{1}\tq\n'.format(i, feat))
            i = i + 1
        outfile.close()
    ceate_feature_map(df.columns)

    這個函數就是根據給定的特征名字(直接使用數據的列名稱), 按照特定格式生成一個xgb.fmap文件, 這個文件就是XGBoost文檔里面多次提到的fmap, 注意使用的時候, 直接提供文件名, 比如fmap='xgb.fmap'.

    有了fmap, 在調用plot_tree函數的時候, 直接指定fmap文件即可:

    plot_tree(fmap='xgb.fmap')

    調整清晰度需要使用plt.gcf()方法

    plot_tree(sklearn_model_new,fmap='xgb.fmap',num_trees=0)
    fig = plt.gcf()
    fig.set_size_inches(150, 100)
    plt.show()
    第一棵樹
    plot_tree(sklearn_model_new,fmap='xgb.fmap',num_trees=1)
    fig = plt.gcf()
    fig.set_size_inches(150, 100)
    plt.show()
    第二棵樹

    重頭戲分割線————手算

    先看看X_train第一棵樹僅以含糖率為分割點,對其排序,分割點為兩點間的均值

    0.186為何可以成為根節點呢?這個咱們待會兒再算。

    那我們就算一下,不過在此之前還要再復習一下損失函數 logloss:

    由于后面需要用到logloss的一階導數以及二階導數,這里先簡單推導一下。

    其中

    在一階導的基礎上再求一次有(其實就是sigmod函數求導)

    base_score初始值 0.5 ,我們計算每個樣本的一階導數值和二階導數值
    樣本的一階導數值:
    樣本的二階導數值:

    =2.5
    =-2.5
    =1.25
    =1.75

    計算最優的權重:

    所以:
    =-0.111111111
    =0.090909091

    tips:上述結果直接計算與圖中不符,這里要記得乘以學習率:0.1

    第一棵樹即為:

    回答開頭的問題,第一棵樹為何以含糖率的0.1856為根節點?必然是所有特征中此處分割的 gain 最大!看一下這個公式

    計算結果為5.0505,其他特征的gain小于它,原理類似這里就不挨個算了。

    另一個問題,為何分裂到此怎么就停了呢?
    XGBClassifier參數min_child_weight默認值 1 ,是葉子節點包含樣本的所有二階偏導數之和,代表子節點的權重閾值。它刻畫的是:對于一個葉子節點,當對它采取劃分之后,它的所有子節點的權重之和的閾值。如果它的所有子節點的權重之和小于該閾值,則該葉子節點不值得繼續分裂。

    本例中如再以0.344處或其他特征某處分裂則必有>1,所以就不分裂了。min_child_weight的值較大時,可以避免模型學習到局部的特殊樣本。本例如將其值改為0.2,就會發現還會分裂(如下圖):

    感興趣的同學可以試試,能算出-0.04和0.12嗎?

    還以min_child_weight默認值為 1,然后,生成第二棵樹,此處僅需按第一棵樹的預測結果更新base_score的值,注意:預測結果要經過sigmod映射,即當預測為0時,base_score更新為
    當預測為0時,base_score更新為

    進一步計算,,大家可以試一下,結果如圖。

    因為我們只有兩棵樹,特征選擇僅使用了含糖率,分裂了兩次,so,特征重要性為2

    plot_importance(sklearn_model_new)

    XGBoost網格搜索調參

    參數調整是機器學習中的一門暗藝術,模型的最優參數可以依賴于很多場景。所以要創建一個全面的指導是不可能的。XGBoost使用sklearn風格的接口,并使用網格搜索類GridSeachCV來調參,非常方便。gsCv.best_params_獲取最優參數,添加新的參數進來,然后再次GridSearchCV。

    也可以一把梭哈,把重要參數一次懟進去。

    gsCv = GridSearchCV(sklearn_model_new,
                       {'max_depth': [4,5,6],
                        'n_estimators': [5,10,20],
                       'learning_rate ': [0.05,0.1,0.3,0.5,0.7],
                        'min_child_weight':[0.1,0.2,0.5,1]
                       })
    gsCv.fit(X_train,y_train)
    print(gsCv.best_params_)

    {'learning_rate ': 0.05, 'max_depth': 4, 'min_child_weight': 0.1, 'n_estimators': 5} 以此參數重新訓練即可。

    也可以加一下老胡的微信
    圍觀朋友圈~~~

    推薦閱讀

    (點擊標題可跳轉閱讀)

    所以,機器學習和深度學習的區別是什么?
    機器學習避坑指南:訓練集/測試集分布一致性檢查
    機器學習深度研究:特征選擇中幾個重要的統計學概念

    老鐵,三連支持一下,好嗎?↓↓↓

      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 亚洲 制服 丝袜 无码| 永久免费无码成人网站| 国产成人8X人网站视频| 久久国产福利播放| 中文国产成人精品久久不卡| 国内老熟妇乱子伦视频| 又湿又紧又大又爽A视频国产| 99中文字幕精品国产| 欧美日韩一区二区综合| 欧美丰满熟妇xxxx性| 欧美亚洲日本国产综合在线美利坚| 色屁屁WWW影院免费观看入口| 重口SM一区二区三区视频| 国内精品久久久久影院蜜芽| 精品无码国产污污污免费| 中文字幕有码无码AV| 日韩深夜视频在线观看| 国内揄拍国内精品人妻| 亚洲中文字幕在线二页| 丰满人妻被黑人猛烈进入| 久久这里有精品国产电影网| 久久久久免费看成人影片| 爱性久久久久久久久| 久久精品国产久精国产| 日本久久99成人网站| 国产精品成人久久电影| 免费无码又爽又刺激网站| 日韩精品人妻中文字幕| 在厨房被C到高潮A毛片奶水| 久久综合九色综合欧洲98| 久久精品国产亚洲av麻豆软件| 久久SE精品一区精品二区| 免费午夜无码片在线观看影院| 亚洲AV无码一区二区三区人| 天天做日日做天天添天天欢公交车 | 国产果冻豆传媒麻婆精东| 无码专区 人妻系列 在线| 亚洲欧美日韩国产精品专区| 性无码专区无码| 毛片大全真人在线| 国产精品高清中文字幕|