金融风控-- >客户流失预警模型-- >金融数据分析
從這篇博文開始,我將介紹機器學習,深度學習在金融風控這個行業(yè)上的應用。其實機器學習,深度學習在一些相關(guān)場景上的應用,其解決方法都是大同小異,差不多都是固定的解決套路,但是需要結(jié)合這個場景這個行業(yè)領(lǐng)域的相關(guān)知識來解決。
這篇博文將開始介紹客戶流失預警模型,而本篇博文將主要側(cè)重介紹金融數(shù)據(jù)分析,預處理。
客戶流失預警模型的業(yè)務意義
-
嚴格地講,客戶流失指的是客戶在該行所有業(yè)務終止,并銷號。但是具體業(yè)務部門可單獨定義在該部門的全部或某些業(yè)務上,客戶的終止行為。
-
對專家及金融業(yè)業(yè)內(nèi)人士的走訪及調(diào)研結(jié)果表明,商業(yè)銀行客戶流失較為嚴重。國內(nèi)商業(yè)銀行,客戶流失率可達20%甚至更高。而獲得新客戶的成本,可達維護現(xiàn)有客戶的5倍。
-
因此,從海量客戶交易記錄中挖掘出對流失有影響的信息,建立高效的客戶流失預警體系尤為重要。
建立量化模型,合理預測客群的潛在流失風險
? 常用的風險因子
? 客戶持有的產(chǎn)品數(shù)量、種類
? 客戶的年齡、性別
? 受地理區(qū)域的影響
? 受產(chǎn)品類別的影響
? 交易的間隔時間
? 營銷、促銷手段
? 銀行的服務方式和態(tài)度
數(shù)據(jù)介紹和描述
本案例搜集了17,241例數(shù)據(jù),其中有1,741例流失樣本,總流失率達到10.10%
銀行自有字段(有效記錄占100%)
?賬戶類信息
?個人類信息
?存款類信息
?消費、交易類信息
?理財、基金類信息
?柜臺服務、網(wǎng)銀類信息
外部三方數(shù)據(jù)(可能存在缺失值)
?外呼客服數(shù)據(jù)
?資產(chǎn)類數(shù)據(jù)
?其他消費類數(shù)據(jù)
單因子分析之連續(xù)變量
1)有效記錄的占比
因為原始數(shù)據(jù)可能存在大量的缺失值,故我們需要查看這個單因子數(shù)據(jù)上缺失值占總個數(shù)據(jù)的比值情況。如果占比特別大,則有可能會不考慮這個因子。
2)整體分布
我們需要看看這個原始數(shù)據(jù)在這個單因子上的初始分布,有時候因為原始數(shù)據(jù)在這個單因子上存在極端值,導致看不來這個單因子數(shù)據(jù)分布情況,這時就需要進行截斷,去除一些極端值,看看這個單因子數(shù)據(jù)的截斷分布。
3)按目標變量分布的差異
這里指的是流失的人群數(shù)據(jù)在這個單因子上分布情況,非流失的人群數(shù)據(jù)在這個單因子上分布情況。
連續(xù)性變量的畫圖代碼:
def NumVarPerf(df,col,target,filepath, truncation=False):''':param df: the dataset containing numerical independent variable and dependent variable:param col: independent variable with numerical type:param target: dependent variable, class of 0-1:param filepath: the location where we save the histogram:param truncation: indication whether we need to do some truncation for outliers:return: the descriptive statistics'''#extract target variable and specific indepedent variablevalidDf = df.loc[df[col] == df[col]][[col,target]]#the percentage of valid elementsvalidRcd = validDf.shape[0]*1.0/df.shape[0]#format the percentage in the form of percentvalidRcdFmt = "%.2f%%"%(validRcd*100)#the descriptive statistics of each numerical columndescStats = validDf[col].describe()mu = "%.2e" % descStats['mean']std = "%.2e" % descStats['std']maxVal = "%.2e" % descStats['max']minVal = "%.2e" % descStats['min']#we show the distribution by churn/not churn statex = validDf.loc[validDf[target]==1][col]y = validDf.loc[validDf[target]==0][col]xweights = 100.0 * np.ones_like(x) / x.sizeyweights = 100.0 * np.ones_like(y) / y.size#if need truncation, truncate the numbers in 95th quantileif truncation == True:'''如果選擇截斷,這里選擇把大于0.95的分位點的數(shù)值全用0.95的分位點值代替。'''pcnt95 = np.percentile(validDf[col],95)x = x.map(lambda x: min(x,pcnt95))y = y.map(lambda x: min(x,pcnt95))fig, ax = pyplot.subplots()ax.hist(x.values, weights=xweights, alpha=0.5,label='Attrition')ax.hist(y.values, weights=yweights, alpha=0.5,label='Retained')titleText = 'Histogram of '+ col +'\n'+'valid pcnt ='+validRcdFmt+', Mean ='+mu + ', Std='+std+'\n max='+maxVal+', min='+minValax.set(title= titleText, ylabel='% of Dataset in Bin')ax.margins(0.05)ax.set_ylim(bottom=0)pyplot.legend(loc='upper right')figSavePath = filepath+str(col)+'.png'pyplot.savefig(figSavePath)pyplot.close(1)以上這段代碼需要注意兩點:
①剛開始我在畫直方圖時用的是這句代碼:
②還是這句代碼
xweights = 100.0 * np.ones_like(x) / x.size ax.hist(x, weights=xweights, alpha=0.5,label='Attrition')這里需要了解hist是如何畫圖的,以及里面的參數(shù)意義
直方圖是一種能對值頻率進行離散化顯示的柱狀圖。數(shù)據(jù)點被拆分到離散的,間隔均勻的面元中,繪制的是各種數(shù)據(jù)點的數(shù)量。即是橫坐標表示數(shù)據(jù)的 一個區(qū)間劃分,縱坐標表示數(shù)據(jù)點出現(xiàn)在這個區(qū)間內(nèi),其頻率為多少。 設置參數(shù)weigths,表示縱坐標不是表示頻率,而是表示出現(xiàn)在這個區(qū)間內(nèi)的數(shù)據(jù)點數(shù)量占總的數(shù)量的比值。 這里面是100.0 * np.ones_like(x) / x.size表示所占的百分比。 alpha參數(shù)表示畫出的直方圖的透明度為多少。這里設為0.5半透明,那么兩個直方圖重合在一起的地方就會變色。我們看看“ASSET_MON_AVG_BAL(資產(chǎn)當前總余額)”這個單因子的初始分布:
NumVarPerf(AllData,'ASSET_MON_AVG_BAL','CHURN_CUST_IND',truncation=False) ##初始分布①橫坐標表示余額的一些區(qū)間,縱坐標表示這個區(qū)間內(nèi)所占總余額的百分比,從圖上看,幾乎看不出分布情況,為什么呢?
②我們看看這張圖的title,valid_pcnt=100.0%:數(shù)據(jù)的有效記錄占比100%,因為資產(chǎn)當前總余額這個字段是銀行內(nèi)部數(shù)據(jù)。
③這個字段的平均值Mean=1.18e+05,而max=4.45e+07,很明顯這個最大值比平均值大了不止一個數(shù)量級。明顯存在極端值。因為極端值的存在,導致看不出較小數(shù)據(jù)的分布情況。
那我們試試去掉極端值看看截斷分布如何?
當前“ASSET_MON_AVG_BAL(資產(chǎn)當前總余額)”極端分布:095分位點以內(nèi)的分布情況:
①這個時候從直方圖分布就能看出,流失客戶的余額基本上小于200000,資產(chǎn)較少,資產(chǎn)越少的客戶流失量占總的流失客戶數(shù)越大。
②高資產(chǎn)的客戶流失則比較少。余額大于200000的客戶基本上沒有流失。
③這就說明了流失和非流失這兩類在“ASSET_MON_AVG_BAL(資產(chǎn)當前總余額)”這個單因子上的差異還是比較明顯的。
上面我們通過直方圖得出流失和非流失這兩類在“ASSET_MON_AVG_BAL(資產(chǎn)當前總余額)”這個單因子上的差異還是比較明顯。那么這只是在直觀上的感覺,現(xiàn)在希望對其差異進行量化的分析。
首先我們得了解下什么是單因子分析:
單因素方差分析: (一)單因素方差分析概念理解步驟①是用來研究一個控制變量的不同水平是否對觀測變量產(chǎn)生了顯著影響。這里,由于僅研究單個因素對觀測變量的影響,因此稱為單因素方差分析。②單因素方差分析的第一步是明確觀測變量和控制變量。例如,上述問題中的觀測變量分別是農(nóng)作物產(chǎn)量、婦女生育率、工資收入;控制變量分別為施肥量、地區(qū)、學歷。③單因素方差分析的第二步是剖析觀測變量的方差。方差分析認為:觀測變量值的變動會受控制變量和隨機變量兩方面的影響。據(jù)此,單因素方差分析將觀測變量<<總的離差平方和分解為組間離差平方和和組內(nèi)離差平方和兩部分,用數(shù)學形式表述為:SST=SSA+SSE>>。④單因素方差分析的第三步是通過比較觀測變量總離差平方和各部分所占的比例,推斷控制變量是否給觀測變量帶來了顯著影響。(二)單因素方差分析原理總結(jié)容易理解:在觀測變量總離差平方和中,如果組間離差平方和所占比例較大,則說明觀測變量的變動主要是由控制變量引起的,可以主要由控制變量來解釋,控制變量給觀測變量帶來了顯著影響;反之,如果組間離差平方和所占比例小,則說明觀測變量的變動不是主要由控制變量引起的,不可以主要由控制變量來解釋,控制變量的不同水平?jīng)]有給觀測變量帶來顯著影響,觀測變量值的變動是由隨機變量因素引起的。(三)單因素方差分析基本步驟 1、提出原假設:H0——無差異;H1——有顯著差異 2、選擇檢驗統(tǒng)計量:方差分析采用的檢驗統(tǒng)計量是F統(tǒng)計量,即F值檢驗。 3、計算檢驗統(tǒng)計量的觀測值和概率P值:該步驟的目的就是計算檢驗統(tǒng)計量的觀測值和相應的概率P值。 4、給定顯著性水平,并作出決策。說了這么多,其實就一句話:
總差異=組間差異+組內(nèi)差異
當組間離差平方和所占比例較大,則說明觀測變量的變動主要是由控制變量引起的,可以主要由控制變量來解釋,控制變量給觀測變量帶來了顯著影響;反之,如果組間離差平方和所占比例小,則說明觀測變量的變動不是主要由控制變量引起的,不可以主要由控制變量來解釋,控制變量的不同水平?jīng)]有給觀測變量帶來顯著影響,觀測變量值的變動是由隨機變量因素引起的。
from statsmodels.formula.api import ols from statsmodels.stats.anova import anova_lmresult=anova_lm(ols('ASSET_MON_AVG_BAL~CHURN_CUST_IND',AllData).fit()) print result打印結(jié)果:
這里得出的PR,p值小于0.05,p值越小,原假設越不成立,這里原假設指的是:在流失和非流失中,客戶在“ASSET_MON_AVG_BAL(資產(chǎn)當前總余額)”這個單因子上沒有顯著性差異。故我們可以通過概率這種量化的方式得出結(jié)論:流失和不流失的人群在資產(chǎn)余額這個單因子上有顯著性差異。
注:這里我們是用流失狀態(tài)來得出對應資產(chǎn)狀態(tài)是不同的,并不是用資產(chǎn)狀態(tài)去預測是否流失。這是個相關(guān)性問題,不是因果性問題。
單因子分析之類別變量
1)有效記錄的占比
2) 種類
3)整體分布
4)按目標變量分布的差異
類別性變量畫圖代碼:
def CharVarPerf(df,col,target,filepath):''':param df: the dataset containing numerical independent variable and dependent variable:param col: independent variable with numerical type:param target: dependent variable, class of 0-1:param filepath: the location where we save the histogram:return: the descriptive statistics'''validDf = df.loc[df[col] == df[col]][[col, target]]validRcd = validDf.shape[0]*1.0/df.shape[0]recdNum = validDf.shape[0]validRcdFmt = "%.2f%%"%(validRcd*100)freqDict = {}churnRateDict = {}#for each category in the categorical variable, we count the percentage and churn ratefor v in set(validDf[col]):vDf = validDf.loc[validDf[col] == v]freqDict[v] = vDf.shape[0]*1.0/recdNumchurnRateDict[v] = sum(vDf[target])*1.0/vDf.shape[0]descStats = pd.DataFrame({'percent':freqDict,'churn rate':churnRateDict})fig = pyplot.figure() # Create matplotlib figureax = fig.add_subplot(111) # Create matplotlib axesax2 = ax.twinx() # Create another axes that shares the same x-axis as ax.pyplot.title('The percentage and churn rate for '+col+'\n valid pcnt ='+validRcdFmt)descStats['churn rate'].plot(kind='line', color='red', ax=ax)descStats.percent.plot(kind='bar', color='blue', ax=ax2, width=0.2,position = 1)ax.set_ylabel('churn rate')ax2.set_ylabel('percentage')figSavePath = filepath+str(col)+'.png'pyplot.savefig(figSavePath)pyplot.close(1) 我們以性別這個類別性變量為例: CharVarPerf(AllData,'GENDER_CD','CHURN_CUST_IND',filepath) 上圖中藍色柱狀圖,1表示女性,2,表示男性,z表未知,對應右邊percentage,表示女性,男性,未知,占總?cè)藬?shù)的占比情況,未知人數(shù)很少 可以忽略不計,紅線表示流失占比,對應左邊churn_rate。由上圖可知三點:
①:絕大多數(shù)性別已知
②:已知性別中,男性占比比較高
③:男性流失率低于女性
④:未知性別的客戶流失率顯著高于已知性別客戶。
那么如何用量化的方式去檢驗得出這些結(jié)論呢?
首先了解卡方檢驗
卡方檢驗就是統(tǒng)計樣本的實際觀測值與理論推斷值之間的偏離程度,實際觀測值與理論推斷值之間的偏離程度就決定卡方值的大小,卡方值越大, 越不符合;卡方值越小,偏差越小,越趨于符合,若兩個值完全相等時,卡方值就為0,表明理論值完全符合。 注意:卡方檢驗針對分類變量。 (1)提出原假設:H0:總體X的分布函數(shù)為F(x)如果總體分布為離散型,則假設具體為H0:總體X的分布律為P{X=xi}=pi, i=1,2,... (2)將總體X的取值范圍分成k個互不相交的小區(qū)間A1,A2,A3,…,Ak,如可取A1=(a0,a1],A2=(a1,a2],...,Ak=(ak-1,ak),其中a0可取-∞,ak可取+∞,區(qū)間的劃分視具體情況而定,但要使每個小區(qū)間所含的樣本值個數(shù)不小于5,而區(qū)間個數(shù)k不要太大也不要太小。 (3)把落入第i個小區(qū)間的Ai的樣本值的個數(shù)記作fi,成為組頻數(shù)(真實值),所有組頻數(shù)之和f1+f2+...+fk等于樣本容量n。 (4)當H0為真時,根據(jù)所假設的總體理論分布,可算出總體X的值落入第i 個小區(qū)間Ai的概率pi,于是,npi就是落入第i個小區(qū)間Ai的樣本值的 理論頻數(shù)(理論值)。(5)當H0為真時,n次試驗中樣本值落入第i個小區(qū)間Ai的頻率fi/n與概率pi應很接近,當H0不真時,則fi/n與pi相差很大。 基于這種思想,皮爾遜引進如下檢驗統(tǒng)計量(下圖公式),在0假設成立的情況下服從自由度為k-1的卡方分布。差異的量化:用卡方檢驗來衡量某因子對目標變量的偏好。
原理:如果某因子跟目標變量獨立,(即該因子對目標變量影響較小)則目標變量在該因子上的分布是均勻的,即卡方值應該較小。用來衡量類別性變量分布的差異性。
計算卡方值代碼:
chisqDf = AllData[['GENDER_CD','CHURN_CUST_IND']] grouped = chisqDf['CHURN_CUST_IND'].groupby(chisqDf['GENDER_CD'])##以GENDER_CD(性別)對CHURN_CUST_IND(是否流失,0,1)進行分組 count = list(grouped.count()) # 按性別(男,女,未知)分組,計算每組有多少個CHURN_CUST_IND,也就是統(tǒng)計男性人數(shù),女性人數(shù),未知人數(shù) churn = list(grouped.sum()) # 按性別(男,女,未知)分組,對每組內(nèi)所有的CHURN_CUST_IND求和,也就是統(tǒng)計男性中流失人數(shù),女性中流失人數(shù)等 chisqTable = pd.DataFrame({'total':count,'churn':churn}) chisqTable['expected'] = chisqTable['total'].map(lambda x: round(x*0.101)) chisqValList = chisqTable[['churn','expected']].apply(lambda x: (x[0]-x[1])**2/x[1], axis=1) chisqVal = sum(chisqValList) print chisqVal得出同樣結(jié)果:32.6579
當然可以引入相關(guān)的包來計算卡方值:
首先我們根據(jù)之前給出數(shù)據(jù)總的人群流失率為10.10%,假設性別對目標變量(客戶是否流失)沒有影響,兩者相互獨立,那么男性,女性分布的流失率應該也在10.10%左右,即可算出其期望流失數(shù)。再根據(jù)真實的流失數(shù)算出卡方值為32.66,。通過查表,我們得知:在自由度為2,置信度為0.05下的卡方分為點為5.99.其32.66大于5.99,那么可得出結(jié)論,性別這個變量對其目標變量差異性顯著。
多因子分析
- 變量直接由于業(yè)務關(guān)系,計算邏輯等因素存在一定的兩兩共線性(呈正相關(guān)或者負相關(guān)),需要研究這種共線性并做出適當?shù)奶幚怼?/li>
- 信息的冗余(注意只是對于一階的線性關(guān)系,可能會冗余)
- 維護數(shù)據(jù)的成本(當一個變量可以代替另外一個變量時,我們可以去掉其中一個變量)
- 對某些模型存在一定的影響(在線性回歸模型中,我們假設兩個變量x1,x2具有很強的相關(guān)性,那么在求中的很有可能是奇異的,就是不可逆的)
隨機選取15個連續(xù)性變量,畫出其散點矩陣圖,得出兩兩直接的相關(guān)性
from pandas.tools.plotting import scatter_matrix corrCols = random.sample(numericCols,15) sampleDf = AllData[corrCols] for col in corrCols:sampleDf.rename(columns = {col:col_to_index[col]}, inplace = True) scatter_matrix(sampleDf, alpha=0.2, figsize=(6, 6), diagonal='kde')其實這篇博文講的主要是機器學習里面的特征選擇部分,在單因子分析中,如果某個變量對目標變量影響不大甚至完全獨立,那么可以去掉這個變量。
如果兩個變量相關(guān)性很高,其中一個變量解釋性比較高,另外一個變量解釋性比較低時,即使解釋性比較低的變量效果更好一些,我們也會將其去掉,保留解釋性比較高的那個變量。當然這是在回歸模型中(奇異性問題)。其他模型不需要剔除。
在做模型時,首先是做單因素分析,剔除那些缺失度比較高的,對結(jié)果影響不大的變量。
總結(jié)
以上是生活随笔為你收集整理的金融风控-- >客户流失预警模型-- >金融数据分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 风控-数据分析
- 下一篇: 利用poi实现table表格导出exce