風(fēng)控(五)——基于決策樹規(guī)則挖掘油品貸案例

本數(shù)據(jù)為滴滴司機(jī)使用油品貸的數(shù)據(jù)。
油品貸的壞賬率高達(dá)5%荡含,非常高咒唆,一定是會(huì)賠錢的。并且能夠通過欺詐檢測释液。
來申請油品貸的司機(jī)本身是已經(jīng)有A卡了钧排,A卡評級為A-F。本來是只有F不放款均澳,但是在油品貸上只有評級為A放款才能不虧錢恨溜。
滴滴是和很多加油站有合作的,加油站會(huì)給滴滴提供司機(jī)數(shù)據(jù)找前。
導(dǎo)入包

import pandas as pd
import numpy as np

#顯示全部特征
pd.set_option('display.max_columns', None)

導(dǎo)入數(shù)據(jù)

data = pd.read_excel('oil_data_for_tree.xlsx')
data.head()

org_lst 不需要做特殊變換糟袁,直接去重
agg_lst 數(shù)值型變量做聚合
dstc_lst 文本型變量做cnt

org_lst = ['uid','create_dt','oil_actv_dt','class_new','bad_ind']
agg_lst = ['oil_amount','discount_amount','sale_amount','amount','pay_amount','coupon_amount','payment_coupon_amount']
dstc_lst = ['channel_code','oil_code','scene','source_app','call_source']

數(shù)據(jù)重組

df = data[org_lst].copy()
df[agg_lst] = data[agg_lst].copy()
df[dstc_lst] = data[dstc_lst].copy()

看一下缺失情況

df.isna().mean()

看一下基礎(chǔ)變量的describe

df.describe()

對creat_dt做補(bǔ)全,用oil_actv_dt來填補(bǔ)躺盛,并且截取6個(gè)月的數(shù)據(jù)项戴。
構(gòu)造變量的時(shí)候不能直接對歷史所有數(shù)據(jù)做累加。
否則隨著時(shí)間推移槽惫,變量分布會(huì)有很大的變化周叮。

def time_isna(x,y):
    if str(x) == 'NaT':
        x = y
    else:
        x = x
    return x
df2 = df.sort_values(['uid','create_dt'],ascending = False)
df2['create_dt'] = df2.apply(lambda x: time_isna(x.create_dt,x.oil_actv_dt),axis = 1)
df2['dtn'] = (df2.oil_actv_dt - df2.create_dt).apply(lambda x :x.days)
df = df2[df2['dtn']<180]
df.head()

對org_list變量求歷史貸款天數(shù)的最大間隔,并且去重

base = df[org_lst]
base['dtn'] = df['dtn']
base = base.sort_values(['uid','create_dt'],ascending = False)
base = base.drop_duplicates(['uid'],keep = 'first')
base.shape

維度(11099, 6)
做變量衍生

gn = pd.DataFrame()
for i in agg_lst:
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:len(df[i])).reset_index())
    tp.columns = ['uid',i + '_cnt']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.where(df[i]>0,1,0).sum()).reset_index())
    tp.columns = ['uid',i + '_num']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.nansum(df[i])).reset_index())
    tp.columns = ['uid',i + '_tot']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.nanmean(df[i])).reset_index())
    tp.columns = ['uid',i + '_avg']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.nanmax(df[i])).reset_index())
    tp.columns = ['uid',i + '_max']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.nanmin(df[i])).reset_index())
    tp.columns = ['uid',i + '_min']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.nanvar(df[i])).reset_index())
    tp.columns = ['uid',i + '_var']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.nanmax(df[i]) -np.nanmin(df[i]) ).reset_index())
    tp.columns = ['uid',i + '_var']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df:np.nanmean(df[i])/max(np.nanvar(df[i]),1)).reset_index())
    tp.columns = ['uid',i + '_var']
    if gn.empty == True:
        gn = tp
    else:
        gn = pd.merge(gn,tp,on = 'uid',how = 'left')

對dstc_lst變量求distinct個(gè)數(shù)

gc = pd.DataFrame()
for i in dstc_lst:
    tp = pd.DataFrame(df.groupby('uid').apply(lambda df: len(set(df[i]))).reset_index())
    tp.columns = ['uid',i + '_dstc']
    if gc.empty == True:
        gc = tp
    else:
        gc = pd.merge(gc,tp,on = 'uid',how = 'left')

將變量組合在一起

fn = pd.merge(base,gn,on= 'uid')
fn = pd.merge(fn,gc,on= 'uid') 
fn.shape

維度(11099, 74)

fn = fn.fillna(0)
fn.head(100)

訓(xùn)練決策樹模型

x = fn.drop(['uid','oil_actv_dt','create_dt','bad_ind','class_new'],axis = 1)
y = fn.bad_ind.copy()
from sklearn import tree

dtree = tree.DecisionTreeRegressor(max_depth = 2,min_samples_leaf = 500,min_samples_split = 5000)
dtree = dtree.fit(x,y)

輸出決策樹圖像界斜,并作出決策

import pydotplus 
from IPython.display import Image
from sklearn.externals.six import StringIO
import os
os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'
with open(path + "dt.dot", "w") as f:
    tree.export_graphviz(dtree, out_file=f)
dot_data = StringIO()
tree.export_graphviz(dtree, out_file=dot_data,
                         feature_names=x.columns,
                         class_names=['bad_ind'],
                         filled=True, rounded=True,
                         special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) 
Image(graph.create_png())

通過加入兩條規(guī)則仿耽,我們最終可以將壞客戶率控制在1.2%。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末各薇,一起剝皮案震驚了整個(gè)濱河市项贺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峭判,老刑警劉巖开缎,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異林螃,居然都是意外死亡奕删,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門疗认,熙熙樓的掌柜王于貴愁眉苦臉地迎上來完残,“玉大人砌滞,你說我怎么就攤上這事』倒郑” “怎么了贝润?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铝宵。 經(jīng)常有香客問我打掘,道長,這世上最難降的妖魔是什么鹏秋? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任尊蚁,我火速辦了婚禮,結(jié)果婚禮上侣夷,老公的妹妹穿的比我還像新娘横朋。我一直安慰自己,他們只是感情好百拓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布琴锭。 她就那樣靜靜地躺著,像睡著了一般衙传。 火紅的嫁衣襯著肌膚如雪决帖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天蓖捶,我揣著相機(jī)與錄音地回,去河邊找鬼。 笑死俊鱼,一個(gè)胖子當(dāng)著我的面吹牛刻像,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播并闲,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼细睡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了焙蚓?” 一聲冷哼從身側(cè)響起纹冤,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洒宝,失蹤者是張志新(化名)和其女友劉穎购公,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雁歌,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宏浩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了靠瞎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片比庄。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡求妹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出佳窑,到底是詐尸還是另有隱情制恍,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布神凑,位于F島的核電站净神,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏溉委。R本人自食惡果不足惜鹃唯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓣喊。 院中可真熱鬧坡慌,春花似錦、人聲如沸藻三。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棵帽。三九已至梨树,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岖寞,已是汗流浹背抡四。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仗谆,地道東北人指巡。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像隶垮,于是被迫代替她去往敵國和親藻雪。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容