主頁 > 知識(shí)庫 > Python機(jī)器學(xué)習(xí)之決策樹和隨機(jī)森林

Python機(jī)器學(xué)習(xí)之決策樹和隨機(jī)森林

熱門標(biāo)簽:銀行業(yè)務(wù) 鐵路電話系統(tǒng) 美圖手機(jī) 服務(wù)器配置 網(wǎng)站文章發(fā)布 檢查注冊(cè)表項(xiàng) 呼叫中心市場(chǎng)需求 智能手機(jī)

什么是決策樹

決策樹屬于經(jīng)典的十大數(shù)據(jù)挖掘算法之一,是通過類似于流程圖的數(shù)形結(jié)構(gòu),其規(guī)則就是iIF…THEN…的思想.,可以用于數(shù)值型因變量的預(yù)測(cè)或離散型因變量的分類,該算法簡(jiǎn)單直觀,通俗易懂,不需要研究者掌握任何領(lǐng)域的知識(shí)或者復(fù)雜的數(shù)學(xué)邏輯,而且算法的輸出結(jié)果具有很強(qiáng)的解釋性,通常情況下決策術(shù)用作分類器會(huì)有很好的預(yù)測(cè)準(zhǔn)確率,目前越來越多的行業(yè),將此算法用于實(shí)際問題的解決。

決策樹組成


這就是一個(gè)典型的決策樹,其呈現(xiàn)字頂向下生長(zhǎng)的過程,通過樹形結(jié)構(gòu)可以將數(shù)據(jù)中的隱藏的規(guī)律,直觀的表現(xiàn)出來,圖中深色的橢圓表示樹的根節(jié)點(diǎn)檢測(cè)的為橢圓表示樹的中間節(jié)點(diǎn),方框表示數(shù)的葉子節(jié)點(diǎn),對(duì)于所有非葉子節(jié)點(diǎn)來說都是用于條件判斷,葉節(jié)點(diǎn)則表示最終儲(chǔ)存的分類結(jié)果。

  • 根節(jié)點(diǎn):沒有進(jìn)邊,有出邊。包含最初的,針對(duì)特征的提問。
  • 中間節(jié)點(diǎn):既有進(jìn)邊也有出邊,進(jìn)邊只有一條,出邊可以有很多條。都是針對(duì)特征的提問。
  • 葉子節(jié)點(diǎn):有進(jìn)邊,沒有出邊,每個(gè)葉子節(jié)點(diǎn)都是一個(gè)類別標(biāo)簽。
  • 子節(jié)點(diǎn)和父節(jié)點(diǎn):在兩個(gè)相連的節(jié)點(diǎn)中,更接近根節(jié)點(diǎn)的是父節(jié)點(diǎn),另一個(gè)是子節(jié)點(diǎn)。

節(jié)點(diǎn)的確定方法

那么對(duì)于所有的非葉子節(jié)點(diǎn)的字段的選擇,可以直接決定我們分類結(jié)果的好和壞,那么如何使這些非葉子節(jié)點(diǎn)分類使結(jié)果更好和效率更高,也就是我們所說的純凈度,對(duì)于純凈度的衡量,我們有三個(gè)衡量指標(biāo)信息增益,信息增益率和基尼系數(shù)。

  • 對(duì)于信息增益來說,就是在我們分類的過程中,會(huì)對(duì)每一種分類條件的結(jié)果都會(huì)進(jìn)行信息增益量的的計(jì)算。然后通過信息增益的比較取出最大的信息增益對(duì)應(yīng)的分類條件。也就是說對(duì)于信息增益值最大的量就是我們尋找的最佳分類條件。關(guān)于信息增益值是怎么計(jì)算得出的,這里就不做過多的講解,因?yàn)樗枰诖罅康臄?shù)學(xué)計(jì)算和概率知識(shí)。)輸入”entropy“,使用信息熵(Entropy)
  • 在計(jì)算信息增益的過程中,可能會(huì)受到數(shù)據(jù)集類別效果不同的值過多,所以會(huì)造成信息增益的計(jì)算結(jié)果將會(huì)更大,但是有時(shí)候并不能夠真正體現(xiàn)我們數(shù)據(jù)集的分類效果,所以這里引入信息增益率來對(duì)于信息增益值進(jìn)行一定程度的懲罰,簡(jiǎn)單的理解就是將信息增益值除以信息量。
  • 決策樹中的信息增益率和信息增益指標(biāo)實(shí)現(xiàn)根節(jié)點(diǎn)和中間節(jié)點(diǎn)的選擇,只能針對(duì)離散型隨機(jī)變量進(jìn)行分類,對(duì)于連續(xù)性的因變量就束手無策,為了能夠讓決策數(shù)預(yù)測(cè)連續(xù)性的因變量,所以就引入了基尼系數(shù)指標(biāo)進(jìn)行字段選擇特征。輸入”gini“,使用基尼系數(shù)(Gini Impurity)

