機(jī)器學(xué)習(xí)(二):決策樹原理及代碼實(shí)現(xiàn)

決策樹(Decision Tree,又稱為判定樹)算法是機(jī)器學(xué)習(xí)中常見的一類算法,是一種以樹結(jié)構(gòu)(包括二叉樹和多叉樹)形式表達(dá)的預(yù)測(cè)分析模型。每個(gè)決策點(diǎn)實(shí)現(xiàn)一個(gè)具有離散輸出的測(cè)試函數(shù),記為分支沼沈。決策樹由結(jié)點(diǎn)和有向邊組成吠勘。結(jié)點(diǎn)有兩種類型: 內(nèi)部結(jié)點(diǎn)和葉節(jié)點(diǎn)若治。內(nèi)部節(jié)點(diǎn)表示一個(gè)特征或?qū)傩跃诱祝~節(jié)點(diǎn)表示一個(gè)類覆山。

一、決策樹的結(jié)構(gòu)

決策樹通常有三個(gè)步驟:特征選擇泥栖、決策樹生成簇宽、決策樹的修建。
特征選擇是建立決策樹之前十分重要的一步吧享。如果是隨機(jī)地選擇特征魏割,那么所建立決策樹的學(xué)習(xí)效率將會(huì)大打折扣。通常我們?cè)谶x擇特征時(shí)钢颂,會(huì)考慮到兩種不同的指標(biāo)钞它,分別為:信息增益和信息增益比。要想弄清楚這兩個(gè)概念殊鞭,我們就不得不提到信息論中的另一個(gè)十分常見的名詞 —— 熵遭垛。熵(Entropy)是表示隨機(jī)變量不確定性的度量。簡(jiǎn)單來講操灿,熵越大锯仪,隨機(jī)變量的不確定性就越大。而特征 A 對(duì)于某一訓(xùn)練集 D 的信息增益 g(D, A) 定義為集合 D 的熵 H(D) 與特征 A 在給定條件下 D 的熵 H(D/A) 之差趾盐。

二庶喜、決策樹分兩個(gè)階段

1、訓(xùn)練階段
從給定的訓(xùn)練數(shù)據(jù)集DB救鲤,構(gòu)造出一顆決策樹
class=DecisionTree(DB)
2久窟、分類階段
從根開始,按照決策樹的分類屬性逐層往下劃分蜒简,直到葉節(jié)點(diǎn)瘸羡,獲得概念(決策、分類)結(jié)果搓茬。
y=DecisionTree(x)

三犹赖、決策樹熵原理

熵:代表的是一個(gè)混亂程度
假設(shè)X和Y兩個(gè)事件相互獨(dú)立队他,則P(X,Y)=P(X)*P(Y),Log(XY)=Log(X)+Log(Y)
H(X),H(Y):事件發(fā)生的不確定性
P(幾率越大)->H(X)值越小->熵值越小

P(幾率越小)->H(X)值越大->熵值越大
0<P<1峻村,最終熵值是大于0的麸折。
尼基系數(shù)和熵值的定義類似,尼基系數(shù)越大粘昨,熵值也越大垢啼,說明越混亂。

四张肾、構(gòu)造決策樹根節(jié)點(diǎn)

決策樹的基本思想是隨著樹深度的增加芭析,節(jié)點(diǎn)的熵迅速地降低。熵降低的速度越快越好吞瞪,這樣我們構(gòu)造的決策樹是一顆高度最矮的決策樹(分支過多容易出現(xiàn)過擬合的現(xiàn)象)馁启,我們舉一個(gè)實(shí)例來看一下:

這是根據(jù)天氣狀況決定是否出去打球的數(shù)據(jù)
14行數(shù)據(jù),每行數(shù)據(jù)4個(gè)特征
在沒有給定任何天氣信息時(shí)芍秆,根據(jù)歷史數(shù)據(jù)惯疙,我們只知道新的一天打球的概率是9/14,不打的概率是5/14妖啥,此時(shí)的熵為:

接下來我們分別求出四個(gè)特征條件下的信息熵:
以outlook為例:
當(dāng)outlook=sunny時(shí)霉颠,2/5的概率打球,3/5的概率不打球荆虱,entropy=0.971
當(dāng)outlook=overcast時(shí)蒿偎,entropy=0
當(dāng)outlook=rainy時(shí),entropy=0.971
而根據(jù)歷史統(tǒng)計(jì)數(shù)據(jù)怀读,outlook取值為sunny酥郭、overcast、rainy的概率分別是5/14愿吹、4/14不从、5/14,所以當(dāng)已知變量outlook的值時(shí)犁跪,信息熵為:
5/14 x 0.971 + 4/14 x 0 + 5/14 x 0.971 = 0.693
這樣的話系統(tǒng)熵就從0.940下降到了0.693椿息,信息增益gain(outlook)為0.940-0.693=0.247
同樣可以計(jì)算出gain(temperture)=0.029,gain(humidity)=0.152坷衍,gain(windy)=0.048寝优。gain(outlook)最大(即outlook在第一步使系統(tǒng)的信息熵下降的最快),所以決策樹的根節(jié)點(diǎn)就去outlook枫耳。其余子節(jié)點(diǎn)的求法和根節(jié)點(diǎn)類似乏矾,所以決策樹算法是一個(gè)遞歸算法。
我們使用代碼實(shí)現(xiàn)一下:

from math import log
def createDataSet():
    #outlook:sunny:1,overcast:2,rainy:3
    #temperature:hot:1,mild:2,cool:3
    #humidity:high:1,normal:2
    #windy:false:1,true:2
    #play:no,yes
    dataSet=[
        [1,1,1,1,'no'],
        [1,1,1,2,'no'],
        [2,1,1,1,'yes'],
        [3,2,1,1,'yes'],
        [3,3,2,1,'yes'],
        [3,3,2,2,'no'],
        [2,3,2,2,'yes'],
        [1,2,1,1,'no'],
        [1,3,2,1,'yes'],
        [3,2,2,1,'yes'],
        [1,2,2,2,'yes'],
        [2,2,1,2,'yes'],
        [2,1,2,1,'yes'],
        [3,2,1,2,'no']
    ]
    labels=['outlook','temperature','humidity','windy','play']
    return dataSet,labels
def calcShannonEnt(dataSet):
    #返回?cái)?shù)據(jù)集行數(shù)
    numEntries=len(dataSet)
    #保存每個(gè)標(biāo)簽(label)出現(xiàn)次數(shù)的字典
    labelCounts={}
    #對(duì)每組特征向量進(jìn)行統(tǒng)計(jì)
    for featVec in dataSet:
        currentLabel=featVec[-1]#提取標(biāo)簽信息
        if currentLabel not in labelCounts.keys():#如果標(biāo)簽沒有放入統(tǒng)計(jì)次數(shù)
            labelCounts[currentLabel]=0
        labelCounts[currentLabel]+=1#label計(jì)數(shù)
    shannonEnt=0.0
    #計(jì)算經(jīng)驗(yàn)熵
    for key in labelCounts:
        prob=float(labelCounts[key])/numEntries #選擇該標(biāo)簽的概率
        shannonEnt-=prob*log(prob,2)            #利用公式計(jì)算
    return shannonEnt
def chooseBestFeatureToSplit(dataSet):
    #特征數(shù)量
    numFeatures = len(dataSet[0]) - 1
    #計(jì)數(shù)數(shù)據(jù)集的香農(nóng)熵
    baseEntropy = calcShannonEnt(dataSet)
    #信息增益
    bestInfoGain = 0.0
    #最優(yōu)特征的索引值
    bestFeature = -1
    #遍歷所有特征
    for i in range(numFeatures):
        # 獲取dataSet的第i個(gè)所有特征
        featList = [example[i] for example in dataSet]
        #創(chuàng)建set集合{},元素不可重復(fù)
        uniqueVals = set(featList)
        #經(jīng)驗(yàn)條件熵
        newEntropy = 0.0
        #計(jì)算信息增益
        for value in uniqueVals:
            #subDataSet劃分后的子集
            subDataSet = splitDataSet(dataSet, i, value)
            #計(jì)算子集的概率
            prob = len(subDataSet) / float(len(dataSet))
            #根據(jù)公式計(jì)算經(jīng)驗(yàn)條件熵
            newEntropy += prob * calcShannonEnt((subDataSet))
        #信息增益
        infoGain = baseEntropy - newEntropy
        #打印每個(gè)特征的信息增益
        print("第%d個(gè)特征的增益為%.3f" % (i, infoGain))
        #計(jì)算信息增益
        if (infoGain > bestInfoGain):
            #更新信息增益钻心,找到最大的信息增益
            bestInfoGain = infoGain
            #記錄信息增益最大的特征的索引值
            bestFeature = i
            #返回信息增益最大特征的索引值
    return bestFeature
