1. 程式人生 > >《Python資料分析與挖掘實戰》第六章學習拓展——偷漏稅使用者識別

《Python資料分析與挖掘實戰》第六章學習拓展——偷漏稅使用者識別

本文是繼上一篇文章中上機實驗之後的拓展思考部分的練習記錄。此拓展思考部分主要目標是依據附件所提供的汽車銷售企業的部分經營指標,來評估汽車銷售行業納稅人的偷漏稅傾向,建立偷漏稅行為識別模型。
本次拓展思考練習分以下幾個步驟進行:

  1. 資料初步探索分析
  2. 資料預處理
  3. 模型選擇與建立
  4. 模型比較

接下來將逐一進行記錄。

一 資料初步探索分析

在這一部分,將對附件中所提供的資料進行初步研究,檢視其可能存在的內部規律。
首先自然是資料的匯入,程式碼如下:

df=pd.read_excel('C:/Python27/Lib/site-packages/xy/chapter6/拓展思考/拓展思考樣本.xls'
.decode('utf-8'))

需要說明的是,剛開始匯入的時候,由於路徑中包含中文,因此發生錯誤,通過百度,在路徑後新增.decode(‘utf-8’)進行了編碼轉換,最後才得以成功匯入。
附件中一共包含124個樣本,16個變數,其中一個是納稅人編號,一個是是否偷漏稅的輸出結果,不偷稅為正常,存在偷漏稅則為異常,其他都為與偷漏稅相關的經營指標。接下來將分別從分類變數和數值型變數兩個方面入手對資料做一個探索性分析。

1.1 偷漏稅情況下的銷售型別和銷售模式分佈

銷售的汽車型別和銷售模式可能會對偷漏稅傾向有一定的表徵,因此,畫出【輸出結果為異常的銷售型別和銷售模式】的分佈圖可能可以直觀上看出是否有一定影響。
程式碼如下:

fig=plt.figure()
fig.set(alpha=0.2)
#不同銷售型別和銷售模式下的偷漏稅情況
plt.subplot2grid((1,2),(0,0))
df_type=df[u'銷售型別'][df[u'輸出']=='異常'].value_counts()
df_type.plot(kind='bar',color='blue')
plt.title(u'不同銷售型別下的偷漏稅情況',fontproperties='SimHei')
plt.xlabel(u'銷售型別',fontproperties='SimHei')
plt.ylabel(u'異常數',fontproperties='SimHei'
) plt.subplot2grid((1,2),(0,1)) df_model=df[u'銷售模式'][df[u'輸出']=='異常'].value_counts() df_model.plot(kind='bar',color='green') plt.title(u'不同銷售模式下的偷漏稅情況',fontproperties='SimHei') plt.xlabel(u'銷售模式',fontproperties='SimHei') plt.ylabel(u'異常數',fontproperties='SimHei') plt.subplots_adjust(wspace=0.3) plt.show()

執行結果如下圖:
這裡寫圖片描述
由圖可以看出在存在偷漏稅情況的納稅人中,銷售國產轎車最多,通過4S店進行銷售的最多。
這只是一個分佈情況,具體是否有關係,在這裡並不確定。
問題記錄:在畫這個柱形圖的時候,剛開始,所有的中文都無法顯示,在進行資料查詢之後,知道是中文字型的問題,需要自己定義中文字型,因此在程式碼中加入:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus']=False

按理說,這樣就可以顯示中文。但是博主在執行的時候,依舊無法顯示中文,後來在cmd執行視窗中執行出來的圖卻能正常顯示中文,因此作出判斷,應該是所用平臺,也就是Python(x,y)的問題。而在第二天重新開啟Python(x,y)並執行的時候發現可以正常顯示,所以,應該就是環境的問題,而不是程式碼的問題。

1.2數值型資料分佈情況

源資料分佈我也看不出什麼規律來,因此,這裡就簡單針對正常和異常這兩種輸出情況進行了describe,程式碼如下:

#不同輸出情況下的數值型變數總體情況
df_normal=df.iloc[:,3:][df[u'輸出']=='正常'].describe().T
df_normal=df_normal[['count','mean','max','min','std']]
df_abnormal=df.iloc[:,3:][df[u'輸出']=='異常'].describe().T
df_abnormal=df_abnormal[['count','mean','max','min','std']]

輸出的結果如下:
正常情況:
正常情況下結果
異常情況:
異常情況下結果
從平均值可以大概看出,當輸出結果為正常和異常兩種情況時,還是有不一樣的,特別是汽車銷售平均毛利、維修毛利、代辦保險率等還是比較明顯的,但這只是初步的一個觀察結果,只能作為一個猜想來考慮。

二 資料預處理

資料預處理包括異常值、缺失值的處理,數值的轉換等。本文中資料沒有缺失值,因此不用對缺失值進行處理,但是博主對汽車銷售經營指標實在不瞭解,所以看不出來哪些值有異常,因此暫且不對數值進行處理,但是涉及到分類變數,在模型建立時,需將分類變數轉換成虛擬變數,因此,博主在資料預處理的過程中,主要對銷售型別、銷售模式以及輸出進行虛擬變數的建立。
Pandas中有直接轉換的函式,get_dummies。
虛擬變數建立程式碼如下:

#資料預處理(將銷售型別與銷售模式以及輸出轉換成虛擬變數)
type_dummies=pd.get_dummies(df[u'銷售型別'],prefix='type')
model_dummies=pd.get_dummies(df[u'銷售模式'],prefix='model')
result_dummies=pd.get_dummies(df[u'輸出'],prefix='result')
df=pd.concat([df,type_dummies,model_dummies,result_dummies],axis=1)
df.drop([u'銷售型別',u'銷售模式',u'輸出'],axis=1,inplace=True)
#正常列去除,異常列作為結果
df.drop([u'result_正常'],axis=1,inplace=True)
df.rename(columns={u'result_異常':'result'},inplace=True)

三 模型選擇與建立

博主在這篇文章中選擇的模型為上一篇文章中用的CART決策樹模型和邏輯迴歸模型。
首先不管哪種模型,都需要先進行資料劃分,即將資料分成訓練資料和測試資料兩部分,與上一篇文章一樣,這裡依舊選取80%作為訓練資料,20%作為測試資料。
程式碼如下:

#資料劃分(80%作為訓練資料,20%作為測試資料)
data=df.as_matrix()
from random import shuffle
shuffle(data)
data_train=data[:int(len(data)*0.8),:]
data_test=data[int(len(data)*0.8):,:]

接下來將分別訓練CART決策樹模型和邏輯迴歸模型。

3.1 CART決策樹模型

CART決策樹模型在上一篇文章中已經講過,程式碼也基本不變,在這裡就不再贅述。在模型建立之後,與上一篇文章相同,也進行了混淆矩陣的繪製,這裡不僅繪製訓練樣本的混淆矩陣,也將測試樣本的混淆矩陣畫出。
程式碼如下:

#確定y值和特徵值
y=data_train[:,-1]
x=data_train[:,1:-1]
from sklearn.tree import DecisionTreeClassifier #匯入決策樹模型


tree = DecisionTreeClassifier() #建立決策樹模型
tree.fit(x, y) #訓練

#儲存模型
from sklearn.externals import joblib
joblib.dump(tree, 'C:/Python27/Lib/site-packages/xy/chapter6/thoughts_tree.pkl')

from cm_plot import * #匯入混淆矩陣視覺化函式
cm_plot(y, tree.predict(x)).show() #顯示混淆矩陣視覺化結果

cm_plot(data_test[:,-1],tree.predict(data_test[:,1:-1])).show()

訓練樣本和測試樣本的混淆矩陣如下所示:
訓練樣本:
訓練樣本混淆矩陣
測試樣本:
這裡寫圖片描述

可以看出,對於訓練樣本來說,決策樹模型的正確率為100%,而對於測試樣本,其準確率為23/25=92%,其中,正常使用者中,被判定為偷漏稅使用者的比例為1/14=7.1%,偷漏稅使用者中,被判定為正常使用者的比例為1/11=9.1%。

3.2 邏輯迴歸模型

邏輯迴歸屬於機器學習中較為簡單的模型。在Andrew NG的機器學習課中,最開始就講了邏輯迴歸模型,是線上性模型上套用一個邏輯函式。具體可以參考下面這篇文章:
邏輯迴歸模型基礎
也可以參考Andrew NG的《Machine Learning》課程講義。(之前上這門課的時候沒有想到可以在部落格裡做筆記來記錄,以後有時間可以考慮補上,或者以後可以另設理論知識版塊對資料分析涉及到的理論知識記錄,以供日後參考回顧。)
在Python中實現邏輯迴歸模型的時候,可以直接從sklearn包中匯入線性模型linear_model,就可以直接對邏輯迴歸模型進行呼叫,模型建立之後同樣分別繪製訓練樣本和測試樣本的混淆矩陣,並且輸出邏輯迴歸的係數。
程式碼如下:

#邏輯迴歸
from sklearn import linear_model
clf=linear_model.LogisticRegression(C=1.0,penalty='l1',tol=1e-6)
#此處的x,y與上文中決策樹所用x,y相同
clf.fit(x,y)
#邏輯迴歸係數
xishu=pd.DataFrame({"columns":list(df.columns)[1:-1], "coef":list(clf.coef_.T)})
#邏輯迴歸混淆矩陣
cm_plot(y,clf.predict(x)).show()
#對test資料進行預測
predictions=clf.predict(data_test[:,1:-1])
#test混淆矩陣
cm_plot(data_test[:,-1],predictions).show()

訓練樣本和測試樣本的混淆矩陣如下:
訓練樣本:
LR訓練樣本
測試樣本:
LR測試樣本
由圖可以看出,對於訓練樣本,邏輯迴歸模型的準確率為(23+66)/99=89.9%,其中,正常使用者中,被判定為偷漏稅使用者的比例為7/73=9.6%,偷漏稅使用者中,被判定為正常使用者的比例為3/25=12%;測試樣本的準確率為18/25=72%,其中,正常使用者中,被判定為偷漏稅使用者的比例為5/17=29.4%,偷漏稅使用者中,被判定為正常使用者的比例為2/8=25%。
得出邏輯迴歸的係數為:
這裡寫圖片描述
可以通過係數看出,維修毛利、代辦保險率、4S店對偷漏稅有明顯的負相關,成本費用利潤率、辦牌率、大客車和一級代理商對偷漏稅有明顯的正相關。也就是說,納稅人維修毛利越高,代辦保險率越高,通過4S店銷售,其偷漏稅傾向將會越低;而納稅人成本費用利潤率、辦牌率越高,銷售型別為大客車,銷售模式為一季代理商,那麼該納稅人將更有可能為偷漏稅使用者。

四 模型比較

通過第三部分中的混淆矩陣和準確率計算,可以發現,不管是針對訓練樣本還是測試樣本,CART決策樹模型都比邏輯迴歸模型效果要更好一些,為了進一步比較兩個模型的效能,博主繪製了兩個模型的ROC曲線,ROC曲線繪製的程式碼與上一篇文章差不多。
具體程式碼如下所示:

#兩個分類方法的ROC曲線
from sklearn.metrics import roc_curve #匯入ROC曲線函式
import matplotlib.pyplot as plt
fig,ax=plt.subplots()
fpr, tpr, thresholds = roc_curve(data_test[:,-1], tree.predict_proba(data_test[:,1:-1])[:,1], pos_label=1)
fpr2, tpr2, thresholds2 = roc_curve(data_test[:,-1], clf.predict_proba(data_test[:,1:-1])[:,1], pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label = 'ROC of CART', color = 'blue') #作出ROC曲線
plt.plot(fpr2, tpr2, linewidth=2, label = 'ROC of LR', color = 'green') #作出ROC曲線
plt.xlabel('False Positive Rate') #座標軸標籤
plt.ylabel('True Positive Rate') #座標軸標籤
plt.ylim(0,1.05) #邊界範圍
plt.xlim(0,1.05) #邊界範圍
plt.legend(loc=4) #圖例
plt.show() #顯示作圖結果

做出的兩個模型的ROC曲線如下圖所示:
ROC曲線
上篇文章中已經提到,ROC曲線越靠近左上角,則模型效能越優,當兩個曲線做於同一個座標時,若一個模型的曲線完全包住另一個模型,則前者優,當兩者有交叉時,則看曲線下的面積,上圖明顯藍色線下的面積更大,即CART決策樹模型效能更優。
由此可見,對於本文中的例子來說,CART決策樹模型不管從混淆矩陣來看,還是從ROC曲線來看,其效能都要優於邏輯迴歸模型。

五 總結

到此,關於拓展思考的部分就練習完畢了。在本次拓展思考中,對於博主來說最主要的“成就”是對於本章節中所涉及到的資料分析基本流程、CART決策樹模型的建立、混淆矩陣的繪製以及ROC曲線的繪製都再次進行了複習鞏固,對邏輯迴歸的Python實現進行了嘗試,對於畫圖中涉及到的一些小問題也進行了解決,還是比較滿意的。
最後有一點遺留的小問題也做一下記錄,在執行檔案的時候,發現混淆矩陣圖和ROC曲線圖幾乎每一次執行結果都不一樣,除了CART決策樹模型的訓練樣本,也就是準確率為100%的那個圖是不變的,其他的圖一直都在變化,說明預測結果一直都在變化。不知道哪裡有問題,暫且先放著吧–