比起基尼系數(shù),信息熵對(duì)不純度更加敏感,對(duì)不純度的懲罰最強(qiáng)。但是在實(shí)際使用中,信息熵和基尼系數(shù)的效果基本相同。信息熵的計(jì)算比基尼系數(shù)緩慢一些,因?yàn)榛嵯禂?shù)的計(jì)算不涉及對(duì)數(shù)。另外,因?yàn)樾畔㈧貙?duì)不純度更加敏感,所以信息熵作為指標(biāo)時(shí),決策樹的生長(zhǎng)會(huì)更加“精細(xì)”,因此對(duì)于高維數(shù)據(jù)或者噪音很多的數(shù)據(jù),信息熵很容易過擬合,基尼系數(shù)在這種情況下效果往往比較好。

決策樹基本流程


他會(huì)循環(huán)次過程,直到?jīng)]有更多的特征可用,或整體的不純度指標(biāo)已經(jīng)最優(yōu),決策樹就會(huì)停止生長(zhǎng)。但是在建模的過程中可能會(huì)由于這種高精度的訓(xùn)練,使得模型在訓(xùn)練基礎(chǔ)上有很高的預(yù)測(cè)精度,但是在測(cè)試集上效果并不夠理想,為了解決過擬合的問題,通常會(huì)對(duì)于決策樹進(jìn)行剪枝操作。
對(duì)于決策樹的剪枝操作有三種:誤差降低剪枝法,悲觀剪枝法,代價(jià)復(fù)雜度剪枝法,但是在這里我們只涉及sklearn中,給我們提供的限制決策樹生長(zhǎng)的參數(shù)。

決策樹的常用參數(shù)

DecisionTreeClassifier(criterion="gini"
								# criterion用于指定選擇節(jié)點(diǎn)字段的評(píng)價(jià)指標(biāo)。對(duì)于分類決策樹默認(rèn)gini,表示采用基尼系數(shù)指標(biāo)進(jìn)行葉子節(jié)點(diǎn)的最佳選擇??捎小癳ntropy”,但是容易過擬合,用于擬合不足
								# 對(duì)于回歸決策數(shù),默認(rèn)“mse”,表示均方誤差選擇節(jié)點(diǎn)的最佳分割手段。
                                ,random_state=None
                                # 用于指定隨機(jī)數(shù)生成器的種子,默認(rèn)None表示使用默認(rèn)的隨機(jī)數(shù)生成器。
                                ,splitter="best"
                                # 用于指定節(jié)點(diǎn)中的分割點(diǎn)的選擇方法,默認(rèn)best表示從所有的分割點(diǎn)中選出最佳分割點(diǎn),
                                # 也可以是random,表示隨機(jī)選擇分割點(diǎn)
                                
                                #以下參數(shù)均為防止過擬合
                                ,max_depth=None
                                # 用于指定決策樹的最大深度,默認(rèn)None,表示樹的生長(zhǎng)過程中對(duì)于深度不做任何限制。
                                ,min_samples_leaf=1
                                # 用于指定葉節(jié)點(diǎn)的最小樣本量默認(rèn)為1。
                                ,min_samples_split=2
                                # 用于指定根節(jié)點(diǎn)或中間節(jié)點(diǎn)能夠繼續(xù)分割的最小樣本量默認(rèn)為2。
                                ,max_features=None
                                # 用于指定決策樹包含的最多分隔字段數(shù),默認(rèn)None表示分割時(shí)使用所有的字段。如果為具體的整數(shù),則考慮使用對(duì)應(yīng)的分割手段數(shù),如果為0~1的浮點(diǎn)數(shù),則考慮對(duì)于對(duì)應(yīng)百分比的字段個(gè)數(shù)。
                                ,min_impurity_decrease=0
                                # 用于指定節(jié)點(diǎn)是否繼續(xù)分割的最小不純度值,默認(rèn)為0
                                ,class_weight=None
                                # 用于指定因變量中類別之間的權(quán)重。默認(rèn)None表示每個(gè)類別的權(quán)重都相同。
                                )