def splitDataSet(dataSet,axis,value):
    retDataSet=[]
    for featVec in dataSet:
        if featVec[axis]==value:
            reducedFeatVec=featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet
if __name__=='__main__':
    dataSet,features=createDataSet()
    print(dataSet)
    print(calcShannonEnt(dataSet))
    print("最優(yōu)索引值:"+str(chooseBestFeatureToSplit(dataSet)))
實(shí)驗(yàn)結(jié)果

五凄硼、決策樹算法

ID3:信息增益
C4.5:信息增益率
CART:Gini系數(shù)

評(píng)價(jià)函數(shù):
其中t是葉子節(jié)點(diǎn)
ID3 算法通過遞歸的方式建立決策樹。建立時(shí)捷沸,從根節(jié)點(diǎn)開始摊沉,對(duì)節(jié)點(diǎn)計(jì)算每個(gè)獨(dú)立特征的信息增益,選擇信息增益最大的特征作為節(jié)點(diǎn)特征痒给。接下來说墨,對(duì)該特征施加判斷條件,建立子節(jié)點(diǎn)苍柏。然后針對(duì)子節(jié)點(diǎn)再此使用信息增益進(jìn)行判斷尼斧,直到所有特征的信息增益很小或者沒有特征時(shí)結(jié)束,這樣就逐步建立一顆完整的決策樹试吁。除了從信息增益演化而來的 ID3 算法突颊,還有一種常見的算法叫 C4.5。C4.5 算法同樣由 John Ross Quinlan 發(fā)明潘悼,但它使用了信息增益比來選擇特征,這被看成是 ID3 算法的一種改進(jìn)爬橡。C4.5算法能夠處理連續(xù)型的屬性治唤。首先將連續(xù)型屬性離散化,把連續(xù)型屬性的值分成不同的區(qū)間糙申,依據(jù)是比較各個(gè)分裂點(diǎn)Gian值得大小宾添,關(guān)于缺失數(shù)據(jù)在構(gòu)建決策樹時(shí),可以簡(jiǎn)單地忽略缺失數(shù)據(jù)柜裸,即在計(jì)算增益時(shí)缕陕,僅考慮具有屬性值的記錄。
ID3 和 C4.5 算法簡(jiǎn)單高效疙挺,但是他倆均存在一個(gè)缺點(diǎn)扛邑,那就是用“完美去造就了另一個(gè)不完美”。這兩個(gè)算法從信息增益和信息增益比開始铐然,對(duì)整個(gè)訓(xùn)練集進(jìn)行的分類蔬崩,擬合出來的模型針對(duì)該訓(xùn)練集的確是非常完美的。但是搀暑,這種完美就使得整體模型的復(fù)雜度較高沥阳,而對(duì)其他數(shù)據(jù)集的預(yù)測(cè)能力就降低了,也就是我們常說的過擬合而使得模型的泛化能力變?nèi)酢?br>

CART 算法本身就包含了決策樹的生成和修剪自点,并且可以同時(shí)被運(yùn)用到分類樹和回歸樹桐罕。這就是和 ID3 及 C4.5 之間的最大區(qū)別。
當(dāng)然,過擬合的問題也是可以解決的功炮,那就是對(duì)決策樹進(jìn)行修剪溅潜。

六、決策樹的剪枝策略

決策樹的修剪死宣,其實(shí)就是通過優(yōu)化損失函數(shù)來去掉不必要的一些分類特征伟恶,降低模型的整體復(fù)雜度。修剪的方式毅该,就是從樹的葉節(jié)點(diǎn)出發(fā)博秫,向上回縮,逐步判斷眶掌。如果去掉某一特征后挡育,整棵決策樹所對(duì)應(yīng)的損失函數(shù)更小,那就將該特征及帶有的分支剪掉朴爬。
剪枝策略分為兩種:
預(yù)剪枝:在構(gòu)建決策樹的過程時(shí)即寒,提前停止
后剪枝:決策樹構(gòu)建好后,然后才開始裁剪

七召噩、鳶尾花分類實(shí)驗(yàn)

數(shù)據(jù)集的介紹

鳶尾花數(shù)據(jù)集是機(jī)器學(xué)習(xí)領(lǐng)域一個(gè)非常經(jīng)典的分類數(shù)據(jù)集母赵。數(shù)據(jù)集名稱的準(zhǔn)確名稱為 Iris DataSet,總共包含 150 行數(shù)據(jù)。每一行數(shù)據(jù)由 4 個(gè)特征值及一個(gè)目標(biāo)值組成具滴。其中 4 個(gè)特征值分別為:萼片長(zhǎng)度凹嘲、萼片寬度、花瓣長(zhǎng)度构韵、花瓣寬度周蹭。該數(shù)據(jù)集可以直接從網(wǎng)上下載,網(wǎng)上有很多關(guān)于該數(shù)據(jù)集的介紹疲恢,如果找不到可以在下方留言或者私信我凶朗。

#導(dǎo)入數(shù)據(jù)集
import pandas as pd
iris_data = pd.read_csv('F:\\BaiduNetdiskDownload\\決策樹\\決策樹鳶尾花\\iris.data')
#指定列名
iris_data.columns = ['sepal_length_cm', 'sepal_width_cm', 'petal_length_cm', 'petal_width_cm', 'class']
iris_data.head()
#查看一下數(shù)據(jù)集的信息
iris_data.describe()#特征之間數(shù)據(jù)的分布

這里我們使用seaborn來進(jìn)行繪圖操作,它比matplotlib更方便直觀一點(diǎn):

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sb
sb.pairplot(iris_data.dropna(), hue='class')#不能有缺失值
plt.figure(figsize=(10, 10))
for column_index, column in enumerate(iris_data.columns):
    if column == 'class':
        continue
    plt.subplot(2, 2, column_index + 1)
    sb.violinplot(x='class', y=column, data=iris_data)#小提琴圖

接下來我們進(jìn)行數(shù)據(jù)集的劃分:

from sklearn.cross_validation import train_test_split
all_inputs = iris_data[['sepal_length_cm', 'sepal_width_cm',
                             'petal_length_cm', 'petal_width_cm']].values

all_classes = iris_data['class'].values

(training_inputs,
 testing_inputs,
 training_classes,
 testing_classes) = train_test_split(all_inputs, all_classes, train_size=0.75, random_state=1)

然后我們使用Scikit-learn包引入決策樹算法显拳,Scikit-learn(sklearn)是機(jī)器學(xué)習(xí)中常用的第三方模塊棚愤,對(duì)常用的機(jī)器學(xué)習(xí)方法進(jìn)行了封裝。但是DecisionTreeClassifier() 模型方法中也包含非常多的參數(shù)值杂数,這里列舉一下:

#使用決策樹算法進(jìn)行分析
from sklearn.tree import DecisionTreeClassifier
#  1.criterion  gini  or  entropy 基尼系數(shù)和熵值的選擇

#  2.splitter  best or random 前者是在所有特征中找最好的切分點(diǎn) 后者是在部分特征中(數(shù)據(jù)量大的時(shí)候)

#  3.max_features  None(所有)遇八,log2,sqrt耍休,N  特征小于50的時(shí)候一般使用所有的
#剪枝操作
#  4.max_depth  數(shù)據(jù)少或者特征少的時(shí)候可以不管這個(gè)值刃永,如果模型樣本量多,特征也多的情況下羊精,可以嘗試限制下
#要不要停止操作
#  5.min_samples_split  如果某節(jié)點(diǎn)的樣本數(shù)少于min_samples_split斯够,則不會(huì)繼續(xù)再嘗試選擇最優(yōu)特征來進(jìn)行劃分
#                       如果樣本量不大囚玫,不需要管這個(gè)值。如果樣本量數(shù)量級(jí)非常大读规,則推薦增大這個(gè)值抓督。

#  6.min_samples_leaf  這個(gè)值限制了葉子節(jié)點(diǎn)最少的樣本數(shù),如果某葉子節(jié)點(diǎn)數(shù)目小于樣本數(shù)束亏,則會(huì)和兄弟節(jié)點(diǎn)一起被
#                      剪枝铃在,如果樣本量不大,不需要管這個(gè)值碍遍,大些如10W可是嘗試下5

#  7.min_weight_fraction_leaf 這個(gè)值限制了葉子節(jié)點(diǎn)所有樣本權(quán)重和的最小值定铜,如果小于這個(gè)值,則會(huì)和兄弟節(jié)點(diǎn)一起
#                          被剪枝默認(rèn)是0怕敬,就是不考慮權(quán)重問題揣炕。一般來說,如果我們有較多樣本有缺失值东跪,
#                          或者分類樹樣本的分布類別偏差很大畸陡,就會(huì)引入樣本權(quán)重,這時(shí)我們就要注意這個(gè)值了虽填。

#  8.max_leaf_nodes 通過限制最大葉子節(jié)點(diǎn)數(shù)丁恭,可以防止過擬合,默認(rèn)是"None”斋日,即不限制最大的葉子節(jié)點(diǎn)數(shù)牲览。
#                   如果加了限制,算法會(huì)建立在最大葉子節(jié)點(diǎn)數(shù)內(nèi)最優(yōu)的決策樹桑驱。
#                   如果特征不多,可以不考慮這個(gè)值跛蛋,但是如果特征分成多的話熬的,可以加以限制
#                   具體的值可以通過交叉驗(yàn)證得到。

#  9.class_weight 指定樣本各類別的的權(quán)重赊级,主要是為了防止訓(xùn)練集某些類別的樣本過多
#                 導(dǎo)致訓(xùn)練的決策樹過于偏向這些類別押框。這里可以自己指定各個(gè)樣本的權(quán)重
#                 如果使用“balanced”,則算法會(huì)自己計(jì)算權(quán)重理逊,樣本量少的類別所對(duì)應(yīng)的樣本權(quán)重會(huì)高橡伞。

#  10.min_impurity_split 這個(gè)值限制了決策樹的增長(zhǎng),如果某節(jié)點(diǎn)的不純度
#                       (基尼系數(shù)晋被,信息增益兑徘,均方差,絕對(duì)差)小于這個(gè)閾值
#                       則該節(jié)點(diǎn)不再生成子節(jié)點(diǎn)羡洛。即為葉子節(jié)點(diǎn) 挂脑。
#定義一個(gè)決策樹的對(duì)象
decision_tree_classifier = DecisionTreeClassifier()
#訓(xùn)練模型
# Train the classifier on the training set
decision_tree_classifier.fit(training_inputs, training_classes)
#所得模型的準(zhǔn)確性
# Validate the classifier on the testing set using classification accuracy
decision_tree_classifier.score(testing_inputs, testing_classes)
準(zhǔn)確性
from sklearn.cross_validation import cross_val_score#交叉驗(yàn)證交叉驗(yàn)證用于評(píng)估模型的預(yù)測(cè)性能,尤其是訓(xùn)練好的模型在新數(shù)據(jù)上的表現(xiàn),可以在一定程度上減小過擬合崭闲。還可以從有限的數(shù)據(jù)中獲取盡可能多的有效信息肋联。
import numpy as np
decision_tree_classifier = DecisionTreeClassifier()

# cross_val_score returns a list of the scores, which we can visualize
# to get a reasonable estimate of our classifier's performance
cv_scores = cross_val_score(decision_tree_classifier, all_inputs, all_classes, cv=10)#cv:選擇每次測(cè)試折數(shù) 
print (cv_scores)
#kde=False
sb.distplot(cv_scores)
plt.title('Average score: {}'.format(np.mean(cv_scores)))

我們?cè)O(shè)置一下參數(shù),查看運(yùn)行結(jié)果:

decision_tree_classifier = DecisionTreeClassifier(max_depth=1)

cv_scores = cross_val_score(decision_tree_classifier, all_inputs, all_classes, cv=10)
print (cv_scores)
sb.distplot(cv_scores, kde=False)
plt.title('Average score: {}'.format(np.mean(cv_scores)))

我們使用GridSearchCV網(wǎng)格搜索進(jìn)行自動(dòng)調(diào)參刁俭,把參數(shù)輸進(jìn)去橄仍,能給出最優(yōu)化的結(jié)果和參數(shù):

from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import StratifiedKFold

decision_tree_classifier = DecisionTreeClassifier()

parameter_grid = {'max_depth': [1, 2, 3, 4, 5],
                  'max_features': [1, 2, 3, 4]}

