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

引言

?隨機(jī)森林的原理網(wǎng)上有一大堆,作為入門小白,下面來(lái)根據(jù)教材敲兩個(gè)隨機(jī)森林的代碼。
隨機(jī)森林有兩個(gè)比較重要的參數(shù):max_features 和 n_estimators。
max_features 的取值越高,隨機(jī)森林里的每一顆決策樹就會(huì)“長(zhǎng)得更像”。如果max_features 的取值越低,就會(huì)迫使每顆決策樹的樣子更加不同,而且因?yàn)樘卣魈?,決策樹們不得不制造更多節(jié)點(diǎn)來(lái)擬合數(shù)據(jù)。
n_estimators 控制隨機(jī)森林中決策樹的數(shù)量。隨機(jī)森林構(gòu)建完成之后,每顆決策樹都會(huì)單獨(dú)進(jìn)行預(yù)測(cè)。如果是用來(lái)進(jìn)行回歸分析的話,隨機(jī)森林會(huì)把所有決策樹預(yù)測(cè)的值取平均數(shù);如果是用來(lái)進(jìn)行分類的話,在森林內(nèi)部會(huì)進(jìn)行“投票”,每棵樹預(yù)測(cè)數(shù)數(shù)據(jù)類別的概率,隨機(jī)森林會(huì)把這些概率取平均值,然后把樣本放入概率較高的分類中。
注釋:

sklearn.ensemble.RandomForestClassifie 隨機(jī)森林

函數(shù)原型
class sklearn.ensemble.RandomForestClassifier(
n_estimators=10,
criterion='gini',
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.0,
max_features=’auto’,
max_leaf_nodes=None,
min_impurity_decrease=0.0,
min_impurity_split=None,
bootstrap=True,
oob_score=False,
n_jobs=1,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None)

參數(shù)解釋
?n_estimators:整數(shù),可選擇(默認(rèn)值為10)。 森林里(決策)樹的數(shù)目。
?criterion:字符串,可選擇(默認(rèn)值為“gini”)。衡量分裂質(zhì)量的性能(函數(shù))。 受支持的標(biāo)準(zhǔn)是基尼不純度的"gini",和信息增益的"entropy"(熵)。
注意:這個(gè)參數(shù)是特定樹的。
首先Gini不純度和Gini系數(shù)(coefficient)沒有關(guān)系。Gini impurity衡量的是從一個(gè)集合中隨機(jī)選擇一個(gè)元素,基于該集合中標(biāo)簽的概率分布為元素分配標(biāo)簽的錯(cuò)誤率。對(duì)于任何一個(gè)標(biāo)簽下的元素,其被分類正確的條件概率可以理解為在選擇元素時(shí)選中該標(biāo)簽的概率與在分類時(shí)選中該標(biāo)簽的概率?;谏鲜雒枋觯珿ini impurity的計(jì)算就非常簡(jiǎn)單了,即1減去所有分類正確的概率,得到的就是分類不正確的概率。若元素?cái)?shù)量非常多,切所有元素單獨(dú)屬于一個(gè)分類時(shí),Gini不純度達(dá)到極小值0
?max_features: 整數(shù),浮點(diǎn)數(shù),字符串或者無(wú)值。尋找最佳分割時(shí)需要考慮的特征數(shù)目:

  • 如果是int,就要考慮每一次分割處的max_feature特征
  • 如果是float,那么max_features就是一個(gè)百分比,那么(max_feature*n_features)特征整數(shù)值是在每個(gè)分割處考慮的。
  • 如果是auto,那么max_features=sqrt(n_features),即n_features的平方根值。
  • 如果是log2,那么max_features=log2(n_features)
  • 如果是None,那么max_features=n_features
    注意:尋找分割點(diǎn)不會(huì)停止,直到找到最少一個(gè)有效的節(jié)點(diǎn)劃分區(qū),即使它需要有效檢查超過(guò)max_features的特征。
    ?max_depth:整數(shù)或者無(wú)值。(決策)樹的最大深度。如果值為None,那么會(huì)擴(kuò)展節(jié)點(diǎn),直到所有的葉子是純凈的,或者直到所有葉子包含少于min_sample_split的樣本。
    ?min_samples_split:整數(shù),浮點(diǎn)數(shù)。分割內(nèi)部節(jié)點(diǎn)所需要的最小樣本數(shù)量:
    ~如果為int,那么考慮min_samples_split作為最小的數(shù)字。
    ~如果為float,那么min_samples_split是一個(gè)百分比,并且把ceil(min_samples_split*n_samples)是每一個(gè)分割最小的樣本數(shù)量。
    在版本0.18中更改:為百分比添加浮點(diǎn)值。