代碼實(shí)現(xiàn)決策樹之分類樹

import pandas as pd
from sklearn import tree
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_wine
import graphviz
# 實(shí)例化數(shù)據(jù)集,為字典格式
wine=load_wine()
datatarget=pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)
# 通過數(shù)據(jù)集的數(shù)據(jù)和標(biāo)簽進(jìn)行訓(xùn)練和測(cè)試集的分類。
xtrain,xtest,ytrain,ytest=train_test_split(wine.data # 數(shù)據(jù)集的數(shù)據(jù)。
											,wine.target# 數(shù)據(jù)集標(biāo)簽。
											,test_size=0.3#表示訓(xùn)練集為70%測(cè)試集為30%。
											)
								
# 創(chuàng)建一個(gè)樹的模型。			
clf=tree.DecisionTreeClassifier(criterion="gini") # 這里只使用了基尼系數(shù)作為參數(shù),其他沒有暫時(shí)使用
# 將訓(xùn)練集數(shù)據(jù)放在模型中進(jìn)行訓(xùn)練,clf就是我們訓(xùn)練好的模型,可以用來進(jìn)行測(cè)試劑的決策。
clf=clf.fit(xtrain,ytrain)

# 那么對(duì)于我們訓(xùn)練好的模型來說,怎么樣才能夠說明他是一個(gè)比較好的模型,那么我們就要引入模型中的一個(gè)函數(shù)score進(jìn)行模型打分
clf.score(xtest,ytest)#測(cè)試集打分
# 也可以使用交叉驗(yàn)證的方式,對(duì)于數(shù)據(jù)進(jìn)行評(píng)估更具有穩(wěn)定性。
cross_val_score(clf # 填入想要打分的模型。
				,wine.data# 打分的數(shù)據(jù)集
				,wine.target# 用于打分的標(biāo)簽。
				,cv=10# 交叉驗(yàn)證的次數(shù)
				#,scoring="neg_mean_squared_error"
		#只有在回歸中有該參數(shù),表示以負(fù)均方誤差輸出分?jǐn)?shù)
		).mean()

# 將決策樹以樹的形式展現(xiàn)出來
dot=tree.export_graphviz(clf
                         #,feature_names    #特征名
                         #,class_names  #結(jié)果名
                         ,filled=True#顏色自動(dòng)填充
                         ,rounded=True)#弧線邊界
graph=graphviz.Source(dot)

# 模型特征重要性指標(biāo)
clf.feature_importances_
#[*zip(wine.feature_name,clf.feature_importances_)]特征名和重要性結(jié)合

#apply返回每個(gè)測(cè)試樣本所在的葉子節(jié)點(diǎn)的索引
clf.apply(Xtest)
#predict返回每個(gè)測(cè)試樣本的分類/回歸結(jié)果
clf.predict(Xtest)

決策樹不同max_depth的學(xué)習(xí)曲線

from sklearn import tree
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_wine
import matplotlib.pyplot as plt、

wine=load_wine()
xtrain,xtest,ytrain,ytest=train_test_split(wine.data,wine.target,test_size=0.3)
trainscore=[]
testscore=[]
for i in range(10):
    clf=tree.DecisionTreeClassifier(criterion="gini"
                                    ,random_state=0
                                    ,max_depth=i+1
                                    ,min_samples_split=5
                                    ,max_features=5
                                    ).fit(xtrain,ytrain)

	# 下面這這兩句代碼本質(zhì)上結(jié)果是一樣的。第2種比較穩(wěn)定,但是費(fèi)時(shí)間
    once1=clf.score(xtrain,ytrain)
    once2=cross_val_score(clf,wine.data,wine.target,cv=10).mean()#也可用clf.score(xtest,ytest)

    trainscore.append(once1)
    testscore.append(once2)