cross_validation = StratifiedKFold(all_classes, n_folds=10)

grid_search = GridSearchCV(decision_tree_classifier,
                           param_grid=parameter_grid,
                           cv=cross_validation)

grid_search.fit(all_inputs, all_classes)
print('Best score: {}'.format(grid_search.best_score_))
print('Best parameters: {}'.format(grid_search.best_params_))
運(yùn)行結(jié)果

八、決策樹的優(yōu)缺點(diǎn)以及改進(jìn)

  • 優(yōu)點(diǎn):
    1牍戚、簡(jiǎn)單易理解和解釋侮繁,樹木可視化
    2、需要很少的數(shù)據(jù)準(zhǔn)備翘魄,其他技術(shù)通常需要數(shù)據(jù)歸一化
  • 缺點(diǎn):
    決策樹學(xué)習(xí)者可以創(chuàng)建不能很好的推廣數(shù)據(jù)的過于復(fù)雜的樹鼎天,這被稱為過擬合
  • 改進(jìn):
    1、剪枝cart算法(決策樹API當(dāng)中已經(jīng)實(shí)現(xiàn)暑竟,隨機(jī)森林參數(shù)調(diào)優(yōu)有相關(guān)介紹)
    2斋射、隨機(jī)森林

九、集成學(xué)習(xí)方法——隨機(jī)森林

1但荤、集成學(xué)習(xí)

集成學(xué)習(xí)童工建立幾個(gè)模型組合來解決單一預(yù)測(cè)問題罗岖。它的工作原理是生成多個(gè)分類器/模型,各自獨(dú)立的學(xué)習(xí)和做出預(yù)測(cè)腹躁,這些預(yù)測(cè)最后結(jié)合成單預(yù)測(cè)桑包,因此優(yōu)于任何一個(gè)單分類做出來的預(yù)測(cè)。

2纺非、隨機(jī)森林

在機(jī)器學(xué)習(xí)中哑了,隨機(jī)森林是一個(gè)包含多個(gè)決策樹的分類器,并且其輸出的類別是由個(gè)別樹輸出的類別的眾數(shù)而定烧颖。

  • 隨機(jī)森林建立多個(gè)決策樹的過程(N個(gè)樣本弱左,M個(gè)特征)
    1、隨機(jī)在N個(gè)樣本當(dāng)中選擇一個(gè)樣本炕淮,重復(fù)N次拆火,樣本有可能重復(fù)
    2、隨機(jī)在M個(gè)特征當(dāng)中選出m個(gè)特征(m<<M)建立決策樹
    3涂圆、采用bootstrap抽樣(隨機(jī)有放回的抽樣)
    為什么要隨機(jī)抽樣訓(xùn)練集:
    如果不隨機(jī)抽樣们镜,每棵樹的訓(xùn)練集都一樣,那么最終訓(xùn)練出的樹分類結(jié)果也是完全一樣的
    為什么要有放回的抽樣:
    如果不是有放回的抽樣润歉,那么每棵樹的訓(xùn)練樣本都是不同的模狭,都是沒有交集的,這樣每棵樹都是"有偏的"踩衩,都是絕對(duì)"片面的"(當(dāng)然這樣說可能不對(duì))胞皱,也就是說每棵樹訓(xùn)練出來都是有很大差異的邪意,而隨機(jī)森林最后分類取決于多棵樹(弱分類器)的投票表決。

3反砌、隨機(jī)森林分類器的API

由于隨機(jī)森林API的參數(shù)眾多雾鬼,這里我們就選擇部分常用的進(jìn)行介紹:
sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion='gini',max_depth=None,bootstrap=True,random_state=None)

參數(shù) 說明
n_estimators integer,optional(default=10)森林里的樹木數(shù)量120,200宴树,300策菜,500,800酒贬,1200
criteria string,可選(default="gini")分割特征的測(cè)量方法
max_depth integer或None,可選(默認(rèn)=無)樹的最大深度5又憨,8,15锭吨,25蠢莺,30
max_features 每個(gè)決策樹的最大特征數(shù)量,若max_features="auto"或者"sqrt",則'max_features=sqrt(n_features),若max_features="log2"則'max_features=log2(n_features)'零如,若max_features="None"則'max_features=n_features'
bootstrap boolean,optional(default = True)是否在構(gòu)建樹時(shí)使用放回抽樣