?min_samples_leaf:整數(shù),浮點(diǎn)數(shù)。一個(gè)葉子節(jié)點(diǎn)所需要的權(quán)重總和(所有的輸入樣本)的最小加權(quán)分?jǐn)?shù)。當(dāng)sample_weight沒有提供時(shí),樣本具有相同的權(quán)重。
?max_leaf_nodes:整數(shù)或者無(wú)值。以最優(yōu)的方法使用max_leaf_nodes來(lái)生長(zhǎng)樹。最好的節(jié)點(diǎn)被定義為不純度上的相對(duì)減少。如果為None,那么不限制葉子節(jié)點(diǎn)的數(shù)量。
?min_impurity_split:浮點(diǎn)數(shù)。樹早期生長(zhǎng)的閾值。如果一個(gè)節(jié)點(diǎn)的不純度超過(guò)閾值那么這個(gè)節(jié)點(diǎn)將會(huì)分裂,否則它還是一片葉子。
自0.19版以后不推薦使用:min_impurity_split已被棄用,取而代之的是0.19中的min_impurity_decrease。min_impurity_split將在0.21中被刪除。 使用min_impurity_decrease。
?min_impurity_decrease:浮點(diǎn)數(shù)。如果節(jié)點(diǎn)的分裂導(dǎo)致的不純度的下降程度大于或者等于這個(gè)節(jié)點(diǎn)的值,那么這個(gè)節(jié)點(diǎn)將會(huì)被分裂。
?bootstrap:bool。是否使用袋外樣本來(lái)估計(jì)泛化精度。
?n_jobs:整數(shù)。用于擬合和預(yù)測(cè)的并行運(yùn)行的工作(作業(yè))數(shù)量。如果值為-1,那么工作數(shù)量被設(shè)置為核的數(shù)量。
?random_state: 整數(shù),RandomState實(shí)例,或者為None。RandomStateIf int,random_state是隨機(jī)數(shù)生成器使用的種子; 如果是RandomState實(shí)例,random_state就是隨機(jī)數(shù)生成器; 如果為None,則隨機(jī)數(shù)生成器是np.random使用的RandomState實(shí)例。
?verbose:整數(shù)。控制決策樹建立過(guò)程的冗余度
?warm_start:布爾值。當(dāng)被設(shè)置為True時(shí),重新使用之前呼叫的解決方案,用來(lái)給全體擬合和添加更多的估計(jì)器,反之,僅僅只是為了擬合一個(gè)全新的森林。
?class_weight:字典,字典序列,"balanced"。“balanced_subsample” 或者None,(默認(rèn)值為None),與格式{class_label: weight}相關(guān)聯(lián)的類的可選的權(quán)值。如果沒有給值,所有的類到都應(yīng)該有一個(gè)權(quán)值。對(duì)于多輸出問(wèn)題,一個(gè)字典序列可以按照y的列的順利被提供。
請(qǐng)注意,對(duì)于多輸出(包括多標(biāo)簽),其權(quán)值應(yīng)該被定義為它自己字典的每一列的每一個(gè)類。例如,對(duì)于四類多標(biāo)簽分類,權(quán)值應(yīng)該如[{0: 1, 1: 1}, {0: 1, 1: 5}, {0: 1, 1: 1}, {0: 1, 1: 1}] 這樣,而不是[{1:1}, {2:5}, {3:1}, {4:1}].這樣。
"balanced"模式使用y的值來(lái)自動(dòng)的調(diào)整權(quán)值,與輸入數(shù)據(jù)中類別頻率成反比,如:
n_samples / (n_classes * np.bincount(y))
"balanced_subsample"模式和"balanced"相同,除了權(quán)值是基于每棵成長(zhǎng)樹有放回抽樣計(jì)算的。
對(duì)于多輸出,y的每列權(quán)值將相乘。
請(qǐng)注意,如果指定了sample_weight,這些權(quán)值將會(huì)和sample_weight相乘(通過(guò)擬合方法傳遞)。