#畫圖像
plt.plot(range(1,11),trainscore,color="red",label="train")
plt.plot(range(1,11),testscore,color="blue",label="test")
#顯示范圍
plt.xticks(range(1,11))
plt.legend()
plt.show()

result:


一般情況下,隨著max_depth的升高訓(xùn)練集和測(cè)試集得分就相對(duì)越高,但是由于紅酒數(shù)據(jù)集的數(shù)據(jù)量比較少,并沒有特別明顯的體現(xiàn)出來。但是我們依舊可以看出:在最大深度為4的時(shí)候到達(dá)了測(cè)試級(jí)的效果巔峰。

網(wǎng)格搜索在分類樹上的應(yīng)用

我們發(fā)現(xiàn)對(duì)于這個(gè)模型的參數(shù)比較多,如果我們想要得到一個(gè)相對(duì)來說分?jǐn)?shù)比較高的效果比較好的模型的話,我們需要對(duì)于每一個(gè)參數(shù)都要進(jìn)行不斷的循環(huán)遍歷,最后才能夠得出最佳答案。但是這對(duì)于我們?nèi)藶榈膶?shí)現(xiàn)來說比較困難,所以我們有了這樣一個(gè)工具:網(wǎng)格搜索可以自動(dòng)實(shí)現(xiàn)最佳效果的各種參數(shù)的確定。(但是比較費(fèi)時(shí)間)

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_wine
from sklearn.model_selection import GridSearchCV # 網(wǎng)格搜索的導(dǎo)入
wine = load_wine()
xtrain, xtest, ytrain, ytest = train_test_split(wine.data, wine.target, test_size=0.3)
clf = DecisionTreeClassifier(random_state=0)  # 確定random_state,就會(huì)在以后多次運(yùn)行的情況下結(jié)果相同

# parameters為網(wǎng)格搜索的主要參數(shù),它是以字典的形式存在。鍵為指定模型的參數(shù)名稱,值為參數(shù)列表
parameters = {"criterion": ["gini", "entropy"]
    , "splitter": ["best", "random"]
    , "max_depth": [*range(1, 10)]
              # ,"min_samples_leaf":[*range(5,10)]
              }
# 使用網(wǎng)絡(luò)搜索便利查詢,返回建立好的模型,網(wǎng)格搜索包括交叉驗(yàn)證cv為交叉次數(shù)
GS = GridSearchCV(clf, cv=10, param_grid=parameters)
# 進(jìn)行數(shù)據(jù)訓(xùn)練
gs = GS.fit(xtrain, ytrain)

# best_params_接口可以查看最佳組合
# 最佳組合,(不一定最好,可能有些參數(shù)不涉及結(jié)果更好)
best_choice = gs.best_params_
print(best_choice)

# best_score_接口可以查看最佳組合的得分
best_score = gs.best_score_
print(best_score)

回歸樹中不同max_depth擬合正弦函數(shù)數(shù)據(jù)

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

#隨機(jī)數(shù)生成器的實(shí)例化
rng = np.random.RandomState(0)
# rng.rand(80, 1)在0到1之間生成80個(gè)數(shù),axis=0,縱向排序作為自變量
X = np.sort(5 * rng.rand(80, 1), axis=0)
# 因變量的生成
y = np.sin(X).ravel()
# 添加噪聲
y[::5] += 3 * (0.5 - rng.rand(16))

#建立不同樹模型,回歸樹除了criterion其余和分類樹參數(shù)相同
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
# 訓(xùn)練數(shù)據(jù)
regr_1.fit(X, y)
regr_2.fit(X, y)

# 生成測(cè)試數(shù)據(jù)
X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
# 預(yù)測(cè)X_test數(shù)據(jù)在不同數(shù)上的表現(xiàn)
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)

#畫圖
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",
            c="red", label="data")
