決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

資料派THU發表於2020-06-11
用一個簡單的比喻來解釋決策樹 vs 隨機森林

讓我們從一個思維實驗來闡述決策樹和隨機森林之間的差異。

假設一個銀行要給一位顧客批准一筆小額貸款,銀行需要迅速做出決策。銀行檢查了這位顧客的信用記錄和他的財政狀況,並發現他還沒有還上之前的貸款。因此,銀行拒絕了他的申請。

但是,這筆貸款跟銀行所擁有的鉅額資金相比實在是小的可憐,銀行本可以輕易地批准這筆貸款並且也不會承擔很多風險。於是,銀行失去了一次賺錢的機會。

現在,銀行又來了一個貸款申請,但是這次銀行想出了一種不同的策略——多重決策過程。有時它會先檢查信用歷史,有時它會先檢查顧客的財政狀況和貸款額度。然後,銀行會把這些多重決策過程的結果進行整合,並最終決定是否將貸款發放給顧客。

即使這個過程比之前更費時,但是銀行依然能夠透過此途徑獲利。這是一個基於單一決策過程進行集合決策的經典案例。現在,我的問題來了——你知道這兩個過程表徵的是什麼嗎?

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

這裡是決策樹和隨機森林,我們將詳細探究這種觀點,深入挖掘兩種方法的主要差異,並且對關鍵問題進行回覆——你應該選擇那種機器學習演算法?

目錄
  • 決策樹簡介

  • 隨機森林概覽

  • 隨機森林和決策樹的衝突(程式碼)

  • 為什麼隨機森林優於決策樹?

  • 決策樹vs隨機森林——你應該在何時選擇何種演算法?

決策樹簡介

決策樹是一種有監督的機器學習演算法,該方法可以用於解決分類和迴歸問題。決策樹可以簡單地理解為達到某一特定結果的一系列決策。這裡是一幅決策樹的闡述圖(使用我們上面的案例):

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

讓我們來理解這棵樹是如何工作的。

首先,它檢查了顧客是否有良好的信用歷史。基於此,它將顧客分為兩組,也就是良好信用組和不良信用組。然後,它檢查了顧客的收入,並再次將顧客分為兩類。最後,它檢查了顧客申請的貸款額度。基於這三種特徵的檢測,決策樹會決定是否透過顧客的貸款申請。

特徵/屬性和調節可能會隨著資料和問題複雜度的改變而改變,但是整體的理念是一致的。所以,一棵決策樹會基於一系列特徵做出一系列的決策,在本例中是信用歷史、收入和貸款額度。

現在,你可能會疑惑:

“為什麼決策樹會先檢測信用得分而不是收入呢?”

特徵重要性和特質的檢測順序是基於如基尼不純度指數或資訊增益等標準來決定的。這些概念的解釋不在本文所探討的範圍內,但是你可以透過以下的資料來學習決策樹相關知識:
  • 基於樹的演算法:從零開始的完整教程(R & Python)

https://www.analyticsvidhya.com/blog/2016/04/tree-based-algorithms-complete-tutorial-scratch-in-python/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

  • 從決策樹開始(免費課程)

https://courses.analyticsvidhya.com/courses/getting-started-with-decision-trees?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

注:本文的想法是比較決策樹和隨機森林。因此,我不會詳細解釋基本概念,但是我將提供相關連結以便於你可以進一步探究。

隨機森林概覽

決策樹演算法很容易理解和解釋。但是通常來說,一棵簡單的樹並不能產生有效的結果。這就是隨機森林演算法的用武之地。

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

隨機森林是基於樹的機器學習演算法,該演算法利用了多棵決策樹的力量來進行決策。顧名思義,它是由一片樹木組成的“森林”!

但是為什麼要稱其為“隨機森林”呢?這是因為它是隨機創造的決策樹組成的森林。決策樹中的每一個節點是特徵的一個隨機子集,用於計算輸出。隨機森林將單個決策樹的輸出整合起來生成最後的輸出結果。

簡單來說:

隨機森林演算法用多棵(隨機生成的)決策樹來生成最後的輸出結果。”

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

這種結合了多個單一模型的輸出(也被稱為弱學習)的過程被稱為整合學習。如果你想閱讀更多關於隨機森林和其他整合學習演算法如何工作,請查閱一下文章:
  • 從零開始構建一個隨機森林&理解真實世界的資料產品

https://www.analyticsvidhya.com/blog/2018/12/building-a-random-forest-from-scratch-understanding-real-world-data-products-ml-for-programmers-part-3/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

  • 隨機森林超引數調優——一個初學者的指南

https://www.analyticsvidhya.com/blog/2020/03/beginners-guide-random-forest-hyperparameter-tuning/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

  • 整合學習的綜合指南(使用Python程式碼)

