21_多易教育之《yiee数据运营系统》用户画像-模型标签流失预测篇兼退拒风险概率预测篇

目录

一、模型标签流失预测篇

       1、流失概率预测需求

       2、算法选择-朴素贝叶斯分类算法

       3、特征工程-选择特征

       4、特征工程-特征数据源

       5、特征工程-特征值离散化

       6、特征工程-向量规范化

       7、机器学习-模型训练

       8、机器学习-流失率预测

二、退拒风险概率预测篇


一、模型标签流失预测篇

1、流失概率预测需求

根据用户的活跃度及消费情况,判断用户的流失意向。可及时对有流失趋向的用户做营销召回
21_多易教育之《yiee数据运营系统》用户画像-模型标签流失预测篇兼退拒风险概率预测篇_第1张图片
像这样的概率型结论,通过一个普通的算术运算来得出的话,不会太靠谱!
要通过历史既定事实的经验(满足某些特征的人群中,哪些流失了,哪些没流失),来得出,才会更靠谱!

2、算法选择-朴素贝叶斯分类算法

用户是否流失,是一个典型的概率分类问题
所以,第一时间想到用朴素贝叶斯算法来实现

3、特征工程-选择特征

特征选择的原则: 所选取的特征,应该跟流失与否有关联!
活跃属性:
       3/7/15/30日登录次数
       3/7/15/30日访问时长
       3/7/15/30日访问深度
消费属性:
       3/7/15/30日消费金额
       3/7/15/30 订单均价
       3/7/15/30日最大单笔消费金额
       3/7/15/30日最小单笔消费金额
       3/7/15/30日退换货次数、占比
       3/7/15/30日拒收次数、占比
最后一次登录距今天数
最后一次购买距今天数
事件属性:
       3/7/15/30/累计 好评数
       3/7/15/30/累计 差评数
       3/7/15/30/累计 分享数

《详细参考数仓中的几个画像报表: 活跃行为画像报表,消费订单画像报表,消费商品画像报表》

4、特征工程-特征数据源

从公司大量的流失用户(标签:已流失)中,随机挑选1万人
从公司大量的未流失用户中,随机挑选1万人
将这2万人的数据(特征)组成先验样本集!

标签,特征1,特征2,特征3,特征4,特征5,特征6………
标签,特征1,特征2,特征3,特征4,特征5,特征6………
标签,特征1,特征2,特征3,特征4,特征5,特征6………
21_多易教育之《yiee数据运营系统》用户画像-模型标签流失预测篇兼退拒风险概率预测篇_第2张图片
这些样本数据从哪里去获取?
       从事实明细标签库(存在hdfs中)中取

5、特征工程-特征值离散化

连续数字的区间化处理,减少值的种类数
由于本案例中,各个特征值,都是一些“连续”数字,无法在概率计算上体现同类别的共同特征,所以,此案例中的特征向量化,需要做一个非常关键的处理:

将特征值区间化(离散化)!
	3日登录次数:  0~2 低频    3~6 ->中频     7~ +  -> 高频
	7登录次数:    0~6 低频    7~14 ->中频    15~ +  -> 高频
	15录次数:     0~14 低频   15~30->中频    31~ +  -> 高频
	30登录次数:   0~29 低频   30~60 ->中频    61~ +  -> 高频

	3日访问时长:    0~2 低频    3~6 ->中频     7~ +  -> 高频
	7日访问时长:    0~6 低频    7~14 ->中频    15~ +  -> 高频
	15日访问时长:   0~14 低频   15~30->中频    31~ +  -> 高频
	30日访问时长:   0~29 低频   30~60 ->中频    61~ +  -> 高频

6、特征工程-向量规范化

数字特征的值域差别太大的问题

有些特征的值域范围在50万-100万

有些特征的值域范围在0-30

在算法中,值域范围大的,对最终结果的影响会明显超出值域范围小的特征,带来预测准确度的降低(相当于把别的特征给忽略掉了)

所以,还需要对特征的值域进行规范化处理

7、机器学习-模型训练


/**
  * @date: 2019/8/10
  * @site: www.doitedu.cn
  * @author: hunter.d 涛哥
  * @qq: 657270652
  * @description: 模型标签计算程序
  * @模型标签: 价值指数
  * @模型标签: 流失概率
  * @模型标签: 退拒风险
  */
object LossProbabilityModelTrainer {


