案例实战:客户价值预测模型

作者: 王小鹏的随笔 | 来源:发表于2020-07-03 10:11 被阅读0次

    同步更新在今日头条 (机器学习and数据科学)
    案例实战:客户价值预测模型
    同步更新在个人网站:http://www.wangpengcufe.com/machinelearning/pythonml-pythonml7/

    原理: 利用多元线性回归模型根据多个因素预测客户价值,当模型搭建完成后,就可以对不同价值的客户采用不同的业务策略。

    目录:

    • 1、案例背景
    • 2、案例主要应用技术
    • 3、案例数据
    • 4、案例过程
      • 4.1、导库
      • 4.2、数据读取
      • 4.3、数据探索
      • 4.4、数据预处理
        • 4.4.1、重复值处理
        • 4.4.2、异常值处理
        • 4.4.3、缺失值处理
      • 4.5、特征工程
        • 4.5.1、特征相关性分析
        • 4.5.2、目标相关性分析
        • 4.5.3、特征构造
      • 4.6、模型搭建
        • 4.6.1、构建特征值和目标值
        • 4.6.2、划分训练和测试集
        • 4.6.3、模型搭建
      • 4.7、线性回归方程构造
      • 4.8、模型评估
      • 4.9、评估结果解读
    • 5、案例数据结论

    一、案例背景:

    客户价值预测就是指客户未来一段时间能带来多少利润,其利润的来源可能来自于信用卡的年费、取现手续费、分期手续费、境外交易手续费用等。而分析出客户的价值后,在进行营销、电话接听、催收、产品咨询等各项服务时,就可以针对高价值的客户进行区别于普通客户的服务,有助于进一步挖掘这些高价值客户的价值,并提高这些高价值客户的忠诚度。

    二、案例主要应用技术

    本案例用到的主要技术包括:

    • 数据建模: 线性回归模型LinearRegression
    • 模型评估:statsmodels
    • 模型可视化:matplotlib 、seaborn 画图
    • 主要用到的库包括:pandas 和 Sklearn

    本案例使用的开发工具是 jupyter notebook,故很多地方直接写对象,就能输出结果,不需要写print(),如果是在其他的编辑器,在输出时,需要加上print()。

    三、案例数据

    以下是数据概览:
    特征变量数:5
    数据记录数:128
    是否有NA值:有
    是否有异常值:有
    以下是本数据集的5个特征变量,包括:
    load_amount : 历史贷款金额,整数型变量。
    loan_time :贷款次数,整数型变量。
    edu:学历,分类型变量, 值域[高中, 本科,研究生]。
    salary:薪水,整数型变量。
    sex:性别,值域为男或女。
    目标变量value :客户价值打分,整数型变量。

    四、案例过程

    4.1、导库

    import pandas as pd  # pandas库
    from sklearn.preprocessing import LabelEncoder # 编号处理
    from sklearn.model_selection import train_test_split # 划分训练集和测试集
    from sklearn.linear_model import LinearRegression # LinearRegression 线性回归模型
    import statsmodels.api as sm  # 模型评估
    import matplotlib.pyplot as plt  # 画图
    import seaborn as sns  # 画图
    plt.rcParams["font.sans-serif"]='SimHei' # 中文乱码
    plt.rcParams['axes.unicode_minus']=False # 负号无法正常显示
    %config InlineBackend.figure_format='svg' # 像素清晰
    

    pandas:常用的数据读取、 展示、处理和数据保存库。
    LabelEncoder :sklearn库中数据预处理的preprocessing 包下的整数编码类,用来将非数值对象转换为数值类型。
    train_test_split :sklearn库中用来划分训练集和测试集的类。
    LinearRegression:sklearn库中linear_model 包下面的线性回归类,用来建立线性回归模型。
    statsmodels.api :引入线性回归模型评估相关库。
    matplotlib.pyplot :引入matplotlib库进行模型可视化画图。
    seaborn :引入seaborn 库进行可视化画图。
    除了上述库以外,还需要关于使用pandas读Excel需要的附属库。如果之前没有安装过这个库, 需要在系统终端命令行窗口使用pip install xlrd 完成安装。这个库无需导入,在Pandas读取Excel时会自动调用。
    用pip install xlwt

    4.2、数据读取

    df = pd.read_excel('Customer_value.xlsx')
    

    4.3、数据探索

    数据形状:

    df.shape
    

    打印输出:(128, 6)
    shape方法用来查看当前数据的形状,返回一个二维的数据元祖,逗号前面的数值表示128行,逗号后面的数值表示6列。

    数据类型:

    df.info()
    

    返回结果如下:


    image.png

    info方法用来查看数据的类型和缺失情况:

    • 从整体看,数据总共有128条,范围是[0,127], 总共有6列。从具体字段看,value(客户价值)是整数型,共128条未缺失,缺失值为0。loan_amount(贷款金额)是整数型,共128条未缺失,缺失值为0。loan_time(贷款次数)是整数型,共128条未缺失,缺失值为0。edu(教育程度)是object对象,需要处理成数值,共128条未缺失,缺失值为0。salary (薪水) 是整数型,共126条未缺失,缺失值为2。sex(性别) 是object对象,需要处理成数值,共128条未缺失,缺失值为0。
    • 统计的结果:总共的类型有 整数型字段4个,object对象2个。
    • 内存使用情况:6.1kb的内存

    查看前几行:

    df.head()
    
    在这里插入图片描述

    head方法用来显示指定数据(N)的前N数据,不指定N的话,默认显示前5条。

    数据概览:

    df.describe()
    
    image.png

    describe方法用来显示数据中所有为数值类型的数据记录数、均值、标准差、最小值、 25%、 50%、75%分位数数据,最大值。

    4.4、数据预处理

    经过数据的探索,我们知道了数据中有缺失值,有非数值对象。这样就需要做2个数据预处理的工作,处理缺失值,和将非数值对象转换为数值对象。在此之前,我们先看看有无重复值。

    4.4.1、重复值处理

    重复数据查询:

    df[df.duplicated()]
    

    输出结果:


    在这里插入图片描述

    duplicated()函数可以查询重复的内容。可以看到第62行记录重复了,被代码筛选了出来。

    查看重复的数量:

    df.duplicated().sum()
    

    输出结果为:1。说明数据中只有一行数据重复了。

    删除重复数据:

    df = df.drop_duplicates()
    

    需要注意的是,drop_duplicates()函数并不改变原表格结构,所以需要进行重新赋值,或者在其中设置inplace参数为True。
    再次查看数据类型:

    df.info()
    
    image.png

    可以看到从整体看,数据的数量变成了127行了,比之前的128少了一行,说明重复值删除成功。
    4.4.2、异常值处理
    处理完了重复值,我们再来看看数据中有无异常值。
    查看异常值,我们可以用箱体图进行观察。查看整体的异常情况:

    df.boxplot()
    

    输出结果:


    image.png

    可以看到value,loan_amount,loan_time,salary中分别有异常值。不过,异常值是否都直接删除,需要我们结合具体的业务来考虑。value(客户价值)只超过最大值一点,可以不删除。loan_amount(贷款金额)也只比最大值大一点,不是大的很过分,可以考虑不删除,同理,薪水的异常值也可以认为是可接受的范围内。由于load_time(贷款次数)的数据量纲和其他的不一致,我们可以单独查看:

    df[['loan_time']].boxplot()
    

    输出结果:


    image.png

    我们可以看到,有一个贷款次数,是要远远大于其他数据的,结合实际业务情况,我们可以认为这个是异常值,(贷款这么多次,银行的征信还能过得去吗)。当然最保险的做法是和业务人员再进行一次确认,然后进行异常值删除。这里,我们暂且认为这个贷款次数30次的人就是异常值。
    我们可以找到这条记录:

    df[df['loan_time']==30]
    

    输出结果:

    在这里插入图片描述
    删除异常值:
    df = df.drop(df[df['loan_time']==30].index)
    

    查看结果:

    df[df['loan_time']==30]
    

    输出结果:


    在这里插入图片描述

    可以看到数据中已经查不到原来的这条异常记录了。

    4.4.3、缺失值处理

    之所以把缺失值放在异常值处理之后,是因为,缺失值通常用平均值,中位数等方法填补,如果数据中有异常值的话,求平均会影响到缺失值的数值。

    刚才已经通过数据探索,发现了salary(薪水)一列中有缺失值,那么我们可以用代码将其筛选出来:

    df[df['salary'].isnull()]
    

    输出结果:


    在这里插入图片描述

    可以看到26行和60行的薪水一列是缺失的。
    缺失值通常处理的方法是删除,平均值填补,中位数填补。根据实际情况,我们这里用平均值法填补。

    df = df.fillna(df.mean())
    

    再次确认填补效果:

    df.info()
    
    image.png

    可以看到,数据中已经没有缺失值了。至此,数据预处理的工作已经做完,下面我们开始特征工程的工作。

    4.5、特征工程

    首先我们查看是否还具有多重共线性的数据,我们查看特征之间的相关性。
    4.5.1、相关性分析
    首先获取所有的特征变量:

    feature = df.drop(['value'],axis=1)
    feature.head()
    
    在这里插入图片描述

    然后我们查看特征之间的相关性,得到相关性矩阵:

    corr = feature.corr()
    corr
    
    在这里插入图片描述

    我们将特征矩阵进行热力图可视化展示:

    plt.figure(figsize=(10,6))
    ax = sns.heatmap(corr, xticklabels=corr.columns, yticklabels=corr.columns, 
                     linewidths=0.2, cmap="RdYlGn",annot=True)
    plt.title("Correlation between variables")
    
    image.png

    从图中,我们可以看出特征之间没有很强的相关性,没有需要处理的共线性的问题。需要注意的是,特性矩阵只会分析数值类型的特征,不会分析非数值对象的特征。

    4.5.2、目标相关性分析

    df_onehot = pd.get_dummies(df)
    df_onehot.head()
    
    在这里插入图片描述
    plt.figure(figsize=(15,4))
    df_onehot.corr()['value'].sort_values(ascending=False).plot(kind='bar')
    plt.title('Correlation between value  and variables ')
    
    image.png

    可以看到目标对象value(客户价值)跟贷款金额,薪水,贷款次数高度相关,和性别无关。和学历相关,其中,和本科成正相关,和高中成负相关,跟研究生学历关系不大,这可能是样本中研究生比例小造成的。说明学历对客户价值还是有一定影响的。
    我们可以看一下样本中学历构成情况:

    df['edu'].value_counts()
    
    在这里插入图片描述

    研究生只有4例。

    4.5.3、特征构造
    非数值型对象是不能直接进行机器建模学习的,所以我们要处理非数值对象,将其转换为数值对象。这里,我们要用到LabelEncoder函数。

    le = LabelEncoder()
    edu = le.fit_transform(df['edu'])
    df['edu'] = edu
    sex = le.fit_transform(df['sex'])
    df['sex'] = sex
    df.head()
    
    在这里插入图片描述

    通过LabelEncoder函数,我们将原来的数值转换成为了数值,这样就为后面的机器学习建模做好了准备。有的小伙伴会问:那原来edu(学历)中的高中,本科,研究生怎么和数值1,2对应呢?这是个好问题啊,我们可以这样来做。即通过LabelEncoder转换前后的计数我们可以进行比较,具体方法如下:
    首先我们做一下转换前的计数:

    df['edu'].value_counts()
    
    在这里插入图片描述
    df['sex'].value_counts()
    
    在这里插入图片描述

    然后我们做一下转换之后的计数:

    df['edu'].value_counts()
    
    在这里插入图片描述
    df['sex'].value_counts()
    
    在这里插入图片描述

    这样,对应关系就一目了然,不用我再说了吧!

    4.6、模型搭建

    4.6.1、构建特征值和目标值

    # 构建特征值X 和目标值 Y
    X = df.drop('value',axis=1)
    y = df['value']
    

    x是包含了除value以外的所有列,y只是value这一列。

    4.6.2、划分训练和测试集

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
    

    test_size=0.2,表示用20%的数据测试,用80%的数据来训练。得到的结果为X的训练集X_train, X的测试集X_test, y的训练集 y_train, y的测试集 y_test。

    4.6.3、模型搭建

    regr = LinearRegression()
    regr.fit(X, y)
    y_pred = regr.predict(X_test)
    

    4.7、线性回归方程构造

    regr.coef_
    
    在这里插入图片描述
    print('各系数为:' + str(regr.coef_))
    print('常数项系数k0为:' + str(regr.intercept_))
    
    在这里插入图片描述
    最后得到的线性方程为:y = 129 + 0.059x1 + 95x2 - 53x3 + 0.054x4 + 7.53*x5

    4.8、模型评估

    X2 = sm.add_constant(X)
    est = sm.OLS(y, X2).fit()
    est.summary()
    
    image.png
    x = len(y_pred)
    plt.plot(range(x), y_pred, label='预测值')
    plt.plot(range(x), y_test, label='真实值')
    plt.title('真实值和预测值对比走势图')
    plt.xticks([])
    plt.legend()
    plt.show()
    
    image.png
    regr.score(X_test, y_test)
    

    输出结果:准确率为0.6470898016296844

    4.9、评估结果解读

    1、coef列,就是常数项(const)和特征变量(loan_amount, load_time, edu, salary, sex)前的系数,即截距b和斜率系数,可以看到,这和之前求出的结果是一致的。

    2、对模型评估而言,需要关心的几个指标有 R-squared、Adj.R-squared 和P值的信息。

    2.1、这里的R-squared为0.548, Adj.R-squared为0.529,说明模型的线性拟合程度还不是特别好,可能因为案例额数据量偏少,不过在此数据量条件下也算可以接受的结果。

    2.2、对P值而言,大部分的P值都较小,的确与目标变量(客户价值)是显著相关的,而sex这一特征的P值达到了0.819,说明性别和目标变量是没有显著相关性的,这个结论也符合经验认知。之后的建模中就可以舍去这一特征变量了。

    五、案例数据结论

    1、从特征的相关性来看,目标对象value(客户价值)跟贷款金额,薪水,贷款次是呈现高度相关的。这说明用户历史贷款的记录越多,客户的给企业带来了利润,客户的价值自然要高。

    2、客户价值和性别无关。

    3、客户价值和学历相关,其中,和本科成正相关,和高中成负相关,跟研究生学历关系不大,可能学历太低风险性会高一点,客户的价值相对低一点。案例中研究生学历太少,导致结果是跟研究生学历关系不大。

    4、模型的整体准确率只有0.65,R-squared为0.548, Adj.R-squared为0.529,说明模型的拟合程度不是特别满意,可能是案例的数量偏少。不过在此数据量条件下也算可以接受的结果。

    相关文章

      网友评论

        本文标题:案例实战:客户价值预测模型

        本文链接:https://www.haomeiwen.com/subject/rfbjqktx.html