算法建模流程详解及python代码实现
算法建模
- 前言
- 建模的一般流程
- 代碼實(shí)現(xiàn)(以邏輯回歸為例,重在解釋流程)
- 導(dǎo)入相關(guān)模塊
- 數(shù)據(jù)清洗及降維
- woe編碼(好處不需要填充缺失值不需要數(shù)據(jù)標(biāo)準(zhǔn)化)
- 檢驗(yàn)多重共線性(在這步之后決定樣本不平衡怎么處理)
- 模型訓(xùn)練(觀察沒通過假設(shè)性檢驗(yàn)的變量)
- 評(píng)估指標(biāo)(以AUC和KS為例)
- 保存模型
- 讀取模型并在樣本上打分
前言
每個(gè)算法工程師都有自己建模的習(xí)慣,因此在建模流程上會(huì)有所不同。本文主要介紹了一般的建模流程,有些步驟的先后順序可能會(huì)有所差異,具體還需結(jié)合自己的實(shí)際相結(jié)合。
建模的一般流程
1.明確需求,確定y: 這是建模第一步需要做的,y定義的合理程度很大程度的影響模型乃至策略的評(píng)估。一方面需要經(jīng)驗(yàn)的支撐,另一方面需要結(jié)合業(yè)務(wù)知識(shí)來確定。例如在信貸中A卡一般根據(jù)vintage曲線或者滾動(dòng)率來確定好人與壞人的標(biāo)簽。
2.尋找與y相關(guān)的底層變量: 在確定y的業(yè)務(wù)基礎(chǔ)上,尋找相關(guān)變量可以是傳統(tǒng)相關(guān)的業(yè)務(wù)變量,可以是相關(guān)的數(shù)據(jù)埋點(diǎn),可以是三方公司的數(shù)據(jù),可以是用戶授權(quán)所爬取的相關(guān)數(shù)據(jù)等。(注意:每個(gè)變量的具體業(yè)務(wù)含義必須明確,下面流程需要評(píng)估合理性與衍生)
3.數(shù)據(jù)EDA: 這部分主要是對(duì)數(shù)據(jù)有一個(gè)大體的了解。主要包含變量的均值、中位數(shù)、缺失率(缺失率高的是否考慮刪除)、同一值(取值distinct較少是否刪除)、異常值、分布、相關(guān)性(這一步也可以放在后面降維步驟后再進(jìn)行一波降維)等。
4.變量衍生: 在拿到且理解了基礎(chǔ)的變量之后,需要做變量衍生處理(涉及到空值時(shí)需要注意,結(jié)合業(yè)務(wù))。可以通過四則運(yùn)算、結(jié)合時(shí)間維度、PCA等模型的方法、結(jié)合業(yè)務(wù)知識(shí)等。
5.數(shù)據(jù)編碼(確保數(shù)據(jù)可入模): 不同的模型對(duì)含有缺失值、字符型變量的容忍度各不相同,因此需要對(duì)數(shù)據(jù)做編碼(可以看成數(shù)據(jù)清洗的一種)來適應(yīng)不同的模型,確保模型的順利訓(xùn)練。對(duì)于涉及計(jì)算距離的模型數(shù)據(jù)需要進(jìn)行標(biāo)準(zhǔn)化/歸一化處理;對(duì)分類變量可以進(jìn)行one-hot(獨(dú)熱編碼會(huì)導(dǎo)致維度急劇增加,可通過one-hot+PCA)、LaberEncoder、woe編碼等;對(duì)于缺失值需要?jiǎng)h除或者填充。
6.降維: 根據(jù)缺失率與同一值做初步剔除;單變量分析進(jìn)行一波降維(包含分箱看趨勢(shì)及IV等);PCA等降維模式;機(jī)器學(xué)習(xí)方法輸出變量重要性等降維;變量相關(guān)性做降維。
7.模型調(diào)參、評(píng)估指標(biāo): 模型調(diào)參主要根據(jù)每個(gè)模型本身進(jìn)行調(diào)參。主要涉及解決樣本不平衡、過擬合與欠擬合的問題。調(diào)參可以調(diào)用網(wǎng)格搜索、貝葉斯調(diào)參等方法。評(píng)估指標(biāo)主要是根據(jù)不同的應(yīng)用場(chǎng)景來確定具體的評(píng)估指標(biāo),例如A卡會(huì)關(guān)注模型衰減度(穩(wěn)定性)、ROC、AUC、KS、swap分析等。
8.模型部署監(jiān)控: 模型的監(jiān)控一方面保證生產(chǎn)上順利進(jìn)行,另一方面是觀察模型的效果。在信貸中A卡一般監(jiān)控:進(jìn)件量、評(píng)分卡均值、評(píng)分卡分10檔分組占比、評(píng)分PSI波動(dòng);變量均值、缺失率、PSI波動(dòng),變量分bin;后端:每周放款件及對(duì)應(yīng)逾期率、auc、ks、Lift圖、變量分bin、變量iv、變量TP圖等
代碼實(shí)現(xiàn)(以邏輯回歸為例,重在解釋流程)
導(dǎo)入相關(guān)模塊
import pandas as pd import Logistic_model as lm #自己定義的包,主要涉及EDA、等頻分箱、卡方分箱、變量IV、一些樹模型的變量重要性自動(dòng)化import os os.chdir("E:/wyz/Desktop/模型學(xué)習(xí)/data/") data = pd.read_excel("E:/wyz/Desktop/模型學(xué)習(xí)/data/data.xlsx")數(shù)據(jù)清洗及降維
#eda data_eda = lm.eda_data(data) data_eda.to_csv('EDA.csv',encoding = 'utf-8-sig') #根據(jù)eda做清洗 data_drop = lm.eda_drop(data_eda,data,0.7,2,'target') #單變量分箱(包含等頻分箱和卡方分箱,需要手工挑選有效變量) page = lm.single_variable(data_drop,'target',5,10,10) page.render('單變量分箱分析.html') #變量重要性分析(可以在單變量分箱之后,也可以拿全變量進(jìn)行分析) page = lm.variable_imp(data_drop,'target') page.render('變量重要性分析.html') #相關(guān)性(變量較少可以直接運(yùn)行,變量較多可以前幾布降維后輸出) heatmap = lm.cor_chart(data_drop,'target') heatmap.render('相關(guān)性.html')woe編碼(好處不需要填充缺失值不需要數(shù)據(jù)標(biāo)準(zhǔn)化)
#挑選出有效變量 data_drop_new = data_drop[['target','var1','var2','var3','var4','var5']] #將變量進(jìn)行woe編碼 var1 = [0.82,0.849,0.928,11.795] data_drop1 = lm.Con_data_process(data_drop_new,"var1",var1,'bin5') var2 = [0.0788,0.108,0.176,27] data_drop1 = lm.Con_data_process(data_drop1,"var2",var2,'bin4') var3 = [-0.253,-0.0232,0.0291,2] data_drop1 = lm.Con_data_process(data_drop1,"var3",var3,'bin1') var4 = [0.0776,0.16,0.327,97] data_drop1 = lm.Con_data_process(data_drop1,"var4",var4,'bin1') var5 = [0.163673,0.334605,0.505539,0.678744,22] data_drop1 = lm.Con_data_process(data_drop1,"var5",var5,'bin1') #取出woe編碼后的數(shù)據(jù) data_model = data_drop1[['target','var1','var2','var3','var4','var5']]檢驗(yàn)多重共線性(在這步之后決定樣本不平衡怎么處理)
from statsmodels.stats.outliers_influence import variance_inflation_factor def vif_value(df):vif = pd.DataFrame()vif["VIF Factor"] = [variance_inflation_factor(df.values, i) for i in range(df.shape[1])]vif["features"] = df.columnsreturn vif vif_value(data_model.drop('target', axis=1))模型訓(xùn)練(觀察沒通過假設(shè)性檢驗(yàn)的變量)
from statsmodels.formula.api import ols import statsmodels.api as sm#最小二乘 from sklearn.model_selection import train_test_splitdata_model['intercept'] = 1 #statsmodels需要價(jià)格截距項(xiàng) y = data_model['target'] x = data_model.drop('target', axis=1) x_train, x_test, y_train, y_test = train_test_split(x, y,random_state=0,train_size=0.7)#訓(xùn)練模型 logit=sm.Logit(y_train,x_train) model_logit=logit.fit()#假設(shè)性檢驗(yàn)輸出 model_logit.summary()評(píng)估指標(biāo)(以AUC和KS為例)
from sklearn.metrics import roc_auc_score #計(jì)算ks def cal_ks(y_true,y_pred,bins):'''y_true:真實(shí)標(biāo)簽y_pred:預(yù)測(cè)的概率bins:劃分的組'''df1 = pd.DataFrame(y_true).join(pd.DataFrame(y_pred))df1.columns = ['t7_cnt','score']factor1,bins1=pd.qcut(df1["score"],bins,retbins=True,precision=6,duplicates='drop')bins = []bad_rate = []good_rate = []bad_total_num = df1.loc[df1.t7_cnt == 1].t7_cnt.count()good_total_num = df1.loc[df1.t7_cnt == 0].t7_cnt.count()for i in range(len(bins1[1:])):bin_group = 'bin'+str(i+1)if i != len(bins1[1:])-1:bad_num = df1.loc[df1.score <= bins1[1:][i]].t7_cnt.sum()good_num = df1.loc[df1.score <= bins1[1:][i]].t7_cnt.count()-df1.loc[df1.score <= bins1[1:][i]].t7_cnt.sum()bins.append(bin_group)bad_rate.append(bad_num/bad_total_num)good_rate.append(good_num/good_total_num)else:bad_num = df1.loc[df1.score <= 1].t7_cnt.sum()good_num = df1.loc[df1.score <= 1].t7_cnt.count()-df1.loc[df1.score <= 1].t7_cnt.sum()bins.append(bin_group)bad_rate.append(good_num/good_total_num)good_rate.append(good_num/good_total_num)df2 = pd.DataFrame(bad_rate,index = bins,columns = ['bad_rate']).join(pd.DataFrame(good_rate,index = bins,columns = ['good_rate']))df2["D_value"] = df2["good_rate"] - df2["bad_rate"]ks = max(df2["D_value"])return ks,df2test_pre_pro = model.predict(x_test)#輸出預(yù)測(cè)為1的概率(其它評(píng)估指標(biāo)可能需要將概率轉(zhuǎn)化為類別) ks_test,ks_dataframe_test = lm.cal_ks(y_test,test_pre_pro,10)#計(jì)算ksprint('test_AUC: %.6f'%roc_auc_score(y_test,test_pre_pro))#AUC,預(yù)測(cè)為概率 print('ks_test: %.6f'%ks_test)保存模型
from sklearn.externals import joblib # 保存模型 joblib.dump(model_logit,'Logistic.pkl')讀取模型并在樣本上打分
#讀取數(shù)據(jù),一般都是原始數(shù)據(jù) data_pre = pd.read_excel("E:/wyz/Desktop/論文/predict/pre_sample.xlsx") #將原始數(shù)據(jù)以訓(xùn)練集中相同方式woe編碼 col_list = ['var1','var2','var3','var4','var5'] data_pre_model= lm.woe_pre(data_pre ,5,col_list,'target') #從本地讀取模型 clf = joblib.load("Logistic.pkl") #添加截距項(xiàng)并進(jìn)行預(yù)測(cè) data_pre_model['intercept'] = 1 clf.predict(data_pre_model)總結(jié)
以上是生活随笔為你收集整理的算法建模流程详解及python代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: K-means算法详解及python代码
- 下一篇: 决策树原理详解及python代码实现