plt.plot(X_test, y_1, color="blue",
         label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="green", label="max_depth=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()

結(jié)果:


從圖像可以看出對(duì)于不同深度的節(jié)點(diǎn)來說,有優(yōu)點(diǎn)和缺點(diǎn)。對(duì)于max_depth=5的時(shí)候,一般情況下很貼近原數(shù)據(jù)結(jié)果,但是對(duì)于一些特殊的噪聲來說,也會(huì)非常貼近噪聲,所以在個(gè)別的點(diǎn)的地方會(huì)和真實(shí)數(shù)據(jù)相差比較大,也就是過擬合現(xiàn)象(對(duì)于訓(xùn)練數(shù)據(jù)集能夠很好地判斷出出,但是對(duì)于測(cè)試數(shù)據(jù)集來說結(jié)果并不理想)。對(duì)于max_depth=2的時(shí)候,雖然不能夠特別貼近大量的數(shù)據(jù)集,但是在處理一些噪聲的時(shí)候,往往能夠很好的避免。

分類樹在合成數(shù)據(jù)的表現(xiàn)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_circles, make_classification
from sklearn.tree import DecisionTreeClassifier

######生成三種數(shù)據(jù)集######
# 二分類數(shù)據(jù)集
X, y = make_classification(n_samples=100, #生成100個(gè)樣本
 n_features=2,#有兩個(gè)特征
 n_redundant=0, #添加冗余特征0個(gè)
 n_informative=2, #包含信息的特征是2個(gè)
 random_state=1,#隨機(jī)模式1
n_clusters_per_class=1 #每個(gè)簇內(nèi)包含的標(biāo)簽類別有1個(gè)
 )
rng = np.random.RandomState(2) #生成一種隨機(jī)模式
X += 2 * rng.uniform(size=X.shape) #加減0~1之間的隨機(jī)數(shù)
linearly_separable = (X, y) #生成了新的X,依然可以畫散點(diǎn)圖來觀察一下特征的分布
#plt.scatter(X[:,0],X[:,1])

#用make_moons創(chuàng)建月亮型數(shù)據(jù),make_circles創(chuàng)建環(huán)形數(shù)據(jù),并將三組數(shù)據(jù)打包起來放在列表datasets中
moons=make_moons(noise=0.3, random_state=0)
circles=make_circles(noise=0.2, factor=0.5, random_state=1)
datasets = [moons,circles,linearly_separable]


figure = plt.figure(figsize=(6, 9))
i=1
#設(shè)置用來安排圖像顯示位置的全局變量i i = 1
#開始迭代數(shù)據(jù),對(duì)datasets中的數(shù)據(jù)進(jìn)行for循環(huán)
for ds_index, ds in enumerate(datasets):
    X, y = ds
    # 對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化處理
    X = StandardScaler().fit_transform(X)
    #劃分?jǐn)?shù)據(jù)集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4,
random_state=42)

    #定數(shù)據(jù)范圍,以便后續(xù)進(jìn)行畫圖背景的確定
    #注意X[:,0]指橫坐標(biāo),X[:,1]指縱坐標(biāo)
    x1_min, x1_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    x2_min, x2_max = X[:, 1].min() - .5, X[:, 1].max() + .5

    #使畫板上每個(gè)點(diǎn)組成坐標(biāo)的形式(沒間隔0.2取一個(gè)),array1表示橫坐標(biāo),array2表示縱坐標(biāo)
    array1,array2 = np.meshgrid(np.arange(x1_min, x1_max, 0.2), np.arange(x2_min, x2_max, 0.2))
    # 顏色列表
    cm_bright = ListedColormap(['#FF0000', '#0000FF'])