一、紅酒的分類

數(shù)據(jù)采用datasets里的 紅酒數(shù)據(jù)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split #切分訓(xùn)練集和測(cè)試集
from sklearn.ensemble import RandomForestClassifier #導(dǎo)入隨機(jī)森林模型
from sklearn import tree, datasets

#載入紅酒數(shù)據(jù)
wine = datasets.load_wine()

#只選取前兩個(gè)特征
X = wine.data[:, :2]
y = wine.target

#拆分訓(xùn)練集和數(shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X, y)

#設(shè)定隨機(jī)森林中有6顆樹
forest = RandomForestClassifier(n_estimators=6, random_state=3)

#擬合數(shù)據(jù)
forest.fit(X_train, y_train)

#繪制圖形
#定義圖像中分區(qū)的顏色和散點(diǎn)的顏色
cmap_light= ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])

#分別用樣本的兩個(gè)特征值創(chuàng)建圖像和橫軸和縱軸
x_min, x_max = X[:,0].min()-1, X[:,0].max()+1
y_min, y_max = X[:,1].min()-1, X[:,1].max()+1
#用不同的背景色表示不同的類
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
                     np.arange(y_min, y_max, .02))
z = forest.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)

plt.figure()
plt.pcolormesh(xx, yy, z, cmap=cmap_light)

#用散點(diǎn)把樣本標(biāo)出來(lái)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolors='k', s=20)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())

plt.title('Classifier: RandomForestClassifier') #依照參數(shù)值修改標(biāo)題
plt.show()

運(yùn)行結(jié)果如下圖可示,隨機(jī)森林的分類比較細(xì)膩,可調(diào)節(jié)參數(shù)查看分類器的表現(xiàn)


6.3RadomForest.png

二、要不要和相親對(duì)象進(jìn)一步發(fā)展

采用美國(guó)1994 年采集的的成年人數(shù)據(jù)集,包括年齡、工作單位性質(zhì)、學(xué)歷等。下完之后是.data格式,重命名為.csv
數(shù)據(jù)集從這個(gè)地址下載:archive.ics.uci.edu/ml/machine-learning-databases/adult/

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split #切分訓(xùn)練集和測(cè)試集
from sklearn.ensemble import RandomForestClassifier #導(dǎo)入隨機(jī)森林模型
from sklearn.tree import DecisionTreeClassifier #導(dǎo)入決策樹模型
import graphviz
from sklearn.tree import export_graphviz  #導(dǎo)入決策樹中輸出graphviz的接口
from sklearn.externals.six import StringIO

#載入數(shù)據(jù)集
data = pd.read_csv('adult.csv', header=None, index_col=False, names=['年齡', '單位性質(zhì)', '權(quán)重', '學(xué)歷', '受教育時(shí)長(zhǎng)', '婚姻狀況',
                                                                     '職業(yè)', '家庭情況', '種族', '性別', '資產(chǎn)所得', '資產(chǎn)損失',
                                                                     '周工作時(shí)長(zhǎng)','原籍', '收入'])

