精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從決策樹到隨機森林:樹型算法的原理與實現

移動開發 開發 算法
基于樹(Tree based)的學習算法在數據科學競賽中是相當常見的。這些算法給預測模型賦予了準確性、穩定性以及易解釋性。和線性模型不同,它們對非線性關系也能進行很好的映射。常見的基于樹的模型有:決策樹(decision trees),隨機森林(random forest)和提升樹(boosted trees)。

在本篇文章中,我們將會介紹決策樹的數學細節(以及各種 Python 示例)及其優缺點。你們將會發現它們是很簡單的,并且這些內容是有助于理解的。然而,與最好的監督學習方法相比,它們通常是沒有競爭力的。為了克服決策樹的各種缺點,我們將會聚焦于各種概念(附有 Python 實例),比如自助聚集或袋裝(Bootstrap Aggregating or Bagging),還有隨機森林(Random Forests)。另一種廣泛使用的提升方法會在以后進行單獨討論。每種方法都包括生成多種樹,這些樹被聯合起來,生成一個單一的一致性預測結果,并且經常帶來預測精度的顯著提升。

決策樹

決策樹是一種監督學習算法。它適用于類別和連續輸入(特征)和輸出(預測)變量。基于樹的方法把特征空間劃分成一系列矩形,然后給每一個矩形安置一個簡單的模型(像一個常數)。從概念上來講,它們是簡單且有效的。首先我們通過一個例子來理解決策樹。然后用一種正規分析方法來分析創建決策樹的過程。考慮一個簡單的借貸公司顧客的數據集合。我們給定了所有客戶的查詢賬戶余額、信用記錄、任職年限和先前貸款狀況。相關任務是預測顧客的風險等級是否可信。該問題可以使用下列決策樹來解決:

 

決策樹

分類和回歸樹(簡稱 CART)是 Leo Breiman 引入的術語,指用來解決分類或回歸預測建模問題的決策樹算法。它常使用 scikit 生成并實現決策樹: sklearn.tree.DecisionTreeClassifier 和 sklearn.tree.DecisionTreeRegressor 分別構建分類和回歸樹。

CART 模型

CART 模型包括選擇輸入變量和那些變量上的分割點,直到創建出適當的樹。使用貪婪算法(greedy algorithm)選擇使用哪個輸入變量和分割點,以使成本函數(cost function)最小化。

樹建造的結尾使用了一個預定義的停止準則,比如分配到樹上每一個葉結點的訓練樣本達到最小數量。

其他決策樹算法:

  • ID3:Iterative Dichotomiser 3
  • C4.5:ID3 算法的改進
  • CHAID:Chi-squared Automatic Interaction Detector
  • MARS:決策樹的擴展式,以更好地解決數值型預測。
  • 條件推斷樹

回歸樹

我們現在關注一下回歸樹的 CART 算法的細節。簡要來說,創建一個決策樹包含兩步:

1. 把預測器空間,即一系列可能值 X_1,X_2,...,X_p 分成 J 個不同的且非重疊的區域 R_1,R_2,...,R_J。

2. 對進入區域 R_J 的每一個樣本觀測值都進行相同的預測,該預測就是 R_J 中訓練樣本預測值的均值。

為了創建 J 個區域 R_1,R_2,...,R_J,預測器區域被分為高維度的矩形或盒形。其目的在于通過下列式子找到能夠使 RSS 最小化的盒形區域 R_1,R_2,...,R_J,

其中,yhat_Rj 即是第 j 個盒形中訓練觀測的平均預測值。

鑒于這種空間分割在計算上是不可行的,因此我們常使用貪婪方法(greedy approach)來劃分區域,叫做遞歸二元分割(recursive binary splitting)。

它是貪婪的(greedy),這是因為在創建樹過程中的每一步驟,最佳分割都會在每個特定步驟選定,而不是對未來進行預測,并選取一個將會在未來步驟中出現且有助于創建更好的樹的分隔。注意所有的劃分區域 R_j 都是矩形。為了進行遞歸二元分割,首先選取預測器 X_j 和切割點 s 

其中 yhat_R1 為區域 R_1(j,s) 中觀察樣本的平均預測值,yhat_R2 為區域 R_2(j,s) 的觀察樣本預測均值。這一過程不斷重復以搜尋最好的預測器和切分點,并進一步分隔數據以使每一個子區域內的 RSS 最小化。然而,我們不會分割整個預測器空間,我們只會分割一個或兩個前面已經認定的區域。這一過程會一直持續,直到達到停止準則,例如我們可以設定停止準則為每一個區域最多包含 m 個觀察樣本。一旦我們創建了區域 R_1、R_2、...、R_J,給定一個測試樣本,我們就可以用該區域所有訓練樣本的平均預測值來預測該測試樣本的值。

分類樹

分類樹和回歸樹十分相似,只不過它是定性地預測響應值而非定量預測。從上文可知,回歸樹對一個觀察值所預測的連續型數值就是屬于同一葉結點訓練樣本觀察值的均值。但是對于分類樹來說,我們所預測的類別是訓練樣本觀察值在某區域下最常見的類別,即訓練觀察值的模式響應(mode response)。為了達到分類目的,很多時候系統并不會只預測一個類別,它常常預測一組類別及其出現的概率。

分類樹的生成和回歸樹的生成十分相似。正如在回歸樹中那樣,我們一般使用遞歸性的二元分割來生成分類樹。然而在分類樹中,RSS 不能作為二元分割的標準。我們需要定義葉結點的不純度量 Q_m 來替代 RSS,即一種可以在子集區域 R_1,R_2,...,R_j 度量目標變量同質性的方法。在結點 m 中,我們可以通過 N_m 個樣本觀察值表示一個區域 R_m 所出現類別的頻率,第 k 個類別在第 m 個區域下訓練所出現的頻率可表示為:

其中,I(y_i=k) 為指示函數,即如果 y_i = k,則取 1,否則取零。

不純性度量 Q_m 一個比較自然的方法是分類誤差率。分類誤差率描述的是訓練觀察值在某個區域內不屬于最常見類別的概率:

考慮到該函數不可微,因此它不能實現數值優化。此外,該函數在結點概率改變上并不敏感,因此這種分類誤差率對于生成樹十分低效。我們一般使用 Gini 指數和交叉熵函數來衡量結點的誤差度量。

Gini 指數可以衡量 k 個類別的總方差,它一般定義為:

較小的 Gini 指數值表示結點包含了某個類別大多數樣本觀察值。

在信息論里面,交叉熵函數用來衡量系統的混亂度。對于二元系統來說,如果系統包含了一個類別的所有內容,那么它的值為零,而如果兩個類別的數量一樣多,那么交叉熵達到最大為 1。因此,和 Gini 指數一樣,交叉熵函數同樣能用于度量結點的不純度:

和 G 一樣,較小的 S 值表示區域內結點包含了單個類別中的大多數觀察值。

決策樹常見參數和概念

如果我們希望以數學的方式理解決策樹,我們首先需要了解決策樹和樹型學習算法的一般概念。理解以下的術語同樣能幫助我們調整模型。

  • 根結點:表示所有數據樣本并可以進一步劃分為兩個或多個子結點的父結點。
  • 分裂(Splitting):將一個結點劃分為兩個或多個子結點的過程。
  • 決策結點:當一個子結點可進一步分裂為多個子結點,那么該結點就稱之為決策結點。
  • 葉/終止結點:不會往下進一步分裂的結點,在分類樹中代表類別。
  • 分枝/子樹:整棵決策樹的一部分。
  • 父結點和子結點:如果一個結點往下分裂,該結點稱之為父結點而父結點所分裂出來的結點稱之為子結點。
  • 結點分裂的最小樣本數:在結點分裂中所要求的最小樣本數量(或觀察值數量)。這種方法通常可以用來防止過擬合,較大的最小樣本數可以防止模型對特定的樣本學習過于具體的關系,該超參數應該需要使用驗證集來調整。
  • 葉結點最小樣本數:葉結點所要求的最小樣本數。和結點分裂的最小樣本數一樣,該超參數同樣也可以用來控制過擬合。對于不平衡類別問題來說,我們應該取較小的值,因為屬于較少類別的樣本可能數量上非常少。
  • 樹的最大深度(垂直深度):該超參數同樣可以用來控制過擬合問題,較小的深度可以防止模型對特定的樣本學習過于具體的關系,該超參數同樣需要在驗證集中調整。
  • 葉結點的最大數量:葉結點的最大個數可以替代數的最大深度這一設定。因為生成一棵深度為 n 的二叉樹,它所能產生的最大葉結點個數為 2^n。
  • 分裂所需要考慮的最大特征數:即當我們搜索更好分離方案時所需要考慮的特征數量,我們常用的方法是取可用特征總數的平方根為最大特征數。

分類樹的實現

為了展示不同的前文所述的決策樹模型,我們將使用 Kaggle 上的美國收入數據集,我們都可以在 Kaggle.com 上下載該數據集。下面的代碼可以展示該數據集的導入過程和部分內容:

import pandas as pd
import numpy as np
from plotnine import *
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn_pandas import DataFrameMapper
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier

training_data = './adult-training.csv'
test_data = './adult-test.csv'

columns = ['Age','Workclass','fnlgwt','Education','EdNum','MaritalStatus','Occupation','Relationship','Race','Sex','CapitalGain','CapitalLoss','HoursPerWeek','Country','Income']

df_train_set = pd.read_csv(training_data, names=columns)
df_test_set = pd.read_csv(test_data, names=columns, skiprows=1)
df_train_set.drop('fnlgwt', axis=1, inplace=True)
df_test_set.drop('fnlgwt', axis=1, inplace=True)

在上面的代碼中,我們首先需要導入所有需要的庫和模塊,然后再讀取數據和結構到訓練數據和驗證數據中。我們同樣去除 fnlgwt 列,因為該數據行對于模型的訓練并不重要。

輸入以下語句可以看到訓練數據的前五行:

df_train_set.head()

 

數據

如下所示,我們還需要做一些數據清洗。我們需要將所有列的的特殊字符移除,此外任何空格或者「.」都需要移除。

#replace the special character to "Unknown"for i in df_train_set.columns:
    df_train_set[i].replace(' ?', 'Unknown', inplace=True)
    df_test_set[i].replace(' ?', 'Unknown', inplace=True)for col in df_train_set.columns:if df_train_set[col].dtype != 'int64':
        df_train_set[col] = df_train_set[col].apply(lambda val: val.replace(" ", ""))
        df_train_set[col] = df_train_set[col].apply(lambda val: val.replace(".", ""))
        df_test_set[col] = df_test_set[col].apply(lambda val: val.replace(" ", ""))
        df_test_set[col] = df_test_set[col].apply(lambda val: val.replace(".", ""))

正如上圖所示,有兩行描述了個人的教育:Eduction 和 EdNum。我們假設這兩個特征十分相關,因此我們可以移除 Education 列。Country 列對預測收入并不會起到什么作用,所以我們需要移除它。

df_train_set.drop(["Country", "Education"], axis=1, inplace=True)
df_test_set.drop(["Country", "Education"], axis=1, inplace=True)