########## 原始數(shù)據(jù)的現(xiàn)實(shí)  #########

    # 用畫板上六個(gè)圖片位置(3,2)的第i個(gè)
    ax = plt.subplot(len(datasets), 2, i)

    # 便簽添加
    if ds_index == 0:
        ax.set_title("Input data")

    #畫出訓(xùn)練數(shù)據(jù)集散點(diǎn)圖
    ax.scatter(X_train[:, 0],#橫坐標(biāo)
               X_train[:, 1],#縱坐標(biāo)
               c=y_train,#意思是根據(jù)y_train標(biāo)簽從cm_bright顏色列表中取出對(duì)應(yīng)的顏色,也就是說相同的標(biāo)簽有相同的顏色。
               cmap = cm_bright, #顏色列表
               edgecolors = 'k'#生成散點(diǎn)圖,每一個(gè)點(diǎn)邊緣的顏色
               )
    #畫出測(cè)試數(shù)據(jù)集的散點(diǎn)圖,其中比訓(xùn)練集多出alpha = 0.4參數(shù),以分辨訓(xùn)練測(cè)試集
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test,cmap = cm_bright, alpha = 0.4, edgecolors = 'k')
    #顯示的坐標(biāo)范圍
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    #不顯示坐標(biāo)值
    ax.set_xticks(())
    ax.set_yticks(())

    #i+1顯示在下一個(gè)子圖版上畫圖
    i += 1

####### 經(jīng)過決策的數(shù)據(jù)顯示 #######
    ax = plt.subplot(len(datasets), 2, i)
    #實(shí)例化訓(xùn)練模型
    clf = DecisionTreeClassifier(max_depth=5).fit(X_train, y_train)
    score = clf.score(X_test, y_test)

    # np.c_是能夠?qū)蓚€(gè)數(shù)組組合起來的函數(shù)
    # ravel()能夠?qū)⒁粋€(gè)多維數(shù)組轉(zhuǎn)換成一維數(shù)組
    #通過對(duì)畫板上每一個(gè)點(diǎn)的預(yù)測(cè)值確定分類結(jié)果范圍,并以此為依據(jù)通,通過不同的顏色展現(xiàn)出來范圍
    Z = clf.predict(np.c_[array1.ravel(), array2.ravel()])
    Z = Z.reshape(array1.shape)
    cm = plt.cm.RdBu # 自動(dòng)選取顏色的實(shí)例化模型。
    ax.contourf(array1#畫板橫坐標(biāo)。
                , array2#畫板縱坐標(biāo)
                , Z# 畫板每個(gè)點(diǎn)對(duì)應(yīng)的預(yù)測(cè)值m,并據(jù)此來確定底底板的顏色。
                , cmap=cm#顏顏色選取的模型,由于Z的值只有兩個(gè),也可以寫出一個(gè)顏色列表,指定相應(yīng)顏色,不讓其自動(dòng)生成
                , alpha=0.8
                )
    #和原始數(shù)據(jù)集一樣,畫出每個(gè)訓(xùn)練集和測(cè)試集的散點(diǎn)圖
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_bright, edgecolors = 'k')
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cm_bright, edgecolors = 'k', alpha = 0.4)
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    ax.set_xticks(())
    ax.set_yticks(())

    if ds_index == 0:
        ax.set_title("Decision Tree")

    #在右下角添加模型的分?jǐn)?shù)
    ax.text(array1.max() - .3, array2.min() + .3, ('{:.1f}%'.format(score * 100)),
    size = 15, horizontalalignment = 'right')
    i += 1

#自動(dòng)調(diào)整子畫板與子畫板之間的的距離
plt.tight_layout()
plt.show()


從這里可以看出決策樹,對(duì)于月亮型數(shù)據(jù)和二分類數(shù)據(jù)有比較好的分類效果,但是對(duì)于環(huán)形的數(shù)據(jù)的分類效果就不是那么理想。

什么是隨機(jī)森林

隨機(jī)森林屬于集成算法,森林從字面理解就是由多顆決策樹構(gòu)成的集合,而且這些子樹都是經(jīng)過充分生長(zhǎng)的CART樹,隨機(jī)則表示構(gòu)成多顆隨機(jī)樹是隨機(jī)生成的,生成過程采用的是bossstrap抽樣法,該算法有兩大優(yōu)點(diǎn),一是運(yùn)行速度快,二是預(yù)測(cè)準(zhǔn)確率高,被稱為最好用的算法之一。

隨機(jī)森林的原理

該算法的核心思想就是采用多棵決策樹的投票機(jī)制,完成分類或預(yù)測(cè)問題的解決。對(duì)于分類的問題,將多個(gè)數(shù)的判斷結(jié)果用做投票,根據(jù)根據(jù)少數(shù)服從多數(shù)的原則,最終確定樣本所屬的類型,對(duì)于預(yù)測(cè)性的問題,將多棵樹的回歸結(jié)果進(jìn)行平均,最終確定樣本的預(yù)測(cè)。