#只取部分?jǐn)?shù)據(jù)
data_lite = data[['年齡', '單位性質(zhì)', '學(xué)歷', '性別', '周工作時(shí)長(zhǎng)', '職業(yè)', '收入']]

#查看前5條數(shù)據(jù)
print('>>>>>>>>>>>原始數(shù)據(jù)前5行')
print(data_lite.head(5))

#使用 get_dummies 處理數(shù)據(jù),將文本數(shù)據(jù)轉(zhuǎn)化為數(shù)值,將特征值拆開,轉(zhuǎn)換為0,1
data_dummie = pd.get_dummies(data_lite)

#對(duì)比原始特征和虛擬變量特征
print('樣本原始特征:\n', list(data_lite.columns), '\n')
print('虛擬變量特征:\n', list(data_dummie.columns), '\n')
print(list(data_dummie.columns)[:-2])

#查看前5條數(shù)據(jù)
print('>>>>>>>>>>>get_dummies 處理后數(shù)據(jù)前5行')
print(data_dummie.head(5))

#定義數(shù)據(jù)集的特征值
features = data_dummie.loc[:,'年齡':'職業(yè)_ Transport-moving']
#將特征數(shù)值賦值給X
X = features.values
#將收入大于50k作為預(yù)測(cè)目標(biāo)
y = data_dummie['收入_ >50K'].values

#拆分訓(xùn)練集和數(shù)據(jù)集
X_train, X_test, y_train, y_test = train_test_split(X, y)

#用最大深度為5 的決策樹擬合數(shù)據(jù)
clf = DecisionTreeClassifier(max_depth=6)#依次取max_depth=1, 3, 5 查看結(jié)果
clf.fit(X_train, y_train)

#用隨機(jī)森林?jǐn)M合數(shù)據(jù)
forest = RandomForestClassifier(n_estimators=6, random_state=2)
forest.fit(X_train, y_train)

print('代碼運(yùn)行結(jié)果為:')
print('==========================')
print("決策樹訓(xùn)練數(shù)據(jù)得分:{:.2f}".format(clf.score(X_test, y_test)))
print('==========================')
print("隨機(jī)森林訓(xùn)練數(shù)據(jù)得分:{:.2f}".format(forest.score(X_test, y_test)))

#畫出決策樹的執(zhí)行圖
dot_data = StringIO()
dot_data = export_graphviz(clf, out_file=None, class_names=list(data_dummie.columns),
                feature_names=list(data_dummie.columns)[:-2], impurity=False, filled=True)
graph = graphviz.Source(dot_data) # doctest: +SKIP

#在同級(jí)目錄下生成tree.pdf文件
graph.render("Datingtree") # 保存成pdf

