使用決策樹進行探索性數據分析
決策樹(DT)是最直觀的機器學習算法,其可以根據一系列簡單選擇做出復雜決策。
DT 在運籌學和數據科學領域非常實用,其成功的原因在于它遵循與人類決策過程類似的過程。該過程基于流程圖,其中每個節點都會對給定變量進行簡單的二元決策,直到我們做出最終決策。
舉個簡單的例子:買一件 T 恤。如果我想買一件 T 恤,我可能會考慮幾個變量,比如價格、品牌、尺碼和顏色。所以我從預算開始做決定:
- 如果價格超過 30 美元,我不會買。否則我會買。
- 一旦找到低于 30 美元的商品,我希望它是我喜歡的品牌。如果是,我會繼續做決定。
- 現在,它適合我嗎?我的尺寸?如果適合,我們繼續。
- 最后,如果 30 美元以下、品牌 X、尺碼 S 的襯衫是黑色的,我會買它,否則,我可以繼續尋找,或者以“我不會買它”結束我的決策過程。
決策樹過程
這個過程非常合乎邏輯且簡單,可以應用于所有類型的數據。該算法的缺點是它對數據集變化非常敏感,尤其是小數據集。因此,它很容易學習數據的微小差異并過度擬合你的機器學習模型。
DT 的這種特性可能對預測造成不小危害,但這如果用在探索性數據分析過程中將會非常出彩。
在這篇文章中,我們將學習如何利用 DT 的強大功能從數據中提取信息。
什么是 EDA?
探索性數據分析(EDA)是數據科學項目的一個階段,我們獲取數據集并探索其變量,盡可能多地了解對目標變量影響最大的因素。
在這個階段,數據科學家希望了解數據、數據如何分布、是否存在錯誤或不完整,提取數據的第一手信息,并可視化并了解每個解釋變量如何影響目標變量。
在流程中使用決策樹
由于 DT 能夠捕捉數據中最小的方差,因此使用它有助于理解變量之間的關系。由于我們只是在這里探索數據,因此我們不必非常小心地進行數據拆分或算法微調。我們只需運行 DT 即可獲得最佳信息。
數據集
這里使用的數據集是學生表現數據集根據。
# 導入庫
import pandas as pd
import seaborn as sns
sns.set_style()
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
from sklearn.tree import plot_tree
# 加載數據集
from ucimlrepo import fetch_ucirepo
# 獲取數據集
student_performance = fetch_ucirepo(id = 320)
# 數據(作為 pandas 數據框)
X = student_performance.data.features
y = student_performance.data.targets
# 收集 X 和 Y 進行可視化
df = pd.concat([X,y], axis= 1 )
df.head( 3 )
圖片
我們想要確定這些數據中的哪些變量對最終成績的影響更大G3。
使用回歸 DT 進行探索
failures現在構建一個 DT 來檢查以及absences對studytime的影響G3。
# 要探索的列
cols = [ 'failures' , 'absences' , 'studytime' ]
# 分割 X 和 Y
X = df[cols]
y = df.G3
# 擬合決策樹
dt = DecisionTreeRegressor().fit(X,y)
# 繪制 DT
plt.figure(figsize=( 20 , 10 ))
plot_tree(dt, filled= True , feature_names=X.columns, max_depth= 3 , fnotallow= 8 );
這是得出的決策樹。
決策樹
現在我們有了一個很好的可視化來了解我們列出的那些變量之間的關系。以下是我們可以從這棵樹中獲得的見解:
- 我們知道,對于每個框內第一行的條件,左邊表示“是”,右邊表示“否”。
- 不及格次數較少(< 0.5,或者說為零)的學生成績較高。只需觀察左側每個框的值都高于右側的值即可。
- 在所有沒有不及格的學生中,不及格的學生的成績studytime > 2.5更高。分數幾乎高出一分。
- 沒有不及格記錄、studytime < 1.5缺勤次數少于 22 次的 學生比學習時間較少、缺勤次數較多的學生的期末成績更高。
自由活動和外出頻率
如果我們想根據學生的自由活動時間和外出頻率來了解哪些學生的成績更高,代碼如下。
# 要探索的列
cols = [ 'freetime' , 'goout' ]
# 分割 X 和 Y
X = df[cols]
y = df.G3
# 擬合決策樹
dt = DecisionTreeRegressor().fit(X,y)
# 繪制 DT
plt.figure(figsize=( 20 , 10 ))
plot_tree(dt, filled= True , feature_names=X.columns, max_depth= 3 , fnotallow= 10 );
決策樹外出/空閑時間
變量goout和的freetime等級從 1= 非常低到 5= 非常高。請注意,那些不經常外出 (< 1.5) 且沒有空閑時間 (<1.5) 的人的分數與那些經常外出 (>4.5) 且有相當多空閑時間的人的分數一樣低。最好的分數來自那些在外出次數 > 1.5 和空閑時間在 1.5 到 2.5 范圍內之間取得平衡的人。
使用分類 DT 進行探索
可以使用分類樹算法進行相同的練習。邏輯和編碼相同,但現在顯示的結果值是預測的類,而不是值。讓我們看一個簡單的示例,使用另一個數據集,來自 Seaborn 包的Taxis 數據集,它帶來了一組紐約市的出租車運行情況。
如果我們想探究運行總金額和付款方式之間的關系,下面是代碼。
# 加載數據集
df = sns.load_dataset('taxis').dropna()
# 要探索的列
cols = ['total']
# 拆分 X 和 Y
X = df[cols]
y = df['payment']
# 擬合決策樹
dt = DecisionTreeClassifier().fit(X,y)
# 繪制樹
plt.figure(figsize=( 21 , 10 ))
plot_tree(dt, filled= True , feature_names=X.columns, max_depth= 3 ,
fnotallow= 10 , class_names=[ 'cash' , 'credit_card' ]);
出租車總費用與付款方式
只需目測結果樹,我們就能發現較低的total金額更有可能以現金支付。低于 9.32 美元的總額一般以現金支付。
寫在最后
在文我們學習了一種快速使用決策樹來探索數據集中變量之間關系的方法。
這種算法可以快速捕捉最初不容易發現的模式。我們可以利用決策樹的力量來找到數據的那些切分點,從而從中提取出重要的見解。
關于代碼的簡要說明:
在函數中plot_tree(),你可以設置使用該功能所需的級別數。你還可以在sklearn 的max_depthDT 實例中設置該超參數。這取決于你。使用它的優點是你可以快速測試許多不同的深度,而無需重新訓練模型。plot_tree
plot_tree(dt,filled= True,feature_names=X.columns,max_depth=3)