將隨機(jī)森林的建模過程,形象地描繪出來就是這樣:


流程:

  • 利用booststrap抽樣法,從原始數(shù)據(jù)集中生成K個(gè)數(shù)據(jù)集,并且每一個(gè)數(shù)據(jù)集都含有N個(gè)觀測(cè)和P個(gè)自變量。
  • 針對(duì)每一個(gè)數(shù)據(jù)集構(gòu)造一個(gè)CART決策樹,在構(gòu)造數(shù)的過程中,并沒有將所有自變量用作節(jié)點(diǎn)字段的選擇而是隨機(jī)選擇P個(gè)字段(特征)
  • 讓每一顆決策樹盡可能的充分生長(zhǎng),使得樹中的每一個(gè)節(jié)點(diǎn),盡可能的純凈,即隨機(jī)森林中的每一顆子樹都不需要剪枝。
  • 針對(duì)K個(gè)CART樹的隨機(jī)森林,對(duì)于分類問題利用投票法將最高的的票的類別用于最后判斷結(jié)果,對(duì)于回歸問題利用均值法,將其作為預(yù)測(cè)樣本的最終結(jié)果。

隨機(jī)森林常用參數(shù)

用分類的隨機(jī)森林舉例

RandomForestClassifier(n_estimators=10 # 用于對(duì)于指定隨機(jī)森林所包含的決策樹個(gè)數(shù)
						,criterion="gini" # 用于每棵樹分類節(jié)點(diǎn)的分割字段的度量指標(biāo)。和決策樹含義相同。
						,max_depth=None # 用于每顆決策樹的最大深度,默認(rèn)不限制其生長(zhǎng)深度。
						,min_samples_split=2 # 用于指定每顆決策數(shù)根節(jié)點(diǎn)或者中間節(jié)點(diǎn)能夠繼續(xù)分割的最小樣本量,默認(rèn)2。
						,min_samples_leaf=1 # 用于指定每個(gè)決策樹葉子節(jié)點(diǎn)的最小樣本量,默認(rèn)為1
						,max_features="auto" # 用于指定每個(gè)決策樹包含的最多分割字段數(shù)(特征數(shù))默認(rèn)None。表示分割時(shí)涉及使用所有特征
						,bootstrap=True # #是否開啟帶外模式(有放回取值,生成帶外數(shù)據(jù))若不開啟,需要自己劃分train和test數(shù)據(jù)集,默認(rèn)True
						,oob_score=False # #是否用帶外數(shù)據(jù)檢測(cè) 即是是否使用帶外樣本計(jì)算泛化,誤差默認(rèn)為false,袋外樣本是指每一個(gè)bootstrap抽樣時(shí)沒有被抽中的樣本
						,random_state=None # 用于指定隨機(jī)數(shù)生成器的種子,默認(rèn)None,表示默認(rèn)隨機(jī)生成器
						,calss_weight # 用于因變量中類別的權(quán)重,默認(rèn)每個(gè)類別權(quán)重相同
						)
注:一般n_estimators越大,模型的效果往往越好。但是相應(yīng)的,任何模型都有決策邊界
n_estimators達(dá)到一定的程度之后,隨機(jī)森林的精確性往往不在上升或開始波動(dòng)
并且n_estimators越大,需要的計(jì)算量和內(nèi)存也越大,訓(xùn)練的時(shí)間也會(huì)越來越長(zhǎng)

隨機(jī)森林應(yīng)用示例

from sklearn.datasets import load_wine
from sklearn.ensemble import RandomForestClassifier
wine=load_wine()
xtrain,xtest,ytrain,ytest=train_test_split(wine.data ,wine.target,test_size=0.3)
rfc=RandomForestClassifier(random_state=0
                          ,n_estimators=10#生成樹的數(shù)量
                          ,bootstrap=True
                          ,oob_score=True#開啟袋外數(shù)據(jù)檢測(cè)
                           ).fit(xtrain,ytrain)
