客户流失预警模型——查看单因子变量分析与多因子变量分析

常用风险因子

静态信息:

客户持有的产品数量、种类

客户的年龄、性别

客户所处地理 位置

产品类别

 动态信息:

交易的间隔时间

营销、促销手段

银行的服务方式和态度

 单因子分析之连续变量

1、有效记录占比

2、整体分布

                     初始分布

                     截断分布

3、按目标变量分布的差异

方差分析,用于两个及以上类别的均值差异的显著性检验,可以查看各个不同类别是否属于同一分布

用到的是F分布,F=MSTR-MSE,分子自由度为n-1,分子自由度为n-k,n为样本总数,k为样本群数量

例如:判断男生的工资与女生的工资是否分布相同,k就等于2,n等于男生工资观测数加女生工资观测数目

MSTR为组间方差

MSE为组内方差

单因子分析之类别变量

1、有效记录占比

2、种类

3、整体分布

4、按目标变量分布的差异

差异的量化:

卡方检验:用来衡量两个分类变量的独立性

多因子分析

连续型变量相关性分析

下列为查看各类数据分布的代码:

定义查看分类型因变量与连续性自变量之间的关系的函数

from pandas import DataFrame
from numpy import nan as NA
from pandas import Series
import os 
import pandas as pd
import numpy as  np
import math
import random
from matplotlib import pyplot
from pandas.tools.plotting import scatter_matrix
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
from scipy.stats import chisquare
#解决输出图片不能为含有中文
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

os.chdir('E://kaggle//risk')
bank_data=pd.read_csv('bankChurn.csv')
external_data=pd.read_csv('ExternalData.csv')

#观测单因子因素变量分布
#df--数据集
#col--需要研究的变量
#target--目标变量
#filepath--保存路径
#truncation-是否处理极端数据
def NumVarPerf(df,col,target,filepath,truncation=True):
    #塞选出有效数据集
    validDf=df.loc[df[col] == df[col]][[target,col]]
    #测算有效数据集百分比
    validRcd=validDf.shape[0]/df.shape[0]
    #以百分好数字输出  
    validRcdFmt='%.2f%%' %(validRcd*100)
    #查看与提取一些统计量
    descStats=validDf[col].describe()
    mu='%.2e' % (descStats['mean'])
    std='%.2e' % (descStats['std'])
    maxVal= '%.2e' % (descStats['max'])
    minVal = '%.2e' % (descStats['min'])
    #类别型目标变量,不同类别所要研究自变量的数据,以下代码只适合两分类,且数字分别为0和1
    x=validDf.loc[validDf[target] == 1][col]
    y=validDf.loc[validDf[target] == 0][col]
    #设定每个值的权重
    xweights = 100*np.ones_like(x)/x.size
    yweights = 100*np.ones_like(y)/y.size
    #如果truncation为True,启用下方功能,主要作用是将超过95%分为点的数值改为95%分为点数值
    if  truncation == True:
        pcnt95=np.percentile(validDf[col],95)
        x=x.map(lambda x: min(x,pcnt95))
        y=y.map(lambda y: min(y,pcnt95))
    #使用matplotlib画图
    #创建图画对象
    flg1=pyplot.figure()
    ax=flg1.add_subplot(111)
    #画条形图
    ax.hist(x,weights=xweights,alpha=0.5,label='流失客户')
    ax.hist(y,weights=yweights,alpha=0.5,label='留存客户')
    titleText = '是'+col+'的条形图'+'\n'+'有效数据收集百分比为:'+str(validRcdFmt)+','+'Mean='+str(mu)+','+'Std='+str(std)
    ax.set(title=titleText,ylabel='各数据分类百分比')
    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)

定义查看两个分类型变量的关系的函数

def CharVarPerf(df,col,target,filepath):
    #塞选出有效数据集
    validDf=df.loc[df[col] == df[col]][[target,col]]
    #测算有效数据集百分比
    validRcd=validDf.shape[0]/df.shape[0]
    #以百分好数字输出  
    validRcdFmt='%.2f%%' %(validRcd*100)
    #有效数据集数量
    recdNum=validDf.shape[0]
    #不同类别的占比
    freqDict={}
    #不同类别的流失率
    churnRateDict={}
    for v in set(validDf[col]):
        vDf = validDf.loc[validDf[col] == v]
        #计算不同类别占比
        freqDict[v]=vDf.shape[0]*1.0/recdNum
        #计算不同类别流失率,这里target必须是取值0和1.
        churnRateDict[v]=sum(vDf[target])*1.0/vDf.shape[0]
    descStats=pd.DataFrame({'percent':freqDict,'churn rate':churnRateDict})
    fig=pyplot.figure()
    ax=fig.add_subplot(111) 
    #可以理解为创建另一根Y轴
    ax2=ax.twinx()
    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='green',ax=ax2,width=0.2,position =1 )
    ax.set_ylabel('流失率-折线图')
    ax2.set_ylabel('所占百分比-条形图')
    figSavePath = filepath +str(col)+'.png'
    pyplot.savefig(figSavePath)
    pyplot.close(1)

根据以上两个函数和数据输出变量分析的图示,并且做一些方差分析和卡方检验

AllData=pd.merge(bank_data,external_data,on='CUST_ID')
columns=set(list(AllData.columns))
columns.remove('CHURN_CUST_IND')
numericCols=[]
stringCols=[]
for var in columns:
    #首先删除所选列的重复值
    x=list(set(AllData[var]))
    #删除所选列的缺失值
    x=[i for i in x if i == i]
    #判断是否为数值型变量,亦或是类别型变量,并放入不同列表
    if isinstance(x[0],numbers.Real):
        numericCols.append(var)
    elif isinstance(x[0],str):
        stringCols.append(var)
    else:
        print('该数据类型未知')
#输出图示
filepath=path+'连续型变量单因子分析图示//'
for var in numericCols:
    NumVarPerf(AllData,var,'CHURN_CUST_IND',filepath,truncation=True)
#利用F检验,查看因变量不同类型的该连续变量是否服从同一个分布,既流失率与否是否印象该变量的分布 
nova_results=anova_lm(ols('ASSET_MON_AVG_BAL~CHURN_CUST_IND',AllData).fit())
#输出图示
filepath=path+'类别型变量单因子分析图示//'
for var in stringCols:
    CharVarPerf(AllData,var,'CHURN_CUST_IND',filepath)
    
#利用卡方检验查看类别型变量是否独立,当客户流失时‘CHURN_CUST_IND’为1,否则0
chisqDf=AllData[['GENDER_CD','CHURN_CUST_IND']]
grouped=chisqDf['CHURN_CUST_IND'].groupby(chisqDf['GENDER_CD'])
#计算各类别的数目
count=list(grouped.count())
#计算各类别的流失数目
churn=list(grouped.sum())
#生成数据框
chisqTable=pd.DataFrame({'类别数量':count,'流失数量':churn})
#生成期望流失率
churn_lv=round(np.array(chisqTable['流失数量']).sum()/np.array(chisqTable['类别数量']).sum(),4)
#计算期望流失数
chisqTable['期望流失数']=chisqTable['类别数量'].map(lambda x : round(x*churn_lv))     
#使用之前导入包的卡方检验函数
chisquare_show=chisquare(chisqTable['流失数量'],chisqTable['期望流失数'])

多因子分析,得出密度函数图示

#多因子数据分析
#将较长的名字改为较短的名字
col_to_index={numericCols[i]:'var'+str(i) for i in range(len(numericCols))} 
#从众多变量中随机抽取15个,看一下他们的相关分布
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')

猜你喜欢

转载自blog.csdn.net/pandacode/article/details/81671902