決策樹 & 隨機森林

<機器學習筆記-05 >決策樹


關鍵詞:機器學習,決策樹

摘要:本文主要介紹了筆者對於決策樹原理的理解。


  1. 知識要點總結

    1. 掌握決策樹、分類器、積極/消極學習方法、集成學習的概念;

    2. 掌握構建決策樹、隨機森林的方法;

    3. 掌握熵、信息增益、基尼不純度的概念和計算方法;

    4. 掌握在python中使用基本數學、決策樹和隨機森林的方法;

  2. 概念理解:

    1. 決策樹:

      1. 是一種分類器;通過訓練數據構建決策樹,對未知數據進行分類;
      2. 構成:一個根結點(樣本全集)、若干內部結點(屬性測試)、若干葉結點(決策結果);
      3. 判定過程:輸入一組未知數據,從根結點出發,按照決策樹的判定測試序列,運行到葉結點輸出決策結果;
      4. 決策樹學習目的:產生泛化能力強(處理未見示例能力強)的決策樹;
      5. 積極學習方法(eager learner):先從訓練集建立一個與後面需求無關的模型,模型一旦建好後可以很快的預測出結果;消極學習方法(lazy learner):如KNN(k-Nearest Neighbor)有了訓練集數據的預測需求,纔會開始學習整個數據的特徵;不需要花時間訓練預測能力,但比積極學習方法預測慢;
    2. 熵(Entropy)

      1. 如何確定決策樹應該先測試哪個解釋變量?解決思路:較好的測試可以更大程度上降低分類的不確定度性
      2. 熵:度量信息的不確定性;以比特(bits)爲單位;完全確定的分類,其熵爲0比特;其公式爲

        H(x)=i=1nP(xi)logbP(xi)

        其中,n 是樣本的數量,P(xi) 是第i 個樣本的概率;b 一般取2或e 或10;前面加符號是爲了熵爲非負數;

      3. 舉例以方便理解:

        1. ##### 投擲硬幣一次,正反面概率各爲0.5,則硬幣投擲一次的結果變量熵爲

        H(x)=(0.5log20.5+0.5log20.5)=1.0
        1. ##### 投擲硬幣一次,正面概率0.8,反面概率0.2,則硬幣投擲一次的結果變量熵爲0.72;不確定性降低了,向另一種結果更加靠近;

        H(x)=(0.8log20.8+0.2log20.2)=0.72
        1. ##### 投擲硬幣一次,正面概率爲1.0,反面概率爲0,則硬幣投擲一次的結果變量熵爲0;結果不確定性度爲0;

        H(x)=(1.0log21.0+0.0log20.0)=0.0
    3. 信息增益(information gain)

      1. 如何評估哪一個變量最大程度地降低了分類的不確定性?
      2. 信息增益:父結點熵 H(T) 與子節點熵加權均值的差;應該選擇信息增益最大的解釋變量進行結點劃分;

        IG(T,a)=H(T)vval(s){xT|xa=v}|T|H(xT|xa=v)

        其中,xaval(s) 表示解釋變量a 的樣本x{xT|xa=v} 表示解釋變量a 的值等於v 樣本數量;H(xT|xa=v) 是解釋變量a的值等於v 的樣本熵;

    4. 基尼不純度(gini impurity):

      1. 在使用CART方法時,按照集合中子集標籤的概率分佈對集合中元素指定標籤,基尼不純度用來衡量被錯誤指定標籤的元素被隨機抽取的概率;(翻譯自wikipedia-decision tree);
      2. 計算公式:假設集合共有j 個子集,t 是結點樣本的子集,其中P(i|t) 表示從結點子集中選擇一個類型i 的概率;

        Gini(t)=i=1jP(i|t)(1P(i|t))=i=1jP(i|t)i=1jP(i|t)2=1i=1jP(i|t)2
      3. 集合中只有一類,基尼不純度爲0;美國類型概率相同時,基尼不純度最大,爲

        Ginimax=11n
      4. 舉例方便理解:
        1. 投擲硬幣,正反面各0.5概率,則硬幣投擲一次的不純度爲

          Gini(t)=20.5(10.5)=1(0.52+0.52)=0.5
        2. 投擲硬幣,正面概率爲0.8,反面概率爲0.2,則硬幣投擲一次的不純度爲

          Gini(t)=20.8(10.8)=1(0.82+0.22)=0.32
        3. 投擲硬幣,正面概率爲1,反面概率爲0,則硬幣投擲一次的不純度爲

          Gini(t)=21.0(11.0)=1(1.02+0.02)=0
    5. 決策樹構建的基本步驟[參考資料4-李伯韜-決策樹學習筆記整理]

      1. 開始,所有記錄看做一個結點;
      2. 遍歷每個變量的每一種分割方式(如信息增益最大、基尼不純度差最大),找到最好的分割點;
      3. 分割成兩個結點N1N2
      4. N1N2 分別繼續執行2-3步,直到每個結點足夠純爲止;
    6. 隨機森林(random forest)

      1. 集成學習(ensemble learning)方法:將一堆模型組合起來使用,比單個模型可以取得更好地效果;
      2. 隨機森林(random foreset):一種集成學習方法,用隨機選擇訓練集解釋變量的子集進行訓練,獲取一系列決策樹集合的方法;
      3. 隨機森林通常用決策樹集合裏每個決策樹的預測結果的均值或者衆數作爲最終預測值;
      4. 優勢:相比單一決策樹,不太會受到擬合過度的影響;每個決策樹只訓練一部分解釋變量數據,不會記憶訓練集的全部噪聲;
  3. Python用法

    1. 基本用法-Math

      1. 基本數學運算(加、減、乘、除、取餘、絕對值、冪),不需要調用math
      2. 數學運算(三角函數、反三角函數、指數、對數),需要調用math
        import math
        
        print math.sin(10)       # sine
        print math.cos(10)       # cosine
        print math.tan(10)       # tangent 
        
        print math.asin(10)      # arc sine
        print math.acos(10)      # arc cosine
        print math.atan(10)      # arc tangent
        
        print math.sinh(10)      # hyperbolic sine    
        print math.cosh(10)      # hyperbolic cosine
        print math.tanh(10)      # hyperbolic tangent
        
        print math.pow(2, 4)     # 2 raised to 4
        print math.exp(4)        # e ^ 4
        print math.sqrt(10)      # square root
        print math.pow(5, 1/3.0) # cubic root of 5
        print math.log(3)        # ln; natural logarithm
        print math.log(100, 10)  # base 10
        
        print math.ceil(2.3)    # ceiling
        print math.floor(2.7)   # floor
        
        print math.pi
        print math.e
      3. 對一組數給定1或者0
        y=[1 if e=='ad.' else 0 for e in response_variable_columns]
    2. Pandas庫

      1. .loc使用標籤選取數據;df.loc的第一個參數是行標籤,第二個參數爲列標籤(可選參數,默認爲所有列標籤),兩個參數既可以是列表也可以是單個字符,如果兩個參數都爲列表則返回的是DataFrame,否則,則爲Series。[來自參考資料8]
        df.loc[行標籤,列標籤]
        df.loc['a':'b']#選取ab兩行數據
        df.loc[:,'one']#選取one列的數據
  4. Python實例代碼整理-決策樹和隨機森林

    1. 讀取數據,並整理數據(將解釋變量和響應變量分開,數據替代,劃分成測試集和訓練集)

      import pandas as pd
      
      df=pd.read_csv('Desktop/ad-dataset/ad.data',header=None,low_memory=False)
      
      explanatory_variable_columns=set(df.columns.values)
      response_variable_column=df[len(df.columns.values)-1]
      explanatory_variable_columns.remove(len(df.columns.values)-1) #得到解釋變量所在的列數
      
      y=[1 if e=='ad.' else 0 for e in response_variable_column]
      X=df.loc[:,list(explanatory_variable_columns)]
      X.replace(to_replace=' *\?',value=-1,regex=True,inplace=True)
      
      from sklearn.cross_validation import train_test_split
      X_train,X_test,y_train,y_test=train_test_split(X,y) 
    2. 構建pipelineGridSearchCV-決策樹

      from sklearn.pipeline import Pipeline
      from sklearn.tree import DecisionTreeClassifier
      from sklearn.grid_search import GridSearchCV
      
      pipeline_Tree=Pipeline([('clf',DecisionTreeClassifier(criterion='entropy'))])
      paras_Tree={'clf__max_depth':(150,155,160),'clf__min_samples_split':(1,2,3),'clf__min_samples_leaf':(1,2,3)}
      grid_search_Tree=GridSearchCV(pipeline_Tree,paras_Tree,n_jobs=-1,verbose=1,scoring='f1')
      grid_search_Tree.fit(X_train,y_train)
    3. 結果輸出-決策樹

      from sklearn.metrics import classification_report
      print('best result: %0.3f' % grid_search_Tree.best_score_) #best result: 0.890
      
      best_paras_Tree=grid_search_Tree.best_estimator_.get_params()
      for param_name in sorted(paras_Tree.keys()):
        print('\t%s: %r' %(param_name,best_paras_Tree[param_name]))
      '''
            clf__max_depth: 150
            clf__min_samples_leaf: 3
            clf__min_samples_split: 1
      '''
      
      predictions_Tree=grid_search_Tree.predict(X_test)
      print(classification_report(y_test,predictions_Tree))
      '''
                 precision    recall  f1-score   support
      
              0       0.97      0.98      0.98       708
              1       0.88      0.81      0.85       112
      
      avg / total       0.96      0.96      0.96       820
      '''
    4. 構建pipelineGridSearchCV-隨機森林

      from sklearn.pipeline import Pipeline
      from sklearn.ensemble import RandomForestClassifier
      from sklearn.grid_search import GridSearchCV
      
      pipeline_Forest=Pipeline([('clf',RandomForestClassifier(criterion='entropy'))])
      paras_Forest={'clf__n_estimators':(5,10,20,50),'clf__max_depth':(50,150,250),'clf__min_samples_split':(1,2,3),'clf__min_samples_leaf':(1,2,3)}
      grid_search_Forest=GridSearchCV(pipeline_Forest,paras_Forest,n_jobs=-1,verbose=1,scoring='f1')
      grid_search_Forest.fit(X_train,y_train)
    5. 結果輸出-隨機森林

      from sklearn.metrics import classification_report
      print('best result: %0.3f' % grid_search_Forest.best_score_)
      
      best_paras_Forest=grid_search_Forest.best_estimator_.get_params()
      for param_name in sorted(paras_Forest.keys()):
        print('\t%s: %r' %(param_name,best_paras_Forest[param_name]))
      predictions_Forest=grid_search_Forest.predict(X_test)
      print(classification_report(y_test,predictions_Forest))
      
      '''
      best result: 0.922
            clf__max_depth: 50
            clf__min_samples_leaf: 1
            clf__min_samples_split: 3
            clf__n_estimators: 50
                 precision    recall  f1-score   support
      
              0       0.98      0.99      0.99       709
              1       0.96      0.87      0.92       111
      
      avg / total       0.98      0.98      0.98       820
      '''
  5. 參考資料:

    1. “Mastering Machine Learning With scikit-learn”

    2. Wikipedia-Decision tree learning

    3. 周志華-《機器學習

    4. 李伯韜- 決策樹學習筆記整理

    5. 華山大師兄- 決策樹算法總結

    6. July-從決策樹學習談到貝葉斯分類算法、EM、HMM

    7. tornadomeet-一些知識點的初步理解_7(隨機森林,ing…)

    8. pandas.loc()用法

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