機器學習一(決策樹和隨機森林)


 

前言

本文試圖提綱挈領的對決策樹和隨機森林的原理及應用做以分析

決策樹

算法偽代碼

def 創建決策樹:
    
    if (數據集中所有樣本分類一致): #或者其他終止條件
        創建攜帶類標簽的葉子節點
    else:
        尋找划分數據集的最好特征
        根據最好特征划分數據集
        for 每個划分的數據集:
            創建決策子樹(遞歸)

注意算法要采用遞歸的方法

依據選取划分數據集特征的方法,有三種常用方法:

ID3:信息增益

 

C4.5:信息增益率

 

CART:基尼系數

對於連續特征:

比如m個樣本的連續特征A有m個,從小到大排列為a1,a2,...,am,則CART算法取相鄰兩樣本值的中位數,一共取得m-1個划分點,其中第i個划分點TiTi表示為:Ti=(ai+ai+1)/2。對於這m-1個點,分別計算以該點作為二元分類點時的基尼系數。選擇基尼系數最小的點作為該連續特征的二元離散分類點,這樣我們就做到了連續特征的離散化。要注意的是,與離散屬性不同的是,如果當前節點為連續屬性,則該屬性后面還可以參與子節點的產生選擇過程。

過擬合問題-——剪枝

 過多的枝葉會導致算法的過擬合,所以常使用減枝的方法防止過擬合:常用的剪枝方法有前置法和后置法,前置法指的是在要構建決策樹時,依據終止條件確定是否提前終止;后置法指構建好決策樹后,再依據條件確定是否用單一節點代替子樹。

回歸問題

一般采用均方誤差作為評價特征的標准

隨機森林

bootstrap方法:從樣本集進行有放回的重采樣。

隨機森林步驟:

1.  樣本的隨機:從樣本集中用Bootstrap隨機選取n個樣本

2.  特征的隨機:從所有屬性中隨機選取K個屬性,選擇最佳分割屬性作為節點建立CART決策樹

3.  重復以上兩步m次,即建立了m棵CART決策樹

4.  這m個CART形成隨機森林,通過投票表決結果,決定數據屬於哪一類(投票機制有一票否決制、少數服從多數、加權多數)

參考:https://www.cnblogs.com/fionacai/p/5894142.html

sklearn.tree.DecisionTreeClassifier

class sklearn.tree.DecisionTreeClassifier(criterion=’gini’splitter=’best’max_depth=Nonemin_samples_split=2min_samples_leaf=1min_weight_fraction_leaf=0.0max_features=Nonerandom_state=Nonemax_leaf_nodes=Nonemin_impurity_decrease=0.0min_impurity_split=Noneclass_weight=Nonepresort=False)

 Parameters: criterion='gini' or 'entropy'

                    max_depth 設置樹的最大深度 默認為‘None’

                    min_sample_split 分割的最小樣本數 默認為2

                    詳細內容的中文說明可以參考  https://www.cnblogs.com/pinard/p/6056319.html

 

sklearn.tree.DecisionTreeRegressor

 Parameters: criterion='mse'  還可以使用‘friedman_mse’或者'mae'

                     max_depth 設置樹的最大深度 默認為‘None’

 

sklearn.ensemble.RandomForestClassifier

Parameters: n_estimator=10 生成決策樹的個數

                   criterion='gini' or 'entropy'

 

應用舉例

使用隨機森林進行回歸的例子

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor


N=100
x = np.random.rand(N) * 6 - 3 
x.sort()
y=0.1*x**3+np.exp(-x*x/2)+ np.random.randn(N) * 0.2  #3次函數+高斯函數+噪聲
x = x.reshape(-1, 1)
x_bar=np.linspace(-3,3,50).reshape(-1,1)
y_bar=0.1*x_bar**3+np.exp(-x_bar*x_bar/2)
plt.plot(x,y,'r.')
plt.plot(x_bar,y_bar)
plt.show()

plt.plot(x,y,'r.')
x_test=np.linspace(-3,3,50).reshape(-1,1)
dt = DecisionTreeRegressor(criterion='mse')
depth=[3,6,18]
color='rgy'
for d,c in zip(depth,color):
    dt.set_params(max_depth=d)
    dt.fit(x, y)
    y_test = dt.predict(x_test)
    plt.plot(x_test,y_test,'-',color=c, linewidth=2, label='Depth=%d' % d)

plt.legend(loc='upper left')
plt.xlabel(u'X')
plt.ylabel(u'Y')
plt.grid(b=True)
plt.show()

   圖1

 

 

  圖2

對比圖1中的真實曲線和圖2中三條擬合折線可以發現,圖二中的折現較好的擬合了原始曲線,如果單純使用一次特征的線性回歸肯定是達不到這樣的效果的,其次,我們可以看到當樹最大深度為3時,折線段較少,細小的彎曲無法體現,而當深度達到18時,折線波折又過多,有過擬合的嫌疑,當深度為6時,相對較好,因此,我們推斷樹的深度在擬合過程中起到了重要作用

 

數據集 Adult

字段名

含義

類型

age

年齡

Double

workclass

工作類型

string

fnlwgt

序號

string

education

教育程度*

string

education_num

受教育時間

double

maritial_status

婚姻狀況*

string

occupation

職業*

string

relationship

關系*

string

race

種族*

string

sex

性別*

string

capital_gain

資本收益

string

capital_loss

資本損失

string

hours_per_week

每周工作小時數

double

native_country

國籍

string

income

收入

string

表1

基於上面特征,預測收入是否大於50K,我們用決策樹和隨機森林來解決上述問題。

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder

column_names = 'age', 'workclass', 'fnlwgt', 'education', 'education-num', 'marital-status', 'occupation', \
                   'relationship', 'race', 'sex', 'capital-gain', 'capital-loss', 'hours-per-week',\
                   'native-country', 'income'  #不加括號為元組
data = pd.read_csv('adult.data', header=None, names=column_names)                  
data.isnull().any().any() #是否存在null
for name in column_names:
    data[name]=LabelEncoder().fit_transform(data[name])   #自動轉換非數字列為數字
x = data[data.columns[:-1]]
y = data[data.columns[-1]]    
x_train, x_valid, y_train, y_valid = train_test_split(x, y, test_size=0.3, random_state=0)
DT = DecisionTreeClassifier(criterion='gini',max_depth=10,min_samples_split=5)
RF = RandomForestClassifier(criterion='gini', max_depth=10, min_samples_split=5,n_estimators=20)
LR= LogisticRegression()
models=[DT,RF,LR]
for model in models:
    model.fit(x_train,y_train)
    y_pre=model.predict(x_valid)
    print('驗證集准確率:', accuracy_score(y_pre, y_valid))

運行結果為:

驗證集准確率: 0.852287849319
驗證集准確率: 0.858429726686
驗證集准確率: 0.805507216706

對比結果,在隨機森林與決策樹選取相似的參數時,隨機森林的結果略好於決策樹,logistic回歸結果最差,但注意這里logistic回歸沒有調參。

附:Adult數據集 https://pan.baidu.com/s/1vTMN9Yp6VPndezUR1UtYtw

 

致謝:本文基於小象學院鄒博老師機器學習課程,部分代碼參考該課程,特此感謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM