我們將學習一種更流行的機器學習算法——決策樹,我們將使用此算法從患者的歷史數據以及他們對不同藥物的反應大數據中,用訓練過的決策樹來構建分類模型預測未知患者的類別,或者說為新患者找到合適的藥物。
導入以下包
import sys
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
import sklearn.tree as tree
假設你是一名醫學研究院,收集了一組患有相同疾病患者的數據。在這些患者的治療過程中,每位患者會對5種藥物種的一種做出反應:A、B、C、X、Y。
你的一部分工作是建立一個模型,找出那種藥物可能適合未來患有相同疾病的患者。這個數據集的幾個指標(特征)是患者的年齡、性別、血壓和膽固醇,標簽是每個患者反應的藥物。
這個數據是一個多分類器的樣本,我們用訓練集來構建決策樹,然後用它來預測未知患者的類別,也就是為患者開藥。
點我下載
my_data = pd.read_csv("drug200.csv", delimiter=",")
my_data[0:5]
數據的大小
my_data.shape
(200, 6)
用 my_data 作為 Drug.csv 的數據,聲明以下變量:
把目標列的名稱給刪了。
X = my_data[['Age', 'Sex', 'BP', 'Cholesterol', 'Na_to_K']].values
X[0:5]
array([[23, 'F', 'HIGH', 'HIGH', 25.355],
[47, 'M', 'LOW', 'HIGH', 13.093],
[47, 'M', 'LOW', 'HIGH', 10.113999999999999],
[28, 'F', 'NORMAL', 'HIGH', 7.797999999999999],
[61, 'F', 'LOW', 'HIGH', 18.043]], dtype=object)
你可能會發現,此數據集中的某些特征是分類的,例如 Sex 或 BP。 不幸的是,Sklearn 決策樹不處理分類變量。 我們仍然可以使用 pandas.get_dummies() 將這些特征轉換為數值
將分類變量轉換為虛擬/指標變量。
from sklearn import preprocessing
le_sex = preprocessing.LabelEncoder()
le_sex.fit(['F','M'])
X[:,1] = le_sex.transform(X[:,1])
le_BP = preprocessing.LabelEncoder()
le_BP.fit([ 'LOW', 'NORMAL', 'HIGH'])
X[:,2] = le_BP.transform(X[:,2])
le_Chol = preprocessing.LabelEncoder()
le_Chol.fit([ 'NORMAL', 'HIGH'])
X[:,3] = le_Chol.transform(X[:,3])
X[0:5]
array([[23, 0, 0, 0, 25.355],
[47, 1, 1, 0, 13.093],
[47, 1, 1, 0, 10.113999999999999],
[28, 0, 2, 0, 7.797999999999999],
[61, 0, 1, 0, 18.043]], dtype=object)
把因變量給提出來
y = my_data["Drug"]
y[0:5]
0 drugY
1 drugC
2 drugC
3 drugX
4 drugY
Name: Drug, dtype: object
讓我們從 sklearn.cross_validation 導入train_test_split,來拆分訓練集和測試集。
from sklearn.model_selection import train_test_split
train_test_split 將返回 4 個不同的參數。 我們將它們命名為:
X_trainset, X_testset, y_trainset, y_testset
train_test_split 需要以下參數:
X, y, test_size=0.3, and random_state=3.
X 和 y 是拆分前需要的數組,test_size 表示測試數據集的比例,random_state 確保我們獲得相同的拆分。
X_trainset, X_testset, y_trainset, y_testset = train_test_split(X, y, test_size=0.3, random_state=3)
打印訓練集和測試集的大小。 確保大小匹配。
print('Shape of X training set {}'.format(X_trainset.shape),'&',' Size of Y training set {}'.format(y_trainset.shape))
Shape of X training set (140, 5) & Size of Y training set (140,)
print('Shape of X training set {}'.format(X_testset.shape),'&',' Size of Y training set {}'.format(y_testset.shape))
Shape of X training set (60, 5) & Size of Y training set (60,)
drugTree = DecisionTreeClassifier(criterion="entropy", max_depth = 4)
drugTree # it shows the default parameters
DecisionTreeClassifier(criterion='entropy', max_depth=4)
接下來,我們將使用訓練特征矩陣 X_trainset 和訓練響應向量 y_trainset 對數據進行擬合
drugTree.fit(X_trainset,y_trainset)
DecisionTreeClassifier(criterion='entropy', max_depth=4)
predTree = drugTree.predict(X_testset)
如果希望直觀地比較預測與實際值,可以打印出predTree和y_testset。
print (predTree [0:5])
print (y_testset [0:5])
['drugY' 'drugX' 'drugX' 'drugX' 'drugX']
40 drugY
51 drugX
139 drugX
197 drugX
170 drugX
Name: Drug, dtype: object
from sklearn import metrics
import matplotlib.pyplot as plt
print("DecisionTrees's Accuracy: ", metrics.accuracy_score(y_testset, predTree))
DecisionTrees's Accuracy: 0.9833333333333333
准確率分類分數計算子集的准確率:為一個樣本預測的標簽集必須精確匹配y_true中對應的標簽集。
在多標簽分類中,函數返回子集精度。 如果樣本的整個預測標簽集與真實標簽集嚴格匹配,則子集精度為1.0; 否則為0.0。
讓我們來可視化這棵樹
# Notice: You might need to uncomment and install the pydotplus and graphviz libraries if you have not installed these before
#!conda install -c conda-forge pydotplus -y
#!conda install -c conda-forge python-graphviz -y
tree.plot_tree(drugTree)
plt.show()