4躏将、案例分析

這里補(bǔ)充一點(diǎn),決策樹可視化問題考蕾,通過sklearn.tree.export_graphviz()可以將樹導(dǎo)出成DOT格式祸憋,然后使用graphviz工具可以將dot格式轉(zhuǎn)換成png或者jpg格式進(jìn)行查看dot -Tpng tree.dot -o tree.png

import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.tree import DecisionTreeClassifier,export_graphviz
def Decision():
    """
    決策樹預(yù)測(cè)泰坦尼克生死
    :return:
    """
    #讀取數(shù)據(jù)
    data = pd.read_csv('../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/titanic.csv')
    # print(data.columns.values)
    #處理數(shù)據(jù),找出特征值和目標(biāo)值
    x = data.loc[:,['sex','age','pclass']]
    y = data.loc[:,['survived']]

    #有缺失值肖卧,處理缺失值蚯窥,平均值填充
    x['age'].fillna(x['age'].mean(),inplace = True)

    #劃分訓(xùn)練集和測(cè)試集
    x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)

    #進(jìn)行字典特征的抽取,特征->類別->one_hot編碼(特征里面是類別,值的類型都不同塞帐,要進(jìn)行one_hot編碼)
    dict = DictVectorizer(sparse=False)

    x_train = dict.fit_transform(x_train.to_dict(orient="records"))

    x_test = dict.transform(x_test.to_dict(orient="records"))

    # 利用決策樹進(jìn)行分類
    dec = DecisionTreeClassifier(max_depth=5)

    dec.fit(x_train,y_train)

    #預(yù)測(cè)準(zhǔn)確率
    print("準(zhǔn)確率為:",dec.score(x_test,y_test))
    print(dict.get_feature_names())

    #導(dǎo)出樹的結(jié)構(gòu)
    export_graphviz(dec,out_file='../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/tree.dot',feature_names=['年齡','pclass','女性','男性'])
    return None


if __name__ == "__main__":
    Decision()

我們運(yùn)行一下之后拦赠,會(huì)在對(duì)應(yīng)的目錄下生成tree.dot

接下來我們安裝graphviz,我這里是在windows系統(tǒng)運(yùn)行的葵姥,先講一下windows的安裝方法荷鼠,首先在官網(wǎng)上下載
graphvizhttps://graphviz.gitlab.io/_pages/Download/Download_windows.html這種格式都可以,安裝完后添加到系統(tǒng)變量牌里,windows添加系統(tǒng)變臉我就不說了颊咬,直接把目錄加載到bin目錄下务甥,能看到dot.exe那個(gè)文件路徑牡辽。

添加到系統(tǒng)變量中后,打開dos命令行敞临,輸入
看到輸出版本號(hào)說明安裝成功态辛!

最后我們進(jìn)入tree.dot的文件中,打開dos命令行輸入挺尿,

這時(shí)文件下就會(huì)多出一個(gè)tree.png的圖片奏黑,我們打開就可以看到了炊邦。
這就是我們生成的決策樹。
接下來我們進(jìn)行決策樹的演練熟史,

