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