Age 和 EdNum 列是數值型的,我們可以將連續數值型轉化為更高效的方式,例如將年齡換為 10 年的整數倍,教育年限換為 5 年的整數倍,實現的代碼如下:

colnames = list(df_train_set.columns)
colnames.remove('Age')
colnames.remove('EdNum')
colnames = ['AgeGroup', 'Education'] + colnames

labels = ["{0}-{1}".format(i, i + 9) for i in range(0, 100, 10)]
df_train_set['AgeGroup'] = pd.cut(df_train_set.Age, range(0, 101, 10), right=False, labels=labels)
df_test_set['AgeGroup'] = pd.cut(df_test_set.Age, range(0, 101, 10), right=False, labels=labels)

labels = ["{0}-{1}".format(i, i + 4) for i in range(0, 20, 5)]
df_train_set['Education'] = pd.cut(df_train_set.EdNum, range(0, 21, 5), right=False, labels=labels)
df_test_set['Education'] = pd.cut(df_test_set.EdNum, range(0, 21, 5), right=False, labels=labels)

df_train_set = df_train_set[colnames]
df_test_set = df_test_set[colnames]

現在我們已經清理了數據,下面語句可以展示我們數據的概況:

df_train_set.Income.value_counts()
<=50K 24720
>50K 7841
Name: Income, dtype: int64
df_test_set.Income.value_counts()
<=50K 12435
>50K 3846
Name: Income, dtype: int64

在訓練集和測試集中,我們發現 <=50K 的類別要比>50K 的多 3 倍。從這里我們就可以看出來樣本數據并不是均衡的數據,但是在這里為了簡化問題,我們在這里將該數據集看作常規問題。

EDA

現在,讓我們以圖像的形式看一下訓練數據中的不同特征的分布和相互依存(inter-dependence)關系。首先看一下關系(Relationships)和婚姻狀況(MaritalStatus)特征是如何相互關聯的。

(ggplot(df_train_set, aes(x = "Relationship", fill = "MaritalStatus"))+ geom_bar(position="fill")+ theme(axis_text_x = element_text(angle = 60, hjust = 1)))

 

Relationship

讓我們首先看一下不同年齡組中,教育對收入的影響(用受教育的年數進行衡量)。

(ggplot(df_train_set, aes(x = "Education", fill = "Income"))+ geom_bar(position="fill")+ theme(axis_text_x = element_text(angle = 60, hjust = 1))+ facet_wrap('~AgeGroup'))

最近,有很多關于性別對收入差距的影響的相關說法。我們可以分別看見男性和女性的教育程度和種族間的影響。

(ggplot(df_train_set, aes(x = "Education", fill = "Income"))+ geom_bar(position="fill")+ theme(axis_text_x = element_text(angle = -90, hjust = 1))+ facet_wrap('~Sex'))

(ggplot(df_train_set, aes(x = "Race", fill = "Income"))+ geom_bar(position="fill")+ theme(axis_text_x = element_text(angle = -90, hjust = 1))+ facet_wrap('~Sex'))

直到現在,我們僅關注了非數值特征(non-numeric)的相互關系。現在我們看一下資本收益(CapitalGain)和資本損失(CapitalLoss)對收入的影響。

(ggplot(df_train_set, aes(x="Income", y="CapitalGain"))+ geom_jitter(position=position_jitter(0.1)))

(ggplot(df_train_set, aes(x="Income", y="CapitalLoss"))+ geom_jitter(position=position_jitter(0.1)))

樹分類器

現在我們理解了我們數據中的一些關系,所以就可以使用 sklearn.tree.DecisionTreeClassifier 創建一個簡單的樹分類器模型。然而,為了使用這一模型,我們需要把所有我們的非數值數據轉化成數值型數據。我們可以直接在 Pandas 數據框架中使用 sklearn.preprocessing.LabeEncoder 模塊和 sklearn_pandas 模塊就可以輕松地完成這一步驟。

mapper = DataFrameMapper([('AgeGroup', LabelEncoder()),('Education', LabelEncoder()),('Workclass', LabelEncoder()),('MaritalStatus', LabelEncoder()),('Occupation', LabelEncoder()),('Relationship', LabelEncoder()),('Race', LabelEncoder()),('Sex', LabelEncoder()),('Income', LabelEncoder())], df_out=True, default=None)

cols = list(df_train_set.columns)
cols.remove("Income")
cols = cols[:-3] + ["Income"] + cols[-3:]

df_train = mapper.fit_transform(df_train_set.copy())
df_train.columns = cols

df_test = mapper.transform(df_test_set.copy())
df_test.columns = cols

cols.remove("Income")
x_train, y_train = df_train[cols].values, df_train["Income"].values
x_test, y_test = df_test[cols].values, df_test["Income"].values

現在我們用正確的形式對數據進行了訓練和測試,已創建了我們的第一個模型!

treeClassifier = DecisionTreeClassifier()
treeClassifier.fit(x_train, y_train)
treeClassifier.score(x_test, y_test)

最簡單的且沒有優化的概率分類器模型可以達到 83.5% 的精度。在分類問題中,混淆矩陣(confusion matrix)是衡量模型精度的好方法。使用下列代碼我們可以繪制任意基于樹的模型的混淆矩陣。