#對(duì)Mr Z男士進(jìn)行預(yù)測(cè)(年齡37,在省機(jī)關(guān)工作,碩士學(xué)歷等等)
Mr_z = [[37, 40, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
dating_desc = clf.predict(Mr_z)
dating_desc1 = forest.predict(Mr_z)
print('決策樹預(yù)測(cè)結(jié)果為:')
print('==========================')
if dating_desc ==1 :
    print("金龜婿啊,這哥們?cè)滦匠^(guò)5萬(wàn)了,快去約會(huì)")
else:
    print("算了,不滿足你的要求")
print('\n')
print('隨機(jī)森林預(yù)測(cè)結(jié)果為:')
print('==========================')
if dating_desc ==1 :
    print("金龜婿啊,這哥們?cè)滦匠^(guò)5萬(wàn)了,快去約會(huì)")
else:
    print("算了,不滿足你的要求")

執(zhí)行結(jié)果如下:


6.4DexisionAndRadomForest.png
>>>>>>>>>>>原始數(shù)據(jù)前5行
   年齡               單位性質(zhì)          學(xué)歷       性別  周工作時(shí)長(zhǎng)                  職業(yè)  \
0  39          State-gov   Bachelors     Male     40        Adm-clerical   
1  50   Self-emp-not-inc   Bachelors     Male     13     Exec-managerial   
2  38            Private     HS-grad     Male     40   Handlers-cleaners   
3  53            Private        11th     Male     40   Handlers-cleaners   
4  28            Private   Bachelors   Female     40      Prof-specialty   

       收入  
0   <=50K  
1   <=50K  
2   <=50K  
3   <=50K  
4   <=50K  
樣本原始特征:
 ['年齡', '單位性質(zhì)', '學(xué)歷', '性別', '周工作時(shí)長(zhǎng)', '職業(yè)', '收入'] 

虛擬變量特征:
 ['年齡', '周工作時(shí)長(zhǎng)', '單位性質(zhì)_ ?', '單位性質(zhì)_ Federal-gov', '單位性質(zhì)_ Local-gov', '單位性質(zhì)_ Never-worked', '單位性質(zhì)_ Private', '單位性質(zhì)_ Self-emp-inc', '單位性質(zhì)_ Self-emp-not-inc', '單位性質(zhì)_ State-gov', '單位性質(zhì)_ Without-pay', '學(xué)歷_ 10th', '學(xué)歷_ 11th', '學(xué)歷_ 12th', '學(xué)歷_ 1st-4th', '學(xué)歷_ 5th-6th', '學(xué)歷_ 7th-8th', '學(xué)歷_ 9th', '學(xué)歷_ Assoc-acdm', '學(xué)歷_ Assoc-voc', '學(xué)歷_ Bachelors', '學(xué)歷_ Doctorate', '學(xué)歷_ HS-grad', '學(xué)歷_ Masters', '學(xué)歷_ Preschool', '學(xué)歷_ Prof-school', '學(xué)歷_ Some-college', '性別_ Female', '性別_ Male', '職業(yè)_ ?', '職業(yè)_ Adm-clerical', '職業(yè)_ Armed-Forces', '職業(yè)_ Craft-repair', '職業(yè)_ Exec-managerial', '職業(yè)_ Farming-fishing', '職業(yè)_ Handlers-cleaners', '職業(yè)_ Machine-op-inspct', '職業(yè)_ Other-service', '職業(yè)_ Priv-house-serv', '職業(yè)_ Prof-specialty', '職業(yè)_ Protective-serv', '職業(yè)_ Sales', '職業(yè)_ Tech-support', '職業(yè)_ Transport-moving', '收入_ <=50K', '收入_ >50K'] 

['年齡', '周工作時(shí)長(zhǎng)', '單位性質(zhì)_ ?', '單位性質(zhì)_ Federal-gov', '單位性質(zhì)_ Local-gov', '單位性質(zhì)_ Never-worked', '單位性質(zhì)_ Private', '單位性質(zhì)_ Self-emp-inc', '單位性質(zhì)_ Self-emp-not-inc', '單位性質(zhì)_ State-gov', '單位性質(zhì)_ Without-pay', '學(xué)歷_ 10th', '學(xué)歷_ 11th', '學(xué)歷_ 12th', '學(xué)歷_ 1st-4th', '學(xué)歷_ 5th-6th', '學(xué)歷_ 7th-8th', '學(xué)歷_ 9th', '學(xué)歷_ Assoc-acdm', '學(xué)歷_ Assoc-voc', '學(xué)歷_ Bachelors', '學(xué)歷_ Doctorate', '學(xué)歷_ HS-grad', '學(xué)歷_ Masters', '學(xué)歷_ Preschool', '學(xué)歷_ Prof-school', '學(xué)歷_ Some-college', '性別_ Female', '性別_ Male', '職業(yè)_ ?', '職業(yè)_ Adm-clerical', '職業(yè)_ Armed-Forces', '職業(yè)_ Craft-repair', '職業(yè)_ Exec-managerial', '職業(yè)_ Farming-fishing', '職業(yè)_ Handlers-cleaners', '職業(yè)_ Machine-op-inspct', '職業(yè)_ Other-service', '職業(yè)_ Priv-house-serv', '職業(yè)_ Prof-specialty', '職業(yè)_ Protective-serv', '職業(yè)_ Sales', '職業(yè)_ Tech-support', '職業(yè)_ Transport-moving']
>>>>>>>>>>>get_dummies 處理后數(shù)據(jù)前5行
   年齡  周工作時(shí)長(zhǎng)  單位性質(zhì)_ ?  單位性質(zhì)_ Federal-gov  單位性質(zhì)_ Local-gov  單位性質(zhì)_ Never-worked  \
0  39     40        0                  0                0                   0   
1  50     13        0                  0                0                   0   
2  38     40        0                  0                0                   0   
3  53     40        0                  0                0                   0   
4  28     40        0                  0                0                   0   

   單位性質(zhì)_ Private  單位性質(zhì)_ Self-emp-inc  單位性質(zhì)_ Self-emp-not-inc  單位性質(zhì)_ State-gov  \
0              0                   0                       0                1   
1              0                   0                       1                0   
2              1                   0                       0                0   
3              1                   0                       0                0   
4              1                   0                       0                0   

     ...     職業(yè)_ Machine-op-inspct  職業(yè)_ Other-service  職業(yè)_ Priv-house-serv  \
0    ...                         0                  0                    0   
1    ...                         0                  0                    0   
2    ...                         0                  0                    0   
3    ...                         0                  0                    0   
4    ...                         0                  0                    0   

   職業(yè)_ Prof-specialty  職業(yè)_ Protective-serv  職業(yè)_ Sales  職業(yè)_ Tech-support  \
0                   0                    0          0                 0   
1                   0                    0          0                 0   
2                   0                    0          0                 0   
3                   0                    0          0                 0   
4                   1                    0          0                 0   

   職業(yè)_ Transport-moving  收入_ <=50K  收入_ >50K  
0                     0          1         0  
1                     0          1         0  
2                     0          1         0  
3                     0          1         0  
4                     0          1         0  

[5 rows x 46 columns]
代碼運(yùn)行結(jié)果為:
==========================
決策樹訓(xùn)練數(shù)據(jù)得分:0.79
==========================
隨機(jī)森林訓(xùn)練數(shù)據(jù)得分:0.78
決策樹預(yù)測(cè)結(jié)果為:
==========================
算了,不滿足你的要求


隨機(jī)森林預(yù)測(cè)結(jié)果為:
==========================
算了,不滿足你的要求

注釋:

畫決策樹的圖的時(shí)候出現(xiàn)了中文亂碼的情況,參考這兩位大哥的帖子修改
《window系統(tǒng)sklearn決策樹graphviz繪圖中文亂碼解決方法》
《Graphviz畫決策樹中文亂碼解決》

三、隨機(jī)森林的優(yōu)勢(shì)和不足

優(yōu)勢(shì):

  • 1.由于對(duì)每個(gè)特征進(jìn)行單獨(dú)處理,因此并不需要對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換,幾乎不需要對(duì)數(shù)據(jù)進(jìn)行預(yù)處理
  • 2.支持并行處理,用 n_jobs 參數(shù)來(lái)調(diào)節(jié)。當(dāng)n_jobs = -1時(shí),隨機(jī)森林會(huì)使用CPU的全部?jī)?nèi)核。
  • 3.隨機(jī)森林生成每顆決策樹的方法是隨機(jī)的,如果不希望建模的結(jié)果太過(guò)于不穩(wěn)定的話,要固化 random_state參數(shù)
    不足:
  • 對(duì)于高維數(shù)據(jù)集、稀疏數(shù)據(jù)集來(lái)說(shuō),線性模型比隨機(jī)森林的表現(xiàn)要好
  • 隨機(jī)森林系相對(duì)更消耗內(nèi)存,速度也比線性模型慢,如果希望節(jié)省內(nèi)存和時(shí)間的話,建議選擇線性模型
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容