https://www.analyticsvidhya.com/blog/2018/06/comprehensive-guide-for-ensemble-models/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

  • 如何在機器學習中建立整合模型?( R程式碼)

https://www.analyticsvidhya.com/blog/2017/02/introduction-to-ensembling-along-with-implementation-in-r/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

現在的問題是,我們怎樣選擇決策樹和隨機森林演算法呢?讓我們在做出結論之前,先看看過兩種演算法的具體情況。

隨機森林和決策樹的衝突(程式碼)

本部分,我們將使用Python實現決策樹和隨機森林演算法來解決一道二分類問題。我們接下來將會比較它們的結果並看一看那種更適合解決我們的問題。
 
我們將基於Analytics Vidhya’s DataHack(https://datahack.analyticsvidhya.com/contest/practice-problem-loan-prediction-iii/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm)平臺的貸款預測資料集進行分析。這是一個二分類問題,我們需要基於特定的特徵集來決定一個人是否可被批准獲得貸款。

注:你可以去DataHack(https://datahack.analyticsvidhya.com/contest/all/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm )平臺並在不同線上機器學習競賽中與他人競爭,並且有機會獲得令人興奮的獎品。

準備好程式設計了嗎?

第一步:載入庫和資料集

讓我們從匯入所需的Python庫和我們的資料集開始:

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

資料庫包括614列和13個特徵,包括信用歷史(credit history),婚姻狀況(marital status),貸款額度(loan amount),和性別(gender)。在這裡,目標變數是是否貸款(Loan_Status),該變數表明是否一個人能夠被批准獲得貸款。

第二步:資料預處理

現在到了任何資料科學專案中最為關鍵的部分——資料預處理和特徵工程。本部分中,我將處理資料中的類別變數以及缺失值插補。

我將使用特定的模式對類別變數中的缺失值進行插補,並且對連續型變數用平均值插補(每列分別插補)。我們也將對類別變數進行標籤設定。你可以閱讀以下文章來了解更多關於標籤編碼的內容。

https://www.analyticsvidhya.com/blog/2016/07/practical-guide-data-preprocessing-python-scikit-learn/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

# Data Preprocessing and null values imputation
# Label Encoding
df['Gender']=df['Gender'].map({'Male':1,'Female':0})
df['Married']=df['Married'].map({'Yes':1,'No':0})
df['Education']=df['Education'].map({'Graduate':1,'Not Graduate':0})
df['Dependents'].replace('3+',3,inplace=True)
df['Self_Employed']=df['Self_Employed'].map({'Yes':1,'No':0})
df['Property_Area']=df['Property_Area'].map({'Semiurban':1,'Urban':2,'Rural':3})
df['Loan_Status']=df['Loan_Status'].map({'Y':1,'N':0})
#Null Value Imputation
rev_null=['Gender','Married','Dependents','Self_Employed','Credit_History','LoanAmount','Loan_Amount_Term']
df[rev_null]=df[rev_null].replace({np.nan:df['Gender'].mode(),
                                   np.nan:df['Married'].mode(),
                                   np.nan:df['Dependents'].mode(),
                                   np.nan:df['Self_Employed'].mode(),
                                   np.nan:df['Credit_History'].mode(),
                                   np.nan:df['LoanAmount'].mean(),
                                   np.nan:df['Loan_Amount_Term'].mean()})rfc_vs_dt-2.py hosted with ❤ by GitHub

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

第三步:創造訓練集和測試集

現在,讓我們以80:20的比例進行訓練集和測試集的劃分:

X=df.drop(columns=['Loan_ID','Loan_Status']).values
Y=df['Loan_Status'].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.2, random_state = 42)rfc_vs_dt-3.py hosted with ❤ by GitHub

讓我們一眼所劃分的訓練集和測試集:

print('Shape of X_train=>',X_train.shape)
print('Shape of X_test=>',X_test.shape)
print('Shape of Y_train=>',Y_train.shape)
print('Shape of Y_test=>',Y_test.shape)rfc_vs_dt-4.py hosted with ❤ by GitHub

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

真棒!現在我們已經準備好進入下一個階段構建決策樹和隨機森林模型了!

第四步:構建和評估模型

既然我們已經有了訓練和測試集,是時候訓練模型和分類貸款申請了。首先,我們將在資料機上進行決策樹的訓練:
# Building Decision Tree
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(criterion = 'entropy', random_state = 42)
dt.fit(X_train, Y_train)
dt_pred_train = dt.predict(X_train)rfc_vs_dt-5.py hosted with ❤ by GitHub
接下來,我們將使用F1-Score對模型進行評估。F1-Score是由公式給出的精度和召回的調和平均數:

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

你可以透過以下文章來了解更多關於F1-Score和其他的評估方法:

https://www.analyticsvidhya.com/blog/2019/08/11-important-model-evaluation-error-metrics/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

讓我們來評價F1-Score模型的表現:

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

# Evaluation on Training set
dt_pred_train = dt.predict(X_train)
print('Training Set Evaluation F1-Score=>',f1_score(Y_train,dt_pred_train))rfc_vs_dt-6.py hosted with ❤ by GitHub# Evaluating on Test set
dt_pred_test = dt.predict(X_test)
print('Testing Set Evaluation F1-Score=>',f1_score(Y_test,dt_pred_test))rfc_vs_dt-7.py hosted with ❤ by GitHub

在這裡,你可以看到決策樹在樣本內估計的表現非常好,但是在樣本外估計的表現迅速下降。為什麼會出現這種情況呢?因為我們的決策樹在訓練集上產生了過擬合隨機森林能否解決這一問題?

建立隨機森林模型

讓我們來看一下隨機森林模型:

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

在這裡,我們可以清楚地看到在樣本外估計當中,隨機森林模型比決策樹的表現更優。讓我們在接下來的一部分當中來討論一下背後的原因。
 # Building  Random Forest Classifier
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier(criterion = 'entropy', random_state = 42)
rfc.fit(X_train, Y_train)# Evaluating on Training set
rfc_pred_train = rfc.predict(X_train)
print('Training Set Evaluation F1-Score=>',f1_score(Y_train,rfc_pred_train))rfc_vs_dt-8.py hosted with ❤ by GitHubf1 score random forest# Evaluating on Test set
rfc_pred_test = rfc.predict(X_test)
print('Testing Set Evaluation F1-Score=>',f1_score(Y_test,rfc_pred_test))rfc_vs_dt-9.py hosted with ❤ by GitHub

為什麼我們的隨機森林模型比決策樹表現更好?

隨機森林利用了多棵決策樹的優勢。它的確不依賴於單一決策樹的特徵重要性。讓我們來看一看不同演算法給予不同特徵的特徵重要性。
feature_importance=pd.DataFrame({
    'rfc':rfc.feature_importances_,
    'dt':dt.feature_importances_
},index=df.drop(columns=['Loan_ID','Loan_Status']).columns)
feature_importance.sort_values(by='rfc',ascending=True,inplace=True)index = np.arange(len(feature_importance))
fig, ax = plt.subplots(figsize=(18,8))
rfc_feature=ax.barh(index,feature_importance['rfc'],0.4,color='purple',label='Random Forest')
dt_feature=ax.barh(index+0.4,feature_importance['dt'],0.4,color='lightgreen',label='Decision Tree')
ax.set(yticks=index+0.4,yticklabels=feature_importance.index)ax.legend()
plt.show()rfc_vs_dt-10.py hosted with ❤ by GitHub

決策樹VS隨機森林——應該使用哪種演算法?(附程式碼&連結)

正如你在上圖所見,決策樹模型基於某一個特徵集很高的重要性。但是隨機森林演算法在訓練過程中隨機選擇特徵。因此,的確不依賴於任何特定的特徵集。這是隨機森林演算法優於bagging演算法的一個特殊之處。你可以閱讀以下文章獲取更多bagging演算法知識。

https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.BaggingClassifier.html#sklearn.ensemble.BaggingClassifier 

因此,隨機森林可以更好地在資料中心進行泛化。隨機化特徵選擇可以使得隨機森林比決策樹更準確。

所以你應該選擇哪一種演算法呢——決策樹還是隨機森林

隨機森林適用於擁有大型資料集的情況,並且可解釋性不是主要考慮因素。”

決策樹更容易解釋和理解。因為隨機森林整合了多棵決策樹,更難以解釋。但是好訊息是——解釋隨機森林也並非不可能。這裡有一篇文章講了如何解釋隨機森林模型的結果:

https://www.analyticsvidhya.com/blog/2019/08/decoding-black-box-step-by-step-guide-interpretable-machine-learning-models-python/?utm_source=blog&utm_medium=decision-tree-vs-random-forest-algorithm

並且,隨機森林比起單一決策樹需要更長的訓練時間。你應該把此納入考慮,因為隨著決策樹數量的增加,所需要的訓練時間也會越長。在你面臨著緊張的機器學習專案安排過程中這可能通常是至關重要的。

但是我要說的是——儘管結果不穩定,且依賴於特定的特徵集,決策樹真的很有幫助,因為他們更容易去解釋、訓練更快。任何對資料科學缺乏知識的人都可以使用決策樹進行快速的資料驅動決策。

寫在最後的話

瞭解決策樹和隨機森林之爭是非常有必要的。在你初入機器學習領域時,這可能是一個很棘手的問題,但是本文能夠為你闡明兩者之間的異同。

原文標題:

Decision Tree vs. Random Forest – Which Algorithm Should you Use?

原文連結:

https://www.analyticsvidhya.com/blog/2020/05/decision-tree-vs-random-forest-algorithm/

相關文章