import itertoolsfrom sklearn.metrics import confusion_matrixdef plot_confusion_matrix(cm, classes, normalize=False):"""
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    cmap = plt.cm.Blues
    title = "Confusion Matrix"if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        cm = np.around(cm, decimals=3)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    thresh = cm.max() / 2.for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, cm[i, j],
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

現在,我們可以看到第一個模型的混淆矩陣:

y_pred = treeClassifier.predict(x_test)
cfm = confusion_matrix(y_test, y_pred, labels=[0, 1])
plt.figure(figsize=(10,6))
plot_confusion_matrix(cfm, classes=["<=50K", ">50K"], normalize=True)

我們發現多數類別(<=50K)的精度為 90.5%,少數類別(>50K)的精度只有 60.8%。

讓我們看一下調校此簡單分類器的方法。我們能使用帶有 5 折交叉驗證的 GridSearchCV() 來調校樹分類器的各種重要參數。

from sklearn.model_selection import GridSearchCV
parameters = {'max_features':(None, 9, 6),'max_depth':(None, 24, 16),'min_samples_split': (2, 4, 8),'min_samples_leaf': (16, 4, 12)}

clf = GridSearchCV(treeClassifier, parameters, cv=5, n_jobs=4)
clf.fit(x_train, y_train)
clf.best_score_, clf.score(x_test, y_test), clf.best_params_
(0.85934092933263717,
0.85897672133161351,
{'max_depth': 16,
'max_features': 9,
'min_samples_leaf': 16,
'min_samples_split': 8})

經過優化,我們發現精度上升到了 85.9%。在上方,我們也可以看見最優模型的參數。現在,讓我們看一下 已優化模型的混淆矩陣(confusion matrix):

y_pred = clf.predict(x_test)
cfm = confusion_matrix(y_test, y_pred, labels=[0, 1])
plt.figure(figsize=(10,6))
plot_confusion_matrix(cfm, classes=["<=50K", ">50K"], normalize=True)

經過優化,我們發現在兩種類別下,預測精度都有所提升。

決策樹的局限性

決策樹有很多優點,比如:

  • 易于理解、易于解釋
  • 可視化
  • 無需大量數據準備。不過要注意,sklearn.tree 模塊不支持缺失值。
  • 使用決策樹(預測數據)的成本是訓練決策時所用數據的對數量級。

但這些模型往往不直接使用,決策樹一些常見的缺陷是:

  • 構建的樹過于復雜,無法很好地在數據上實現泛化。
  • 數據的微小變動可能導致生成的樹完全不同,因此決策樹不夠穩定。
  • 決策樹學習算法在實踐中通常基于啟發式算法,如貪婪算法,在每一個結點作出局部最優決策。此類算法無法確保返回全局最優決策樹。
  • 如果某些類別占據主導地位,則決策樹學習器構建的決策樹會有偏差。因此推薦做法是在數據集與決策樹擬合之前先使數據集保持均衡。
  • 某些類別的函數很難使用決策樹模型來建模,如 XOR、奇偶校驗函數(parity)和數據選擇器函數(multiplexer)。

大部分限制可以通過改善決策樹輕易解決。在下面的內容中,我們將介紹相關的幾個概念,重點介紹袋裝和隨機森林。

剪枝

由于決策樹容易對數據產生過擬合,因此分支更少(即減少區域 R_1, … ,R_J)的小樹雖然偏差略微高一點,但其產生的方差更低,可解釋性更強。處理上述問題的一種方法是構建一棵樹,每個分支超過某個(高)閾值造成葉結點誤差率 Qm 下降,則結束構建。但是,由于分裂算法的貪婪本質,它其實很短視。決策樹早期看似無用的一次分裂有可能會導致之后一次優秀的分裂,并使得 Qm 大幅下降。

因此,更好的策略是構建一個非常大的樹 T_0,然后再剪枝,得到一棵子樹。剪枝可以使用多種策略。代價復雜度剪枝(Cost complexity pruning),又叫最弱連接剪枝(weakest link pruning),就是其中一種行之有效的策略。除了考慮每一個可能的子樹之外,還需要考慮由非負調參(nonnegative tuning parameter)α 索引的樹序列。每一個 α 值都對應一個盡可能小的子樹 T⊂T_0。

這里∣T∣代表樹 T 中葉結點的數量,R_m 代表第 m 個葉結點對應的矩形(預測器空間的子集),yhat_Rm 是 Rm 的預測值,即 Rm 中訓練樣本預測值的均值(或分類樹中的模式響應)。調整參數 α 控制子樹復雜度之間的權衡,對訓練數據進行擬合。當 α= 0 的時候,子樹 T 等同于 T_0。當α的值增長時,構建具備多個子結點的樹需要付出代價,這樣,要想得到更小的子樹,上述公式將達到最小化。我們可以使用某種交叉驗證方法選擇剪枝參數 α 。

注意,目前 sklearn.tree 決策樹分類器(和回歸器)不支持剪枝。

袋裝(Bootstrap Aggregating——Bagging)

在統計學中,Bootstrap 是依靠替換隨機采樣的任意試驗或度量。我們從上文可以看見,決策樹會受到高方差的困擾。這意味著如果我們把訓練數據隨機分成兩部分,并且給二者都安置一個決策樹,我們得到的結果可能就會相當不同。Bootstrap 聚集,或者叫做袋裝,是減少統計學習方法的方差的通用過程。

給定一組 n 個獨立的樣本觀測值 Z_1,Z_2,...,Z_n,每一個值的方差均為 *σ^*2,樣本觀測值的均值方差為 *σ^*2/*n*。換句話說,對一組觀測值取平均會減小方差。因此一種減小方差的自然方式,也就是增加統計學習方法預測精度的方式,就是從總體中取出很多訓練集,使用每一個訓練集創建一個分離的預測模型,并且對預測結果求取平均值。

這里有一個問題,即我們不能獲取多個訓練數據集。相反,我們可以通過從(單一)訓練數據集提取重復樣本進行自助法(bootstrap)操作。在這種方法中,我們生成了 B 個不同的自助訓練數據集。我們隨后在第 b 個自助訓練數據集得到了一個預測結果,從而獲得一個聚集預測(aggregate prediction)。

這就叫做袋裝(bagging)。注意,聚集(aggregating)在回歸和分類問題中可能有不同的均值。當平均預測值在回歸問題中的效果很好時,我們將會需要使用多數票決(majority vote):由于分類問題中的聚集機制,整體預測就是在 B 個預測值中最常出現的那個主要類別。

Out-of-Bag(OOB)誤差

Bagging 方法最大的優勢是我們可以不通過交叉驗證而求得測試誤差。回想一下,Bagging 方法的精髓是多棵樹可以重復地擬合觀察樣本的自助子集。平均而言,每一個袋裝樹可以利用 2/3 的觀察樣本。而剩下的 1/3 觀察樣本就可以稱為 out-of-bag (OOB) 觀察樣本,它們并不會擬合一一棵給定袋裝樹。我們可以使用每一棵樹的 OOB 觀察樣本而計算第 i 個觀察樣本的預測值,這將會導致大約有 B/3 的預測值可以預測第 i 個觀察樣本。現在我們可以使用和 Bagging(平均回歸和大多數投票分類)類似的聚集技術,我們能獲得第 i 個觀察樣本的單一預測值。我們可以用這種方式獲得 n 個觀察樣本的 OOB 預測,因此總體的 OOB MSE(回歸問題)和分類誤差率(分類問題)就能計算出來。OOB 誤差結果是 Bagging 模型測試誤差的有效估計,因為每一個樣本的預測值都是僅僅使用不會進行擬合訓練模型的樣本。

特征重要性度量

通過使用單一樹,Bagging 通常會提升預測的精確度。但是,解釋最終的模型可能很困難。當我們袋裝大量的樹時,就不再可能使用單一的樹表征最終的統計學習流程,因此,Bagging 是以犧牲闡釋性能力為代價來提升預測精確度的。有趣的是,一個人可使用 RSS(用于 bagging 回歸樹)或者基尼指數(用于 bagging 分類樹)得到每一個預測器的整體總結。在 bagging 回歸樹的情況中,我們可以記錄由于所有的 B 樹上平均的給定預測分子分裂而造成的 RSS 減少的所有數量。一個大的值表示一個重要的預測器。相似地,在 bagging 分類樹的情況下,我們可以添加由于所有的 B 樹上平均的給定預測分子分裂而造成的基尼系數降低的所有數量。一旦訓練完成,sklearn 模塊的不同袋裝樹(bagged tree)學習方法可直接訪問特征的重要性數據作為屬性。

隨機森林模型

雖然袋裝技術(Bagging)通過降低方差而提高了一般決策樹的預測性能,但它還遇到了其他缺點:Bagging 要求我們在自助樣本上生成整棵樹,這就增加了 B 倍計算復雜度。此外,因為基于 Bagging 的樹是相關聯的,預測精度會根據 B 而飽和。

隨機森林通過隨機擾動而令所有的樹去相關,因此隨機森林要比 Bagging 性能更好。隨機森林不像 Bagging,在構建每一棵樹時,每一個結點分割前都是采用隨機樣本預測器。因為在核心思想上,隨機森林還是和 Bagging 樹一樣,因此其在方差上有所減少。此外,隨機森林可以考慮使用大量預測器,不僅因為這種方法減少了偏差,同時局部特征預測器在樹型結構中充當重要的決策。

隨機森林可以使用巨量的預測器,甚至預測器的數量比觀察樣本的數量還多。采用隨機森林方法最顯著的優勢是它能獲得更多的信息以減少擬合數值和估計分割的偏差。

通常我們會有一些預測器能主導決策樹的擬合過程,因為它們的平均性能始終要比其他一些競爭預測器更好。因此,其它許多對局部數據特征有用的預測器并不會選定作為分割變量。隨著隨機森林計算了足夠多的決策樹模型,每一個預測器都至少有幾次機會能成為定義分割的預測器。大多數情況下,我們不僅僅只有主導預測器,特征預測器也有機會定義數據集的分割。

隨機森林有三個主要的超參數調整:

  • 結點規模:隨機森林不像決策樹,每一棵樹葉結點所包含的觀察樣本數量可能十分少。該超參數的目標是生成樹的時候盡可能保持小偏差。
  • 樹的數量:在實踐中選擇數百棵樹一般是比較好的選擇。
  • 預測器采樣的數量:一般來說,如果我們一共有 D 個預測器,那么我們可以在回歸任務中使用 D/3 個預測器數作為采樣數,在分類任務中使用 D^(1/2) 個預測器作為抽樣。 

隨機森林模型案例

使用和上文一樣的收入數據,現在我們構建一個包含 500 棵樹的簡單隨機森林分類器模型:

rclf = RandomForestClassifier(n_estimators=500)
rclf.fit(x_train, y_train)
rclf.score(x_test, y_test)

即使沒有任何優化,我們仍然發現模型性能可以和已優化決策樹分類器相媲美,并且測試分達到了 85.1%。按照下面的混淆矩陣,我們發現簡單的隨機森林和經過優化的樹型分類器表現差不多,其在主要類別(<=50K 收入)的預測精度達到了 92.1%,而在少數類別(>50K 收入)上達到了 62.6%。

rclf = RandomForestClassifier(n_estimators=500)
rclf.fit(x_train, y_train)
rclf.score(x_test, y_test)

正如前面所探討的,隨機森林模型還提供了特征重要性的度量方法。我們可以在下圖中看到目前模型不同特征的重要性:

importances = rclf.feature_importances_
indices = np.argsort(importances)
cols = [cols[x] for x in indices]
plt.figure(figsize=(10,6))
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='b', align='center')
plt.yticks(range(len(indices)), cols)
plt.xlabel('Relative Importance')

現在我們可以嘗試優化我們的隨機森林模型,如下我們可以使用帶 5-折交叉驗證的 GridSearchCV() 操作來優化隨機森林:

parameters = {'n_estimators':(100, 500, 1000),'max_depth':(None, 24, 16),'min_samples_split': (2, 4, 8),'min_samples_leaf': (16, 4, 12)}

clf = GridSearchCV(RandomForestClassifier(), parameters, cv=5, n_jobs=8)
clf.fit(x_train, y_train)
clf.best_score_, clf.best_params_
0.86606676699118579
{'max_depth': 24,
 'min_samples_leaf': 4,
 'min_samples_split': 4,
 'n_estimators': 1000}
0.86606676699118579
{'max_depth': 24,
'min_samples_leaf': 4,
'min_samples_split': 4,
'n_estimators': 1000}

我們可以看到現在的模型要顯著地比前面的更好一些,并且預測率達到了 86.6%。按照下面的混淆矩陣,新模型在主要類別的預測精度上有顯著的提升,并且在少數類別的預測上精度只稍微降低了一點。這是非平衡數據普遍存在的問題。

rclf2 = RandomForestClassifier(n_estimators=1000,max_depth=24,min_samples_leaf=4,min_samples_split=8)
rclf2.fit(x_train, y_train)

y_pred = rclf2.predict(x_test)
cfm = confusion_matrix(y_test, y_pred, labels=[0, 1])
plt.figure(figsize=(10,6))
plot_confusion_matrix(cfm, classes=["<=50K", ">50K"], normalize=True)

最后,下面展示了對優化后模型比較重要的特征。

importances = rclf2.feature_importances_
indices = np.argsort(importances)
cols = [cols[x] for x in indices]
plt.figure(figsize=(10,6))
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='b', align='center')
plt.yticks(range(len(indices)), cols)
plt.xlabel('Relative Importance')

隨機森林的局限性

除了 Bagging 樹模型的一般局限性外,隨機森林還有一些局限性:

 

  • 當我們需要推斷超出范圍的獨立變量或非獨立變量,隨機森林做得并不好,我們最好使用如 MARS 那樣的算法。
  • 隨機森林算法在訓練和預測時都比較慢。
  • 如果需要區分的類別十分多,隨機森林的表現并不會很好。

總的來說,隨機森林在很多任務上一般要比提升方法的精度差,并且運行時間也更長。所有在 Kaggle 競賽上,有很多模型都是使用的梯度提升樹算法或其他優秀的提升方法。

責任編輯:張子龍 來源: 機器之心
相關推薦

2014-07-07 10:05:57

機械學習

2017-10-18 14:11:20

機器學習決策樹隨機森林

2022-09-25 23:19:01

機器學習決策樹Python

2022-11-11 08:00:00

決策樹機器學習監督學習

2017-09-25 16:16:49

決策樹隨機森林機器學習

2021-11-08 07:11:49

決策樹數據分類器

2017-02-23 08:45:36

Python決策樹數據集

2022-10-19 11:33:07

決策樹策略搜索

2023-03-16 08:00:00

機器學習深度學習人工智能

2017-07-18 16:25:31

機器學習算法決策樹

2017-05-10 15:41:29

機器學習算法數據

2018-02-02 15:50:07

決策樹Apache Spar數據

2016-09-30 16:12:47

GBDT算法決策樹

2017-11-21 13:00:20

機器學習決策樹可視化

2023-08-11 17:30:54

決策樹機器學習算法

2019-05-15 09:00:00

決策樹機器學習人工智能

2022-12-21 14:39:35

機器學習案發決策樹

2022-01-24 09:00:00

機器學習決策樹算法

2017-12-12 12:24:39

Python決策樹

2017-09-11 13:33:44

大數據數據可視化決策樹
點贊
收藏

51CTO技術棧公眾號

亚洲国产欧美在线| 成人美女视频在线观看18| 在线亚洲男人天堂| 国产美女视频免费看| а√天堂资源地址在线下载| 成人国产精品免费观看| 日本欧美一级片| 日韩精品123区| 欧美人妖视频| 欧美日韩一区成人| 日韩网站在线免费观看| a中文在线播放| 高清视频一区二区| 国产精品欧美日韩久久| 久久国产精品二区| 日韩av专区| 日韩av在线不卡| 国产精欧美一区二区三区白种人| 国产高清自产拍av在线| ㊣最新国产の精品bt伙计久久| 国产日韩在线一区二区三区| 亚洲最新av网站| 亚洲在线成人| 色综合久久悠悠| jizzjizzjizz国产| 清纯唯美亚洲经典中文字幕| 欧美一区在线视频| 日本女优爱爱视频| 999av小视频在线| 亚洲精品国产一区二区精华液 | 国产精品流白浆在线观看| 欧美性xxxxxxxx| 欧美三级一级片| 久久久123| 亚洲色大成网站www久久九九| 欧美成人蜜桃| 香蕉久久一区二区三区| 国产成人欧美日韩在线电影| 国产玖玖精品视频| 国产男人搡女人免费视频| 日韩视频久久| 久久乐国产精品| 国产成人免费在线观看视频| 欧美日韩国产传媒| 日韩电视剧免费观看网站| 91超薄肉色丝袜交足高跟凉鞋| 四虎精品一区二区免费| 欧洲国产伦久久久久久久| 国产亚洲天堂网| 日韩大片免费观看| 精品久久中文字幕| 国产中文字幕二区| 一区二区精品伦理...| 香蕉久久一区二区不卡无毒影院| 99久久99久久精品| 久久国产精品黑丝| 亚洲高清视频中文字幕| 久久99久久久久久| 日本蜜桃在线观看视频| 精品美女国产在线| 免费日韩视频在线观看| 免费亚洲电影| 91激情五月电影| 一区二区三区免费播放| 国产69精品久久久久9999人| 欧美视频一区在线观看| 最新av免费在线观看| 成人在线视频区| 欧美一级黄色大片| 男男一级淫片免费播放| 亚洲都市激情| 一本大道久久加勒比香蕉| 亚洲天堂最新地址| 综合久久一区| 久久久噜噜噜久久久| 91蜜桃视频在线观看| 亚洲一区图片| 国产精品视频1区| 999免费视频| 成人免费视频一区二区| 欧美日韩一区二区三区在线视频| 黄色小视频在线免费观看| 中文字幕亚洲不卡| 欧美日韩激情四射| 高清av不卡| 欧美日韩精品一区二区在线播放| 少妇愉情理伦片bd| 欧美一级一片| 综合av色偷偷网| 久热这里只有精品在线| 可以看av的网站久久看| 成人免费网视频| 日韩性xxxx| 欧美—级在线免费片| 精品视频在线观看一区二区| 欧美男女交配| 91精品国产综合久久国产大片| 波多野结衣先锋影音| 成人黄色小视频| 久久久久久久久网站| 青青视频在线免费观看| 国产又粗又猛又爽又黄91精品| 国产精品一区二区三区免费| 岛国视频免费在线观看| 亚洲午夜精品网| 一区二区xxx| 国产厕拍一区| 日韩中文字幕视频在线观看| 国产午夜精品无码一区二区| 日本aⅴ免费视频一区二区三区| av一区二区三区四区电影| 国产尤物视频在线| 亚瑟在线精品视频| 一级黄色在线播放| 国产一区二区三区四区五区| 欧美高清无遮挡| 中文字幕精品一区二| 成人午夜免费视频| 手机成人av在线| 中文在线免费视频| 精品久久一区二区三区| 美女av免费看| 老牛国产精品一区的观看方式| 丁香五月网久久综合| 一级毛片视频在线观看| 五月综合激情网| 中文字幕在线国产| 欧美一区二区三区免费看| 国产精品一区二区久久精品| 色视频在线观看| 亚洲成a人片综合在线| 激情图片中文字幕| 日韩精品一区二区三区免费观看| 欧美在线观看日本一区| 韩国av电影在线观看| 亚洲蜜臀av乱码久久精品蜜桃| 日韩亚洲在线视频| 亚洲三级网页| 午夜剧场成人观在线视频免费观看| 99国产精品欲| 国产精品护士白丝一区av| 精品少妇无遮挡毛片| 亚洲性视频大全| 97在线视频免费看| 免费观看成年人视频| 亚洲精品菠萝久久久久久久| 国产美女视频免费看| 99久久精品费精品国产风间由美| 国产精品电影久久久久电影网| 欧美性孕妇孕交| 欧美三级免费观看| 亚洲 小说 欧美 激情 另类| 六月天综合网| 日韩资源av在线| 日韩国产网站| 揄拍成人国产精品视频| 中文字幕人妻互换av久久| 国产精品污网站| jizz18女人| 99精品视频在线| 成人羞羞国产免费| av免费在线免费| 日韩精品一区二区三区在线观看| 午夜剧场免费在线观看| 国产黑丝在线一区二区三区| 台湾无码一区二区| 欧美做受69| 国产精品久久久久久久久久久不卡| 国产一区精品| 制服丝袜成人动漫| 国产性70yerg老太| 26uuu欧美| 污污网站免费看| 亚洲色图二区| 国产成人亚洲欧美| 精品国产免费人成网站| 在线精品国产欧美| a天堂在线观看视频| 亚洲午夜国产一区99re久久| 亚洲久久久久久| 日韩高清在线电影| 国产日产欧美一区二区| 亚洲一区二区免费在线观看| 7m精品福利视频导航| 日韩精品系列| 欧美精品成人一区二区三区四区| 91成人福利视频| 91丨porny丨在线| 一本色道久久亚洲综合精品蜜桃| 综合日韩在线| 欧美一区二区三区精美影视| 亚洲成人a级片| 久久久亚洲精选| 国产黄在线观看免费观看不卡| 欧美人与z0zoxxxx视频| 99免费在线观看| 欧美激情一区二区三区蜜桃视频| 亚欧美一区二区三区| 性8sex亚洲区入口| 日本黄色a视频| 伊人久久大香线蕉综合网蜜芽| 成人国产在线视频| 美女福利一区二区| 欧美精品在线免费观看| 狠狠v欧美ⅴ日韩v亚洲v大胸| 欧美一区二区三区的| 毛片在线免费视频| 亚洲男人天堂av| 精品成人av一区二区三区| 国产成人免费视频网站高清观看视频 | 亚洲美女免费在线| 日本美女xxx| 不卡欧美aaaaa| 九九热视频免费| 视频在线观看一区| 男人日女人视频网站| 一区二区电影在线观看| 色噜噜一区二区| 欧美精品密入口播放| 5566中文字幕一区二区| 国产精品99| 欧美做爰性生交视频| 免费在线中文字幕| 欧美成在线视频| 欧美一区二区三区在线观看免费| 精品亚洲一区二区三区在线观看 | 亚洲毛片在线看| 亚洲精品久久久蜜桃动漫 | 亚洲精品成a人| 成年人看的免费视频| 久久久91精品国产一区二区精品| 人妻 丝袜美腿 中文字幕| 国内欧美视频一区二区| 色婷婷综合网站| 日本伊人色综合网| 乱子伦视频在线看| 羞羞视频在线观看欧美| 黄页网站大全在线观看| 亚洲国产电影| www.夜夜爱| 黄色日韩在线| 蜜桃视频一区二区在线观看| 性欧美69xoxoxoxo| 中文字幕剧情在线观看一区| 日本在线电影一区二区三区| 日韩精品一区二区三区丰满| 亚欧日韩另类中文欧美| 精品产品国产在线不卡| 精品成人自拍视频| 国内视频一区二区| 欧美巨大xxxx| 欧美一卡2卡3卡4卡无卡免费观看水多多 | 亚洲欧美日本一区| 99国产欧美另类久久久精品| 日韩av无码一区二区三区不卡| 成人一级黄色片| 久久性爱视频网站| 成人激情免费电影网址| 亚洲天堂av网站| 91麻豆精品秘密| 丝袜美腿中文字幕| 国产欧美精品区一区二区三区 | 日本激情一区二区三区| 欧美精品一区二区三区蜜桃视频| 丰满少妇被猛烈进入| 亚洲成人网在线| 全色精品综合影院| 国产一区二区三区直播精品电影 | 粉嫩虎白女毛片人体| 日本不卡一二三区黄网| 中文字幕亚洲欧洲| 国产不卡视频一区| 一区二区三区少妇| 国产日韩在线不卡| 91ts人妖另类精品系列| 亚洲精品视频在线看| 国产在线观看成人| 色综合激情五月| 国产又粗又猛又爽又黄视频 | 亚洲精品乱码久久久久久蜜桃图片| 99精品欧美一区二区三区小说 | 精品久久久亚洲| 亚洲精品免费在线看| 中文字幕免费一区二区三区| 日韩av综合在线观看| 麻豆成人免费电影| 无码人妻丰满熟妇啪啪网站| 久久先锋影音av| 亚洲一二三在线观看| 午夜精品久久久久久久蜜桃app| 怡红院av久久久久久久| 欧美一区二区性放荡片| 五月婷在线视频| 久久精品国产亚洲一区二区| 成人在线黄色电影| 91精品久久久久久综合乱菊| 国产精品男女| 一本一本久久a久久精品综合妖精| 激情综合激情| 久久国产这里只有精品| 成人毛片老司机大片| 韩国一级黄色录像| 精品电影在线观看| 99久久久国产精品无码免费 | 曰韩不卡视频| 麻豆视频在线免费观看| 97精品视频在线观看| 在线免费成人| 日本在线成人一区二区| 红桃视频国产精品| 在线看免费毛片| 国产婷婷色一区二区三区在线| 校园春色 亚洲| 欧美日韩精品一区二区三区四区| 人妻一区二区三区| 18欧美亚洲精品| 六月激情综合网| 激情久久五月天| 熟女少妇一区二区三区| 一卡二卡三卡日韩欧美| 亚洲一区二区视频在线播放| 日韩av有码在线| 牛牛在线精品视频| 91美女高潮出水| 成人久久电影| 91精品91久久久中77777老牛| 国产一区二区剧情av在线| 国产精品酒店视频| 日韩欧美国产成人| 女人18毛片水真多18精品| 久久国产精品电影| 日韩电影精品| 亚洲欧洲久久| 三级欧美韩日大片在线看| 韩国无码一区二区三区精品| 亚洲国产三级在线| 丰满肉嫩西川结衣av| 久久99亚洲热视| 精品视频在线观看网站| 青青草原国产免费| 乱一区二区av| 久久久久99精品成人| 欧美亚洲一区三区| 国产小视频在线播放| 欧美在线视频播放| 日韩极品少妇| 久久久久人妻精品一区三寸| 91网站视频在线观看| 午夜毛片在线观看| 日韩国产精品一区| 婷婷六月国产精品久久不卡| 久久天堂国产精品| 免费亚洲一区| 亚洲第一成人网站| 欧美专区在线观看一区| 91视频在线观看| 成人福利视频网| 亚洲午夜精品一区二区国产 | 色猫猫成人app| 亚洲人成77777| 精品中文字幕一区二区| 久久久久久视频| 日韩午夜激情av| 激情国产在线| 日韩色妇久久av| 激情综合五月婷婷| 久久久久久久9999| 日韩av网址在线观看| 国模冰冰炮一区二区| 亚欧精品在线| 国产精品白丝av| 在线看成人av| 亚洲偷欧美偷国内偷| 日本久久一区| 人人干视频在线| 国产校园另类小说区| 91麻豆成人精品国产免费网站| 久久艳片www.17c.com| 加勒比中文字幕精品| 日韩av片网站| 亚洲影院在线观看| 日本亚洲欧美| 成人黄色免费看| 亚洲二区免费| 一级在线观看视频| 欧美本精品男人aⅴ天堂| 一级毛片久久久| 国产精品亚洲天堂| 91网站在线播放| 国产一区二区网站| 欧美精品videosex性欧美| 久久99精品久久久久久园产越南| 亚洲成人福利在线| 亚洲va国产va欧美va观看| av网站在线免费播放| 99在线国产| 青青草97国产精品免费观看 | 国产精品久久亚洲7777| 国产欧美在线| 侵犯稚嫩小箩莉h文系列小说|