美文网首页python机器学习爬虫数据分析Analytical thinking
用Logistic和随机森林建立流失预警模型

用Logistic和随机森林建立流失预警模型

作者: apricoter | 来源:发表于2019-02-28 23:32 被阅读87次

    产品如同蓄水池,用户好比池中之水。池子中每时每刻都有新用户源源不断地加入,也有一部分用户选择离开。如果用户流失超过新用户的补给,且速度越来越快、规模越来越大时,产品如若不警惕,蓄水池迟早会干涸。

    不合理的周期造成预测准确率低且不平衡,我们需要不断尝试周期划分,在保证整体准确率的情况下寻求流失与留存准确率最佳的平衡点,才能更为准确地同时预测流失及留存情况。


    流失比较经典的定义是“一段时间内未进行关键行为的用户”,关键点在于如何界定时间周期(流失周期)和关键行为(流失行为)。

    用户回访率 = 回访用户数 ÷ 流失用户数 × 100%

    通过流失预警模型,我们可以获得产品一系列功能模块或指标对流失留存的影响因子,并计算出每个用户的流失概率。通过影响因子,我们可以对流失原因有所了解,在此基础上进行深入研究和确认,结合用户反馈的频率、专家意见等确定改版的优先级。

    区分出可能流失的用户是为了提高挽留策略的针对性,提高效率与减少成本,实现精细化运营——这也是流失模型的核心价值所在。

    从用户使用的轻重程度出发(如上图),在通过模型计算出用户未来的流失概率后,将使用App的频率和时长作为用户轻重度的划分标准,结合用户流失留存预期,将用户划分为高价值、重点发展、重点转化、有待挽留等几种类型,分析每个类型用户不同的行为特点和使用痛点,采取针对性的运营策略。

    当然,流失模型也可结合付费维度进行研究。先筛选出极有可能将会流失的用户,再根据购买频次和付费金额来进行细分:从未付费的用户可通过优惠券、促销活动或超低价商品吸引回访、促成首单购买;少量付费且客单价低的用户可以精准推送符合个性化偏好的商品,或者推荐符合该用户消费层次的超值商品;多次付费的老用户,可以增加会员专属优惠,通过回馈激励增强用户粘性,延长使用周期。

    以上只是流失模型的两个层面的应用,在不同项目中还可以结合多种方式对用户进行精细化运营。模型准确性高的话,可以用更少的成本、对用户更少的干扰来留住更有价值的用户。

    下面举例:电信公司希望针对客户的信息预测其流失可能性
    从机器学习的分类来讲, 这是一个监督问题中的分类问题。 具体来说, 是一个二分类问题。

    数据预处理

    读取数据:

    from __future__ import division
    import pandas as pd
    import numpy as np
    ds = pd.read_csv('F:\churn.csv')
    col_names = ds.columns.tolist()
    print("Column names:")
    print(col_names)
    ds.shape
    

    变量说明:

    subscriberID="个人客户的ID"
    churn="是否流失:1=流失";
    Age="年龄"
    incomeCode="用户居住区域平均收入的代码"
    duration="在网时长"
    peakMinAv="统计期间内最高单月通话时长"
    peakMinDiff="统计期间结束月份与开始月份相比通话时长增加数量"
    posTrend="该用户通话时长是否呈现出上升态势:是=1"
    negTrend="该用户通话时长是否呈现出下降态势:是=1"
    nrProm="电话公司营销的数量"
    prom="最近一个月是否被营销过:是=1"
    curPlan="统计时间开始时套餐类型:1=最高通过200分钟;2=300分钟;3=350分钟;4=500分钟"
    avPlan="统计期间内平均套餐类型"
    planChange="统计结束时和开始时套餐的变化:正值代表套餐档次提升,负值代表下降,0代表不变"
    posPlanChange="统计期间是否提高套餐:1=是"
    negPlanChange="统计期间是否降低套餐:1=是"
    call_10086="拨打10086的次数"
    

    查看前5行

    ds.head()
    

    整个数据集有3463条数据, 20个维度,第二项是分类是否流失。

    查看数据类型:

    ds.info()
    

    全为浮点型数据,不需要数值转换

    首先查看因变量中各类别的比例差异,通过饼图:

    import matplotlib.pyplot as plt
    # 数据集中是否违约的客户比例
    # 为确保绘制的饼图为圆形,需执行如下代码
    plt.axes(aspect = 'equal')
    # 中文乱码和坐标轴负号的处理
    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    plt.rcParams['axes.unicode_minus'] = False
    #重命名因变量
    ds.rename(columns={'churn':'y'},inplace=True)
    # 统计客户是否违约的频数
    counts = ds.y.value_counts()
    # 绘制饼图
    plt.pie(x = counts, # 绘图数据
            labels=pd.Series(counts.index).map({0:'不流失',1:'流失'}), # 添加文字标签
            autopct='%.1f%%' # 设置百分比的格式,这里保留一位小数
           )
    # 显示图形
    plt.show()
    

    总体来说,两个类别的比例不算失衡。

    拆分数据

    # 将数据集拆分为训练集和测试集
    # 导入第三方包
    from sklearn import model_selection
    from sklearn import ensemble
    from sklearn import metrics
    
    # 排除数据集中的ID变量和因变量,剩余的数据用作自变量X
    X = ds.drop(['y'], axis = 1)
    y = ds.y
    # 数据拆分
    X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size = 0.3, random_state = 1234)
    

    Logistic模型

    建模

    from sklearn import linear_model
    #利用训练集建模
    sklearn_logistic=linear_model.LogisticRegression()
    sklearn_logistic.fit(X_train,y_train)
    #返回模型的各个参数
    print(sklearn_logistic.intercept_,sklearn_logistic.coef_)
    

    预测构建混淆矩阵

    # 模型预测
    sklearn_predict = sklearn_logistic.predict(X_test)
    # 预测结果统计
    pd.Series(sklearn_predict).head()
    
    pd.Series(sklearn_predict).value_counts()
    

    判断为不流失的为1039个

    # 导入第三方模块
    from sklearn import metrics
    # 混淆矩阵
    cm = metrics.confusion_matrix(y_test, sklearn_predict, labels = [0,1])
    cm
    

    绘制ROC曲线

    Accuracy = metrics.scorer.accuracy_score(y_test, sklearn_predict)
    Sensitivity = metrics.scorer.recall_score(y_test, sklearn_predict)
    Specificity = metrics.scorer.recall_score(y_test, sklearn_predict, pos_label=0)
    print('模型准确率为%.2f%%:' %(Accuracy*100))
    print('正例覆盖率为%.2f%%' %(Sensitivity*100))
    print('负例覆盖率为%.2f%%' %(Specificity*100))
    

    整体的预测准确率一般

    # y得分为模型预测正例的概率
    y_score = sklearn_logistic.predict_proba(X_test)[:,1]
    # 计算不同阈值下,fpr和tpr的组合值,其中fpr表示1-Specificity,tpr表示Sensitivity
    fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
    # 计算AUC的值
    roc_auc = metrics.auc(fpr,tpr)
    
    # 绘制面积图
    plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
    # 添加边际线
    plt.plot(fpr, tpr, color='black', lw = 1)
    # 添加对角线
    plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
    # 添加文本信息
    plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
    # 添加x轴与y轴标签
    plt.xlabel('1-Specificity')
    plt.ylabel('Sensitivity')
    # 显示图形
    plt.show()
    

    低于0.8,认定回归模型是不合理的

    随机森林模型

    from sklearn import ensemble
    # 构建随机森林
    RF_class = ensemble.RandomForestClassifier(n_estimators=200, random_state=1234)
    # 随机森林的拟合
    RF_class.fit(X_train, y_train)
    # 模型在测试集上的预测
    RFclass_pred = RF_class.predict(X_test)
    # 模型的准确率
    print('模型在测试集的预测准确率:\n',metrics.accuracy_score(y_test, RFclass_pred))
    
    # 计算绘图数据
    y_score = RF_class.predict_proba(X_test)[:,1]
    fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
    roc_auc = metrics.auc(fpr,tpr)
    # 绘图
    plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
    plt.plot(fpr, tpr, color='black', lw = 1)
    plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
    plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
    plt.xlabel('1-Specificity')
    plt.ylabel('Sensitivity')
    plt.show()
    

    远远高于0.8,认为模型合理

    再挑选出重要因素

    # 变量的重要性程度值
    importance = RF_class.feature_importances_
    # 构建含序列用于绘图
    Impt_Series = pd.Series(importance, index = X_train.columns)
    # 对序列排序绘图
    Impt_Series.sort_values(ascending = True).plot('barh')
    plt.show()
    

    取出重要性比较高的变量再利用交叉验证选择参数建模

    # 取出重要性比较高的自变量建模
    predictors = list(Impt_Series[Impt_Series>0.015].index)
    predictors
    

    重新建模

    # 随机森林的拟合
    RF_class.fit(X_train[predictors], y_train)
    # 模型在测试集上的预测
    RFclass_pred = RF_class.predict(X_test[predictors])
    # 模型的准确率
    print('模型在测试集的预测准确率:\n',metrics.accuracy_score(y_test, RFclass_pred))
    
    # 计算绘图数据
    y_score = RF_class.predict_proba(X_test[predictors])[:,1]
    fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
    roc_auc = metrics.auc(fpr,tpr)
    # 绘图
    plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
    plt.plot(fpr, tpr, color='black', lw = 1)
    plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
    plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
    plt.xlabel('1-Specificity')
    plt.ylabel('Sensitivity')
    plt.show()
    

    远远高于0.8且准确率上升,认为模型合理

    相关文章

      网友评论

        本文标题:用Logistic和随机森林建立流失预警模型

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