利用python建立客户流失预警模型(上)——数据处理部分

利用python建立客户流失预警模型(上)——数据处理部分

前言

看了不少文章受益匪浅,我也来在这里尝试总结一下自己运用到的,旨在和大家一起交流学习,请各位大佬多多指教。
下面进入正题,数据为商业银行的客户数据,将数据集分为训练集和测试机:
1、构建客户流失预警模型(bad_good为被解释变量);
2、通过相关变量构建客户画像系统;
3、根据两个模型,提出流失客户的应对策略
我将从数据处理和模型建立两个部分来展开。

数据处理

数据探索

一、读入数据

import pandas as pd
data=pd.read_csv('train.csv',sep=',',index_col=None)

二、数据探索
1、是否有缺失值

data.isnull().any().any()#查看data是否存在缺失值
v_null=data.isnull().any()#查看每个变量是否缺失
v_null=v_null[v_null==True].reset_index()#取出有缺失值的变量
v_null=data[v_null['index']]#取出有缺失值
v_isnull().sum()
#若缺失值比较多使用fillna进行填充
data['变量名'].fillna(data['变量名'].mean())

2、查看是否有逻辑上的重复数据,即重复样本

len(np.unique(data['主键名']))#若等于样本数则没有重复,否则运行下列代码
sta=data['主键名'].value_counts()#统计出现次数
sta=sta[sta>1]#取出重复样本,并予以删除

3、查看离散与连续数据分布

dis=data[离散变量].apply(pd.value_counts)#查看离散连续变量
con=data[连续变量].describe()

在此数据中看到性别有X的样本,需要后续处理,同时大多FLAG变量属性不统一,存在N、Y、0、1共存的情况,需要后续将其统一
4、变量整理与衍生变量
首先从变量层面对原有的628个变量做整理,得到离散变量、交易金额和笔数最大最小变量、存在本期3个月6个月变量以及其他变量
1)离散变量:
首先进行属性的统一,使用map将之映射为0或1
对于其中基金,将所有基金标志合并,只要有一类为1,即最终为1
对于其中国债,将所有国债标志合并,只要有一类为1,即最终为1
对于客户卡,按带有白金、钻石以及无限卡作为VIP,其余为非VIP
2)最大最小变量:
删除最小变量,因为其仅有极少数样本有值且值都不大,研究意义不大
有的变量可以整合成一个变量,将其取最大来表示
新衍生变量转入转出金额最大为不同途径金额最大和
3)本期3个月6个月变量:
首先,考虑仅保留6个月变量作为较稳定的衡量指标
新衍生变量活跃度:本期除以3个月比率和3个月除以6个月比率以7:3权重综合得到
新衍生变量转入转出比率
新衍生变量资产负债比
新衍生变量集中度,不同渠道或产品的最大值以及最大值对应的活跃度:分别对于交易金额与笔数、投资金额、转入转出金额与笔数进行构造
4)其他变量:
有的无6个月数据但可以根据其他变量计算出6个月数据,故将其他中的本期与3个月数据删除,还可以删除一些对业务没有影响的变量
5)当数据量大时,每做完一次操作可考虑保存数据,否则每次运行耗费大量时间

#对分类与连续变量做统计进行清洗并初步筛选变量
all_names=data.columns.values.tolist()                                              #取所有变量名
all_names.remove('bad_good')
remove_variable=[]
data['GENDER']=data['GENDER'].map({1:'1',2:'2','2':'2','1':'1','X':'X'})
for i in range(len(all_names)):                                                      #删除值全一样的变量
    if len(np.unique(data[all_names[i]]))==1:
        remove_variable.append(all_names[i])
data=data.drop(remove_variable,axis=1,inplace=False)
all_names=list(set(all_names).difference(set(remove_variable)))
del remove_variable

discrete_variable=['OPEN_ORG_NUM','IDF_TYP_CD','GENDER']                             #取离散变量名
for i in range(len(all_names)):                                                      #补全离散变量名
    if all_names[i].upper().endswith('FLAG'):
        discrete_variable.append(all_names[i])
IND_variable=[]
for i in range(len(all_names)):                                                      #对应最大渠道或投资产品
    if all_names[i].upper().endswith('IND'):
        IND_variable.append(all_names[i])
data_ind=data[IND_variable]
data=data.drop(IND_variable,axis=1,inplace=False)
continuous_variable=list(set(all_names).difference(set(
                 discrete_variable)).difference(set(IND_variable)))           #取连续变量名
sta_data=data[discrete_variable].apply(pd.value_counts)                            #查看变量频次
con_data=data[continuous_variable].describe()
                         

5、值替换
1)根据训练集中男女性别比对X值进行随机替换

sum1=data.groupby('GENDER').size()[0]                                               #查看性别频次,获取男女比
sum2=data.groupby('GENDER').size()[1]                                               #大的设置为sum1,小的为sum2
data_gender=data[data['GENDER']=='X'].reset_index()['index'].tolist()
for i in data_gender:                                                          
	random.seed(6)      #男女比随机生成性别                                                 
    data.loc[i,'GENDER']=str(math.ceil(random.randint(1,sum1+sum2)/sum1))