import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.tree import DecisionTreeClassifier,export_graphviz
from sklearn.ensemble import RandomForestClassifier
def Decision():
    """
    決策樹預(yù)測(cè)泰坦尼克生死
    :return:
    """
    #讀取數(shù)據(jù)
    data = pd.read_csv('../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/titanic.csv')
    # print(data.columns.values)
    #處理數(shù)據(jù)馁害,找出特征值和目標(biāo)值
    x = data.loc[:,['sex','age','pclass']]
    y = data.loc[:,['survived']]

    #有缺失值,處理缺失值蹂匹,平均值填充
    x['age'].fillna(x['age'].mean(),inplace = True)

    #劃分訓(xùn)練集和測(cè)試集
    x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)

    #進(jìn)行字典特征的抽取,特征->類別->one_hot編碼(特征里面是類別碘菜,值的類型都不同,要進(jìn)行one_hot編碼)
    dict = DictVectorizer(sparse=False)

    x_train = dict.fit_transform(x_train.to_dict(orient="records"))

    x_test = dict.transform(x_test.to_dict(orient="records"))

    # 利用決策樹進(jìn)行分類
    # dec = DecisionTreeClassifier(max_depth=5)
    # 
    # dec.fit(x_train,y_train)
    # 
    # #預(yù)測(cè)準(zhǔn)確率
    # print("準(zhǔn)確率為:",dec.score(x_test,y_test))
    # print(dict.get_feature_names())
    # 
    # #導(dǎo)出樹的結(jié)構(gòu)
    # export_graphviz(dec,out_file='../../數(shù)據(jù)集/機(jī)器學(xué)習(xí)/分類算法/Titanic/tree.dot',feature_names=['年齡','pclass','女性','男性'])

    #隨機(jī)森林預(yù)測(cè)分類(超參數(shù)調(diào)優(yōu))
    rf = RandomForestClassifier()

    param = {"n_estimators":[120,200,300,500,800],"max_depth":[5,8,15,25,30]}

    #網(wǎng)格搜索與交叉驗(yàn)證
    gc = GridSearchCV(rf,param_grid=param,cv=5)

    gc.fit(x_train,y_train)

    #輸出準(zhǔn)確率
    print("準(zhǔn)確率為:",gc.score(x_test,y_test))

    print("選擇最好的模型是:",gc.best_estimator_)

    print("每次交叉驗(yàn)證的結(jié)果",gc.cv_results_)

    return None


if __name__ == "__main__":
    Decision()

最后得出當(dāng) n_estimators=500,max_depth=25模型最好限寞。

十忍啸、隨機(jī)森林算法的優(yōu)點(diǎn)

這里提一下,隨機(jī)森林算法幾乎沒有缺點(diǎn)履植,唯一的缺點(diǎn)是參數(shù)的選取

  • 在當(dāng)前所有算法中计雌,具有極好的準(zhǔn)確率
  • 能夠有效地運(yùn)行在大數(shù)據(jù)集上
  • 能夠處理具有高維特征的輸入樣本,而且不需要降維
  • 能夠評(píng)估各個(gè)特征在分類問題上的重要性

隨機(jī)森林的用法到這里就結(jié)束玫霎,有不明白的地方可以私信我凿滤。歡迎一起學(xué)習(xí),一起進(jìn)步鼠渺。

參考鏈接

1.《統(tǒng)計(jì)學(xué)習(xí)方法》鸭巴,李航,清華大學(xué)出版社
2.https://blog.csdn.net/oxuzhenyi/article/details/76427704
3.http://www.reibang.com/p/52b86c774b0b
4.https://blog.csdn.net/qq_36523839/article/details/80707678
5.b站視頻講解(up主:藍(lán)亞之舟)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拦盹,一起剝皮案震驚了整個(gè)濱河市鹃祖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌普舆,老刑警劉巖恬口,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異沼侣,居然都是意外死亡祖能,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門蛾洛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來养铸,“玉大人,你說我怎么就攤上這事轧膘〕” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵谎碍,是天一觀的道長(zhǎng)鳞滨。 經(jīng)常有香客問我,道長(zhǎng)蟆淀,這世上最難降的妖魔是什么拯啦? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任澡匪,我火速辦了婚禮,結(jié)果婚禮上褒链,老公的妹妹穿的比我還像新娘唁情。我一直安慰自己,他們只是感情好甫匹,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布荠瘪。 她就那樣靜靜地躺著,像睡著了一般赛惩。 火紅的嫁衣襯著肌膚如雪哀墓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天喷兼,我揣著相機(jī)與錄音篮绰,去河邊找鬼。 笑死季惯,一個(gè)胖子當(dāng)著我的面吹牛吠各,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勉抓,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼贾漏,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了藕筋?” 一聲冷哼從身側(cè)響起纵散,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隐圾,沒想到半個(gè)月后伍掀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡暇藏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年蜜笤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盐碱。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡把兔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瓮顽,到底是詐尸還是另有隱情县好,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布趣倾,位于F島的核電站聘惦,受9級(jí)特大地震影響某饰,放射性物質(zhì)發(fā)生泄漏儒恋。R本人自食惡果不足惜善绎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诫尽。 院中可真熱鬧禀酱,春花似錦、人聲如沸牧嫉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酣藻。三九已至曹洽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辽剧,已是汗流浹背送淆。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怕轿,地道東北人偷崩。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撞羽,于是被迫代替她去往敵國(guó)和親阐斜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容