  def main(args: Array[String]): Unit = {
    val spark = SparkUtil.getSparkSession(this.getClass.getSimpleName)
    import spark.implicits._


    /**
      * 加载样本特征数据:
      * 数仓的用户活跃度统计报表(每个人的平均访问深度、时长,次数、间隔....)
      * 数仓的用户消费订单画像统计报表(每个人的消费总额、平均金额、客单价、消费时间间隔、笔数、首单距今天数、末单距今天数,退换拒收次数、占比)
      * 数仓的用户商品画像统计报表(每个人消费的最多品类,最多商品,消费的价格偏好区间..........)
      * 事实标签
      */

    val sample = spark.read.option("header", "true").csv("user_profile/data/modeltag/modeltag_sample/liushi_sample.csv")
    // 将特征数据向量化
    val featureMatrix = sample.rdd.map({
      case Row(label: String, gid: String, t1: String, t2: String, t3: String, t4: String, t5: String, t6: String, t7: String, t8: String, t9: String, t10: String, t11: String, t12: String)

      =>
        (gid,label.toDouble,
          Vectors.dense(
            Array(
              t1.toDouble,
              t2.toDouble,
              t3.toDouble,
              t4.toDouble,
              t5.toDouble,
              t6.toDouble,
              t7.toDouble,
              t8.toDouble,
              t9.toDouble,
              t10.toDouble,
              t11.toDouble,
              t12.toDouble
            )
          )
        )
    }).toDF("gid","label","vec")


    featureMatrix.show(30,false)


    /**
      * 特征向量处理:统一特征值的顺序,对需要进行区间化的做区间化
      * 对需要进行值域规范化的进行规范化操作
      *
      * sparkmllib中提供了4种向量规范化算法工具
      *
      * 这里是4种向量规范化算法
      * val norm = new Normalizer().setInputCol("vec").setOutputCol("norm").setP(1)
      *norm.transform(data).show(10,false)
      * *
      * val sd = new StandardScaler().setInputCol("vec").setOutputCol("stand").setWithMean(true).setWithStd(true)
      *sd.fit(data).transform(data).show(10,false)
      * *
      * val minscalar = new MinMaxScaler().setInputCol("vec").setOutputCol("minmax")
      *minscalar.fit(data).transform(data).show(10,false)
      * *
      * val maxscalar = new MaxAbsScaler().setInputCol("vec").setOutputCol("maxabs")
      *maxscalar.fit(data).transform(data).show(10,false)
      */
    val scaler = new MinMaxScaler().setInputCol("vec").setOutputCol("normed_vec")
    val normed = scaler.fit(featureMatrix).transform(featureMatrix).drop("vec")
    normed.show(30,false)


    /**
      * 构造朴素贝叶斯算法,并用样本特征来训练模型
      */
    val bayes = new NaiveBayes()
        .setSmoothing(0.01)
        .setLabelCol("label")
        .setFeaturesCol("normed_vec")

    val model = bayes.fit(normed)
    /**
      * 保存训练好的模型
      */
    model.save("user_profile/data/modeltag/model")
    spark.close()
  }
}

8、机器学习-流失率预测

/**
 * @date: 2019/8/15
 * @site: www.doitedu.cn
 * @author: hunter.d 涛哥
 * @qq: 657270652
 * @description: 流失概率预测 : 即流失概率标签计算
 */
object LossProbabilityPredict {

  def main(args: Array[String]): Unit = {

    val spark = SparkUtil.getSparkSession(this.getClass.getSimpleName)
    import spark.implicits._
    import org.apache.spark.sql.functions._

    val sample = spark.read.option("header", "true").csv("user_profile/data/modeltag/modeltag_test")


    // 将特征数据向量化
    val featureMatrix = sample.rdd.map({
      case Row(gid: String, t1: String, t2: String, t3: String, t4: String, t5: String, t6: String, t7: String, t8: String, t9: String, t10: String, t11: String, t12: String)

      =>
        (gid,
          Vectors.dense(
            Array(
              t1.toDouble,
              t2.toDouble,
              t3.toDouble,
              t4.toDouble,
              t5.toDouble,
              t6.toDouble,
              t7.toDouble,
              t8.toDouble,
              t9.toDouble,
              t10.toDouble,
              t11.toDouble,
              t12.toDouble
            )
          )
        )
    }).toDF("gid","vec")


    // 向量规范化
    val scaler = new MinMaxScaler().setInputCol("vec").setOutputCol("normed_vec")
    val normedMatrix = scaler.fit(featureMatrix).transform(featureMatrix).drop("vec")


    val model = NaiveBayesModel.load("user_profile/data/modeltag/model")

    // 用模型去预测流失率
    val prediction =  model.transform(normedMatrix)
     // .show(10,false)
    /**
      * +---+-------------------------------------------------+-----------------------------------------+----------+
      * |gid|normed_vec                                       |probability                              |prediction|
      * +---+-------------------------------------------------+-----------------------------------------+----------+
      * |11 |[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.0]|[4.499154745714537E-4,0.9995500845254286]|1.0       |
      * |12 |[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0]|[0.999999999999992,8.079939852611191E-15]|0.0       |
      * +---+-------------------------------------------------+-----------------------------------------+----------+
      */



    val getLossProb: UserDefinedFunction = udf((v:linalg.Vector)=> {v.toArray(1)})
    spark.udf.register("getprob",getLossProb)
    prediction.createTempView("prediction")



    // 整理结果成为标签模型: gid,模块名,标签名,标签值,权重值

    spark.sql(
      """
        |select
        |gid as gid,
        |'M010' as module,
        |'T107' as tagname,
        |getprob(probability) as tagvalue,
        |-9999 as weight
        |from  prediction
        |
      """.stripMargin)

        .show(10,false)

    spark.close()
  }
}

二、退拒风险概率预测篇

《方案和流程都雷同“流失概率”标签的计算,只是特征选取不同》

《详见项目代码》

你可能感兴趣的:(大数据综合实战项目)