data['GENDER']=train['GENDER'].map({'1':1,'2':2})
sta_data=data[discrete_variable].apply(pd.value_counts)   

2)对之前数据探索中离散变量中属性较多的变量利用贝叶斯平滑得到流失率,并观察人为给定划分界限,将离散变量属性合并,得到属性较少的变量

转化率(CTR)预测的贝叶斯平滑https://blog.csdn.net/jinping_shi/article/details/78334362

def est(data):                                                                       #计算贝叶斯平滑参数
    datamean=sum(data.iloc[:,1]*data.iloc[:,3])/sum(data.iloc[:,1])
    datavar=sum(data.iloc[:,1]*pow(data.iloc[:,3]-datamean,2))/(sum(data.iloc[:,1])-1)
    a=datamean*(datamean*(1-datamean)/datavar-1)
    b=(1-datamean)*(datamean*(1-datamean)/datavar-1)
    return a,b

5.筛选变量
1)初步筛选:删除所有样本的值均相同的变量
2)筛选离散变量(离散与离散关系):一般使用卡方检验,也可以使用计算WOE与IV,通过IV的大小来判断,一般小于0.2的删除,大于0.6的与因变量特别相关,考虑是否合适,其余可以保留


#使用卡方检验筛选分类变量
dis_chi2=pd.DataFrame({'name':discrete_variable,'p_value':chi2(train[discrete_variable],train.bad_good)[1]})             #建表
dis_chi2=dis_chi2[dis_chi2.p_value<0.05].sort_index(by='p_value').reset_index().drop('index',axis=1,inplace=False)  #卡方检验显著变量与p值

left_dis=dis_chi2.name.tolist()                                                      #剩下的变量
dis_remove=list(set(discrete_variable).difference(set(left_dis)))                    #删掉的变量
all_names=list(set(all_names).difference(set(dis_remove)))                           #删除变量
data=data.drop(dis_remove,axis=1,inplace=False)
del dis_remove,discrete_variable

https://blog.csdn.net/sscc_learning/article/details/78591210

3)筛选连续变量(连续与离散关系):一般使用方差分析,看离散变量属性的均值有无差异,但方差分析需要满足正态性、方差齐性以及独立性条件,需要先KS检验正态性以及检验方差齐性才可进行方差分析;若不满足则考虑使用曼-惠特尼U检验。(也可以使用相关性分析或者MI互信息来考察变量之间的相关程度)

#筛选连续变量
data0=data[data.bad_good==0]
data1=data[data.bad_good==1]
sel_con=pd.DataFrame({'name':continuous_variable,'ks0p_value':1,'ks1p_value':1,
                      'lp_value':1,'ap_value':1,'Up_value':1})
for i in range(len(continuous_variable)):                                            #检验正态性、方差齐性
    d0=data0[continuous_variable[i]]                                              #方差分析与非参数检验
    d1=data1[continuous_variable[i]]                                              #筛选变量
    args=[d0,d1]
    sel_con.loc[i,'ks0p_value']=kstest(data0[continuous_variable[i]],'norm')[1]
    sel_con.loc[i,'ks1p_value']=kstest(data1[continuous_variable[i]],'norm')[1]
    sel_con.loc[i,'lp_value']=stats.levene(*args)[1]
    sel_con.loc[i,'ap_value']=anova_lm(ols(continuous_variable[i]+'~bad_good',data).fit()).iloc[0,4]
    sel_con.loc[i,'Up_value']=stats.mannwhitneyu(d0,d1)[1]
con_U=sel_con[sel_con.Up_value<0.05].sort_index(by='Up_value').reset_index()[['name','Up_value']]
left_con=con_U.name.tolist()  #剩下的变量                                                    

6.数据归一或标准化
主要是为了消除变量之间数量级的差异,对于回归以及需要计算距离的问题尤为重要,也为后续使用过采样方法做准备。主要有归一化、标准化或取对数这些方法。

#数据归一化
data_all=data.append(test).reset_index()
data_all=data_all.drop('index',axis=1,inplace=False)
data_all=pd.DataFrame(preprocessing.MinMaxScaler().fit_transform(data_all.values),columns=data_all.columns)
train=data_all.iloc[:len(data),:]
test=data_all.iloc[len(data):,:]
del data_all

7.采样方法
可以进行过采样、欠采样、双采样的方法来处理不平衡数据,最为普通的就是简单的对原样本进行少类重抽样或者多类随机删除的方法;过采样较新的方法可由SMOTE方法人工合成大量少类样本。

#过采样,可改变种子
x_train,y_train=SMOTE(random_state=666,kind='borderline2').fit_sample(train.iloc[:,1:],train.bad_good)
y_train=list(map(int,y_train))
#x_train=train.iloc[:,1:].values
#y_train=train.bad_good.values
x_test=test.iloc[:,1:].values
y_test=test.bad_good.values
  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值