1. 程式人生 > >決策樹演算法的Python實現—基於金融場景實操

決策樹演算法的Python實現—基於金融場景實操

決策樹是最經常使用的資料探勘演算法,本次分享jacky帶你深入淺出,走進決策樹的世界

基本概念

  • 決策樹(Decision Tree)

    • 它通過對訓練樣本的學習,並建立分類規則,然後依據分類規則,對新樣本資料進行分類預測,屬於有監督學習。
  • 優點

    • 1)決策樹易於理解和實現

      • 使用者不需要了解很多的背景知識,通過決策樹就能夠直觀形象的瞭解分類規則;
    • 2)決策樹能夠同時處理數值型和非數值型資料

      • 在相對短的時間內,能夠對大型資料做出可行且效果良好的結果;

邏輯-類比找物件

決策樹分類的思想類似於找物件,例如一個女孩的母親要給這個女孩介紹男朋友,於是母女倆有了下面的對話:

女兒問:“多大年齡了”;母親答:“26”
女兒接著問:“長得帥不帥?”;母親答:“挺帥的。”
女兒問:“收入高不?”;母親答:“不算很高,中等情況”
女兒問:“是公務員嗎?”;母親答:“是,在財政局上班”
最後,女兒做出決定說:“那好,我去見見!”

這個女孩的決策過程就是典型的分類樹決策:
@資料分析-jacky

在來看一個金融場景下的舉例:客戶向銀行貸款的時候,銀行對使用者的貸款資格做一個評估的流程:

@資料分析-jacky

首先銀行工作人員詢問客戶是否有房產,如何回答有,則判斷客戶可以償還貸款,如果沒有則進入第二層的屬性判斷詢問,是否結婚,如何已婚,兩個人可以負擔的起貸款,則判斷為可以償還,否則進入第三層的屬性判斷詢問,月薪是否超過五千,如果滿足,則判斷為可以償還,否則給出不能償還貸款的結論。

看完上面兩個例子,我們可以看出,決策樹是非常實用的,下面我們就進入正式案例的講解;

案例實操

下面以金融場景舉例:

情景鋪墊

使用者在購買網際網路金融產品的過程“類似於”理財,對於P2P平臺來說,嚴格來說,這個過程稱之為撮合。

使用者金融平臺上充值購買相應期限和約定利率的金融產品,產品到期後,使用者有兩種選擇一個是提現(贖回),另一個就是復投。

對於使用者到期贖回的理解是比較簡單的,比如你在2018年1月1日買了6個月10萬定存金融產品,那麼在2018年7月1日的時候,你可以選擇連本帶息全部贖回,當然你也可以在到期日選擇在平臺還款時,繼續投資,這個過程就是復投。

下面,在嚴謹一點歸納復投的定義就是:
針對按月等額本息還款的使用者,還款或,使用者自己再投,這個過程就是復投。

需解決的問題

作為金融平臺來說,為了把控風險,保證資金的流動性,都一定要提前預測(預判)未來一段時間內的使用者充值和提現金額。
那麼,準確預測使用者到期是否復投,對於我們金融從業者和管理人員來說,就是特別重要了。

  • 那麼,我們可以提出我們亟需解決的問題:

    • 使用者到期是否復投,我們改怎樣預判?

一個初步模型的建立

場景:預測使用者是否復投
注:以下源資料模擬真實資料編撰

(一)選擇特徵變數-featureDate

1. 資料來源抓取

import pandas
data = pandas.read_csv('file:///Users/apple/Desktop/jacky_reinvest.csv',encoding='GBK')
print(data)

@資料分析-jacky

  • jacky註解(1):上面這份資料來源其實是經過預處理(或者說是經過初步的資料清理的),我們拿到資料來源的第一步一定是做資料清理的,資料科學與傳統的統計科學,在實操中,區別最大的可能就是資料清理了,本文的資料來源只用於學習舉例用,所以資料還是比較規整的,但在實際工作中,一定不要忘了資料清洗這一步。

  • jacky註解(2): 初始心裡預期這列是一個產品概念,就是使用者在購買定存金融產品的時候,可以預先設定是否需要復投,當然這只是一個預設定,在使用者購買到贖回這個過程中,我們都可以隨時變更。復投模式是一個過去式,也是最終的復投結果,所以下面我們會把這列當作目標變數來處理。

2. 啞變數處理(虛擬變數轉化)

需處理的特徵變數有:

  • 金融產品

  • 初始心裡預期

  • 客戶類別

#呼叫Map方法進行可比較大小虛擬變數的轉換
productDict={'12個月定存':4,'6個月定存':3,'3個月定存':2,'1個月定存':1}
data['產品Map']=data['金融產品'].map(productDict)

#呼叫get_dummyColumns方法進行不可比較大小虛擬變數的轉換
dummyColumns = ['初始心裡預期','客戶類別',]
for column in dummyColumns:
    data[column]= data[column].astype('category')

dummiesData=pandas.get_dummies(
    data,
    columns=dummyColumns,prefix=dummyColumns
    ,prefix_sep='_',dummy_na=False,drop_first=False)

#挑選可以建模的變數 featureData
fData = dummiesData[[
    '購買金額','產品Map','初始心裡預期_復投','客戶類別_VIP使用者'
]]

@資料分析-jacky

  • jacky註解(3):關於啞變數更詳細的說明,可以參照我《特徵工程三部曲》這篇文章,啞變數處理要處理的就是離散變數,購買金額的列,因為都是連續型資料,所以就談不上虛擬變數處理的。

  • jacky註解(4):離散變數分為有比較關係的離散變數和無比較關係的離散變數,所以需要用map方法和get_dummyColumns方法分別處理;

(二)選擇目標變數-targerDate

#設定目標變數 targetData
tData = dummiesData['復投模式']
  • jacky註解(5):目標變數是我們分析問題的目標和結果,從目標變數既定的歷史資料中,我們可以”餵養”資料,繼而訓練資料,最終達到洞察預測資料的目的。

(三)決策樹問題的求解與建模

#生成決策樹
from sklearn.tree import DecisionTreeClassifier

#設定最大葉子數為5
dtModel = DecisionTreeClassifier(max_leaf_nodes=5)
  • jacky註解(6):生成決策樹並設定最大葉子樹為5,使⽤sklearn的DecisionTreeClassifer類進⾏行決策樹問題的求解與建模,關於最大葉子樹,可以在看過圖形化之後,在反過來理解這部分,就簡單的多了,在這裡我們可以先理解為是一個很常用的引數即可。

(四)10折交叉驗證

#模型檢驗-交叉驗證法
from sklearn.model_selection import cross_val_score
cross_val_score(
    dtModel,
    fData,tData,cv=10
)

@資料分析-jacky

  • jacky註解(7):從控制檯的輸出可以看出,每次驗證的評分都超過0.9,是一個非常不錯的模型,可以用於實踐;

(五)模型訓練

#訓練模型
dtModel=dtModel.fit(fData,tData)

控制檯結果輸出:

@資料分析-jacky

(六)模型視覺化

決策樹的繪圖方法:

  • sklearn.tree.export_graphviz(… …)

    • dtModel:決策樹模型

    • out_file:圖形資料的輸出路徑

    • class_names:目標屬性的名稱,一般用於中文化

    • feature_names:特徵屬性的名稱,一般用於種文化

    • filled= True :是否使用顏色填充

    • rounded=True:邊框是否採用圓角邊框

    • special_characters: 是否有特殊字元

#模型視覺化
import pydotplus
from sklearn.externals.six import StringIO  #生成StringIO物件
from sklearn.tree import export_graphviz

dot_data = StringIO() #把檔案暫時寫在記憶體的物件中

export_graphviz(
    dtModel,
    out_file=dot_data,
    class_names=['復投','不復投'],
    feature_names=['購買金額','產品Map','初始心裡預期_不復投','客戶類別_VIP使用者'],
    filled=True,rounded=True,special_characters=True
)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_png('shujudata.png')

@資料分析-jacky

  • jacky註解(8):需要提前安裝graphviz軟體

  • jacky註解(9):最大葉子樹,一般設定為8個,因為葉子數太多,決策樹的結構越複雜,太複雜的結構就會導致訓練過度的問題,因此,在決策樹演算法中,設定合適葉子數是非常重要的。

  • jacky註解(10):gini值越接近於0,那麼結果就越顯而易見,如果越接近於1,那麼結果就越難判定;

完整程式碼展示

#---author:朱元祿---

import pandas
data = pandas.read_csv('file:///Users/apple/Desktop/jacky_reinvest.csv',encoding='GBK')

#呼叫Map方法進行可比較大小虛擬變數的轉換
productDict={'12個月定存':4,'6個月定存':3,'3個月定存':2,'1個月定存':1}
data['產品Map']=data['金融產品'].map(productDict)

#呼叫get_dummyColumns方法進行可比較大小虛擬變數的轉換
dummyColumns = ['初始心裡預期','客戶類別',]
for column in dummyColumns:
    data[column]= data[column].astype('category')

dummiesData=pandas.get_dummies(
    data,
    columns=dummyColumns,prefix=dummyColumns
    ,prefix_sep='_',dummy_na=False,drop_first=False)

#挑選可以建模的變數 featureData
fData = dummiesData[[
    '購買金額','產品Map','初始心裡預期_復投','客戶類別_VIP使用者'
]]

#設定目標變數 targetData
tData = dummiesData['復投模式']

#生成決策樹
from sklearn.tree import DecisionTreeClassifier

#設定最大葉子數為8
dtModel = DecisionTreeClassifier(max_leaf_nodes=8)

'''
#模型檢驗-交叉驗證法
from sklearn.model_selection import cross_val_score

cross_val_score(
    dtModel,
    fData,tData,cv=10
)
'''
#訓練模型
dtModel=dtModel.fit(fData,tData)

#模型視覺化
import pydotplus
from sklearn.externals.six import StringIO  #生成StringIO物件
from sklearn.tree import export_graphviz

dot_data = StringIO() #把檔案暫時寫在記憶體的物件中

export_graphviz(
    dtModel,
    out_file=dot_data,
    class_names=['復投','不復投'],
    feature_names=['購買金額','產品Map','初始心裡預期_不復投','客戶類別_VIP使用者'],
    filled=True,rounded=True,special_characters=True
)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_png('shujudata.png')