使用《python數據分析與數據化運營》一書的代碼及數據。
用決策樹做分類:
#導入庫
import numpy as np import pandas as pd from sklearn import tree #導入決策樹庫 import prettytable #導入表格庫 import matplotlib.pyplot as plt #導入圖形展示庫 import pydotplus #導入dot插件庫 from sklearn.model_selection import train_test_split #數據分區庫,用於數據將數據分為訓練集、測試集 from sklearn.metrics import confusion_matrix,accuracy_score,auc,f1_score,precision_score,recall_score,roc_curve #導入指標庫
#導入數據
df=pd.read_csv(r'E:\data analysis\test\classification.csv')
#輸出數據整體信息
print('samples:%d \t features:%d' % (x.shape[0],x.shape[1])) #整體數據的信息,一共有多少個樣本,多少個特征 print(70*'-')
samples:21927 features:4
#分割數據
x=df.ix[:,:-1] #分割x y=df.ix[:,-1] #分割y x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=0)
#將數據分為訓練集,測試集,設置random_state等於固定的值,則每次得到的訓練集是一樣的、測試集也是一樣的
train_test_split(train_data,train_target,test_size, random_state):用於分割數據集
參數:
train_data:所要划分的樣本特征集,即x
train_target:所要划分的樣本結果,即y
test_size:測試集的占比,如果是整數的話就是樣本的數量。
random_state:是隨機數的種子。種子不同,產生不同的隨機數;種子相同,即使實例不同也產生相同的隨機數。
#訓練分類模型
model_tree=tree.DecisionTreeClassifier(random_state=0) #建立決策樹模型對象。決策樹的生成過程中,往往引入隨機數,這是為了得到更好的分類間隔。如數據本身的特征是連續的,計算分割點就需要隨機。 model_tree.fit(x_train,y_train) #將訓練集導入模型 pre_y=model_tree.predict(x_test) #將測試集的x導入建好的決策樹模型,得出測試集的y
#計算混淆矩陣,用於評價決策樹
confusion_m=confusion_matrix(y_test,pre_y) #獲得混淆矩陣 confusion_table=prettytable.PrettyTable() #創建表格 confusion_table.add_row(confusion_m[0,:]) #將混淆矩陣的第一行添加到表格的第一行 confusion_table.add_row(confusion_m[1,:]) #將混淆矩陣的第二行添加到表格的第二行 print(confusion_table)
+---------+---------+
| Field 1 | Field 2 |
+---------+---------+
| 5617 | 282 |
| 321 | 359 |
+---------+---------+
#從准確率(accuracy)、精確度(precision)、召回率(recall)、F1得分值,AUC(ROC曲線下的面積),這5個指標評價決策樹
accuracy_s=accuracy_score(y_test,pre_y) #計算准確度 precision_s=precision_score(y_test,pre_y) #計算精確度 recall_s=recall_score(y_test,pre_y) #計算召回率 f1_s=f1_score(y_test,pre_y) #計算F1得分
y_score=model_tree.predict_proba(x_test) #獲得決策樹的預測概率,predict_proba返回的是一個 n 行 k 列的數組, 第 i 行 第 j 列上的數值是模型預測 第 i 個預測樣本為某個標簽的概率,並且每一行的概率和為1。 fpr,tpr,thresholds=roc_curve(y_test,y_score[:,1]) auc_s=auc(fpr,tpr) #計算AUC
core_metrics=prettytable.PrettyTable() #創建表格 core_metrics.field_names=['auc','accuracy','precision','recall','f1'] #定義表格列名 core_metrics.add_row([auc_s,accuracy_s,precision_s,recall_s,f1_s]) #增加數據 print(core_metrics)
+---------------+----------------+----------------+----------------+----------------+
| auc | accuracy | precision | recall | f1 |
+---------------+----------------+----------------+----------------+----------------+
| 0.75004437442 | 0.908344733242 | 0.560062402496 | 0.527941176471 | 0.543527630583 |
+---------------+----------------+----------------+----------------+----------------+
混淆矩陣:
ture positive(TP):本來是正例,分類成正例
false positive(FP):本來是負例,分類成正例
false negative(FN):本來是正例,分類成負例
true negative(TN):本來是負例,分類成負例
准確度(accuracy):A=(TP+TN)/(TP+FP+FN+TN),取值范圍 [0,1],值越大說明分類結果越准確。
精確度(precision):P=TP/(TP+FP),取值范圍 [0,1],值越大說明分類結果越准確。
召回率(recall):R=TP/(TP+FN),取值范圍 [0,1],值越大說明分類結果越准確。
F1得分:是准確度和召回率的調和均值,F1=2*(P*R)/(P+R),取值范圍 [0,1],值越大說明分類結果越准確。
ROC曲線:
ROC觀察模型正確地識別正例的比例與模型錯誤地把負例數據識別成正例的比例之間的權衡。TPR的增加以FPR的增加為代價。AUC(Area under roccurve),即ROC曲線下的面積,是模型准確率的度量。
縱坐標:真正率(True Positive Rate , TPR)或靈敏度(sensitivity)
TPR = TP /(TP + FN) (正樣本預測結果數 / 正樣本實際數)
橫坐標:假正率(False Positive Rate , FPR)
FPR = FP /(FP + TN) (被預測為正的負樣本結果數 /負樣本實際數)
如何畫ROC 曲線,對於一個特定的分類器和測試數據集,顯然只能得到一個分類結果,即一組FPR和TPR結果,而要得到一個曲線,我們實際上需要一系列FPR和TPR的值。分類器的一個重要功能“概率輸出”,即表示分類器認為某個樣本具有多大的概率屬於正樣本(或負樣本)。閾值threshold,當測試樣本屬於正樣本的概率大於或等於這個threshold時,我們認為它為正樣本,否則為負樣本。每次選取一個不同的threshold,我們就可以得到一組FPR和TPR,即ROC曲線上的一點。
AUC的取值
AUC = 1,是完美分類器,采用這個預測模型時,存在至少一個閾值能得出完美預測。絕大多數預測的場合,不存在完美分類器。
0.5 < AUC < 1,優於隨機猜測。這個分類器(模型)妥善設定閾值的話,能有預測價值。
AUC = 0.5,跟隨機猜測一樣(例:丟銅板),模型沒有預測價值。
AUC < 0.5,比隨機猜測還差;但只要總是反預測而行,就優於隨機猜測。
#圖形顯示ROC曲線
plt.plot(fpr,tpr,label='ROC') plt.plot([0,1],[0,1],linestyle='--',color='k',label='random chance') #畫隨機狀態下的准確率線 plt.xlabel('false positive rate') #x軸標簽 plt.ylabel('true positive rate') #y軸標簽 plt.legend(loc='best') #圖例,圖例位於best位置 plt.show()
#畫出指標的重要性
names_list=['age','gender','income','rfm_score'] #定義特征值的名稱(就是x的名稱)
feature_importance=model_tree.feature_importances_ #從決策樹中獲取指標重要性
plt.bar(np.arange(feature_importance.shape[0]),feature_importance,tick_label=names_list) #畫出柱狀圖
plt.xlabel('feature')
plt.ylabel('importance')
plt.show()
#模型應用
x_new=pd.DataFrame([[40,0,55616,0],[17,0,55568,0],[55,1,55932,1]]) y_pre_new=model_tree.predict(x_new) print(y_pre_new)
#將決策樹圖保存為pdf文件
dot_data=tree.export_graphviz(model_tree,out_file=None,max_depth=5,feature_names=names_list,filled=True,rounded=True) #將決策樹生成dot對象 graph=pydotplus.graph_from_dot_data(dot_data) #通過pydotplus將決策樹規則解析為圖形 graph.write_pdf('tree.pdf') #將決策樹規則保存為圖形
參考:
http://www.dataivy.cn/blog/classification_with_skelarn_tree/#more-655
http://alexkong.net/2013/06/introduction-to-auc-and-roc/
https://blog.csdn.net/tanzuozhev/article/details/79109311