rfc.score(xtest,ytest)
rfc.oob_score_#帶外數(shù)據(jù)作為檢測(cè)數(shù)據(jù)集
rfc.predict_proba(wine.data)#輸出所有數(shù)據(jù)在target上的概率
rfc.estimators_#所有樹情況
rfc.estimators_[1].random_state#某個(gè)樹random——state值

參數(shù)n_estimators對(duì)隨機(jī)森林的影響

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.ensemble import RandomForestClassifier
wine=load_wine()
score=[]
for i in range(100):
    rfc=RandomForestClassifier(random_state=0
                              ,n_estimators=i+1
                              ,bootstrap=True
                              ,oob_score=False
                               )
    once=cross_val_score(rfc,wine.data,wine.target,cv=10).mean()
    score.append(once)
    
plt.plot(range(1,101),score)
plt.xlabel("n_estimators")
plt.show()
print("best srore = ",max(score),"\nbest n_estimators = ",score.index(max(score))+1)

輸出:
best srore = 0.9833333333333334
best n_estimators = 12

決策樹和隨機(jī)森林效果

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.ensemble import RandomForestClassifier
wine=load_wine()
score1=[]
score2=[]
for i in range(10):
    rfc=RandomForestClassifier(n_estimators=12)
    once1=cross_val_score(rfc,wine.data,wine.target,cv=10).mean()
    score1.append(once1)
    clf=DecisionTreeClassifier()
    once2=cross_val_score(clf,wine.data,wine.target,cv=10).mean()
    score2.append(once2)
plt.plot(range(1,11),score1,label="Forest")
plt.plot(range(1,11),score2,label="singe tree")
plt.legend()
plt.show()


從圖像中可以直觀的看出:多個(gè)決策樹組成的隨機(jī)森林集成算法的模型效果要明顯優(yōu)于單個(gè)決策樹的效果。

實(shí)例用隨機(jī)森林對(duì)乳腺癌數(shù)據(jù)的調(diào)參

n_estimators

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
cancer = load_breast_cancer()
scores=[]
for i in range(1,201,10):
    rfc = RandomForestClassifier(n_estimators=i, random_state=0).fit(cancer.data,cancer.target)
    score = cross_val_score(rfc,cancer.data,cancer.target,cv=10).mean()
    scores.append(score)
print(max(scores),(scores.index(max(scores))*10)+1)
plt.figure(figsize=[20,5])
plt.plot(range(1,201,10),scores)
plt.show()

0.9649122807017545 111

max_depth

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
cancer = load_breast_cancer()
scores=[]
for i in range(1,20,2):
    rfc = RandomForestClassifier(n_estimators=111,max_depth=i, random_state=0)
    score = cross_val_score(rfc,cancer.data,cancer.target,cv=10).mean()
    scores.append(score)
print(max(scores),(scores.index(max(scores))*2)+1)
plt.figure(figsize=[20,5])
plt.plot(range(1,20,2),scores)
plt.show()

0.9649122807017545 11

gini改為entropy

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
cancer = load_breast_cancer()
scores=[]
for i in range(1,20,2):
    rfc = RandomForestClassifier(n_estimators=111,criterion="entropy",max_depth=i, random_state=0)
    score = cross_val_score(rfc,cancer.data,cancer.target,cv=10).mean()
    scores.append(score)
print(max(scores),(scores.index(max(scores))*2)+1)
plt.figure(figsize=[20,5])
plt.plot(range(1,20,2),scores)
plt.show()

0.9666666666666666 7

gini和entropy結(jié)果圖片:

到此這篇關(guān)于Python機(jī)器學(xué)習(xí)之決策樹和隨機(jī)森林的文章就介紹到這了,更多相關(guān)Python 決策樹和隨機(jī)森林內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • python實(shí)現(xiàn)決策樹、隨機(jī)森林的簡(jiǎn)單原理
  • Python決策樹和隨機(jī)森林算法實(shí)例詳解

標(biāo)簽:上海 新疆 紅河 沈陽 滄州 河南 長(zhǎng)治 樂山

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Python機(jī)器學(xué)習(xí)之決策樹和隨機(jī)森林》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266