一文带你揭秘并实现“大数据杀熟”背后的逻辑!_大数据杀熟ppt(4)

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

一般来说,“太便宜”和“太贵”的交点作为最优价格点,因为在此处觉得“不过于便宜也不过于昂贵”的消费者最多。但是也有人认为“便宜”和“贵”的交点是最优价格,因为该交点取得了“划算,肯定会买”及“贵,但能接受”的平衡点,是能让最多消费者满意的价格。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PSM模型的缺陷及解决
  • 存在的问题

第一:只考虑到了消费者的接受率,忽视了消费者的购买能力,即只追求最大的目标人群数。但事实上,即使消费者觉得价格合理,受限于购买力等因素,也无法购买。

第二:研究中消费者可能出于各种因素(比如让价格更低能让自己收益,出于面子问题而抬高自己能接受的价格等)有意或无意地抬高或压低其接受的价格。由于消费者知道虚拟世界中的产品(道具或服务)没有成本,其压低价格的可能性较高。

第三:没有考虑价格变化导致的购买意愿(销量)变化。

  • 解决方案

第一:为了避免购买力的影响, 问卷或访谈研究中要强调“定这个价格,以自己目前的情况是否会购买”,而非仅仅去客观判断该产品值多少钱。

第二:为了解决玩家抬高或压低价格的问题,可以增大样本量,预期随机误差可以相互抵消。

第三:仅仅从曲线获得最优价格,受到玩家压低或抬高价格的影响较大。由于该误差可能是系统误差,对此,可以用所获得的价格区间设计不同的价格方案,然后设计组间实验设计,每个参与研究的消费者只接触其中一种或几种价格方案,并对该价格方案下是否购买及购买数量做出决策,通过计算那种价格方案下玩家消费金钱量最高来分析出最佳价格方案。如下表。

第四:通过前一条中提到的组间实验设计,可以计算出不同价格下玩家购买意愿的变化,从而得知价格调整会对整体收益带来的影响。此外,价格接受比例还可以作为消费者对某价格满意度的指标,用于计算某价格下企业该产品的良性收益。

注意,我们的上述对策部分基于统计学和实验心理学理论,部分基于我们工作中的实践,欢迎大家讨论和优化。
在这里插入图片描述
        以上都是基于大量理论后得出的结果,下面我们来结合用户画像的项目,来“模拟”商家给不同价格敏感度的用户打上不同标签的过程。

用户画像

首先我们在web页面,先添加上我们本次需要给用户开发的标签和标签值。
在这里插入图片描述
        查看数据库
在这里插入图片描述
        现在有了数据,我们本该就可以直接上手代码了。但为了简便开发,避免重复的步骤,我们先来分析一下业务需求。

业务分析

我们如果要实现根据不同的人给出不同的价格,那么如何才能确定用户的价格敏感度( PSM)?

这里有一个公式:

psm = 优惠订单占比 + 平均优惠金额占比 + 优惠总金额占比

是不是刚看有点懵,我们再来细化一下。

优惠订单占比 = 优惠次数/总购买次数

平均优惠金额占比 = 平均优惠金额/平均应收金额

平均优惠金额=优惠总金额/优惠总次数

平均应收金额 = 应收总金额 /订单总次数

优惠总金额占比 = 优惠总金额/应收总金额

在这里插入图片描述
        
        综上所述,我们可以将计算PSM的目标进一步变成计算以下四个数据,只要将它们计算出来,PSM就迎刃而解。

优惠次数
总购买次数
优惠总金额
应收总金额

前三个数据,我们可以提供统计型函数计算得出, 而 应收总金额= 优惠金额 + 成交金额 这一点我们明确了之后,就可以很好的上手代码了。

在这里插入图片描述

业务代码

算上这次,博主已经是第三次开发挖掘型标签了。所以就不单独把每一步具体实现的业务拿出来慢慢叙述了。更多的细节已经每步实现的效果已经用注释的方式贴在代码中了,有兴趣尝试的朋友,或者想要借鉴结果的朋友可以一睹代码究竟。

import com.czxy.base.BaseModel
import org.apache.spark.ml.clustering.{KMeans, KMeansModel}
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.sql._
import org.apache.spark.sql.expressions.UserDefinedFunction

import scala.collection.immutable

/\*
 \* @Author: Alice菌
 \* @Date: 2020/6/26 11:17
 \* @Description: 

 基于PSM模型,对用户的价格敏感度进行挖掘
 \*/
object PSMModel extends BaseModel {
  override def setAppName: String = "PSMModel"

  override def setFourTagId: String = "181"

  override def getNewTag(spark: SparkSession, fiveTagDF: DataFrame, hbaseDF: DataFrame): DataFrame = {

    // 五级标签的数据
      fiveTagDF.show()
    //+---+----+
    //| id|rule|
    //+---+----+
    //|182| 1|
    //|183| 2|
    //|184| 3|
    //|185| 4|
    //|186| 5|
    //+---+----+


    // HBase的数据
       hbaseDF.show()
    //+---------+--------------------+-----------+---------------+
    //| memberId| orderSn|orderAmount|couponCodeValue|
    //+---------+--------------------+-----------+---------------+
    //| 13823431|gome\_792756751164275| 2479.45| 0.00|
    //| 4035167|jd\_14090106121770839| 2449.00| 0.00|
    //| 4035291|jd\_14090112394810659| 1099.42| 0.00|
    //| 4035041|amazon\_7877495617...| 1999.00| 0.00|


    // tdonr 优惠订单占比(优惠订单数 / 订单总数)
    // adar 平均优惠金额占比(平均优惠金额 / 平均每单应收金额)
    // tdar 优惠金额占比(优惠总金额 / 订单总金额)
    //psm = 优惠订单占比 + 平均优惠金额占比 + 优惠总金额占比
    //只需要求取下面的字段,即可获取到最终的结果
    //优惠次数 
    //总购买次数
    //优惠总金额
    //应收总金额 = 优惠金额+成交金额
    
    // 引入隐式转换
    import spark.implicits._
    //引入java 和scala相互转换
    import scala.collection.JavaConverters._
    //引入sparkSQL的内置函数
    import org.apache.spark.sql.functions._

    // 优惠次数
    var preferentialCount:String = "preferential"
    // 订单总数
    var orderCount:String = "orderCount"
    // 总优惠金额
    var couponCodeValue:String = "couponCodeValue"
    // 应收总金额
    var totalValue:String = "totalValue"

    // 优惠次数
    var getPreferentialCount:Column= count(
      when(col("couponCodeValue") !== 0.00,1)
    ) as preferentialCount
     
    // 总购买次数
    val getOrderCount: Column = count("orderSn") as orderCount

    // 优惠总金额
    var getCouponCodeValue:Column= sum("couponCodeValue") as couponCodeValue

    // 应收总金额
    var getTotalValue: Column = (sum("orderAmount") + sum("couponCodeValue") ) as totalValue

    // 特征单词
    val featureStr: String = "feature"  // 向量
    val predictStr: String = "predict"  // 分类

    // 进行查询
    val getPSMDF01: DataFrame = hbaseDF.groupBy("memberId")
      .agg(getPreferentialCount, getOrderCount, getCouponCodeValue,getTotalValue)

    //展示结果
    getPSMDF01.show(5)

    //+---------+------------+-----------+---------------+------------------+
    //| memberId|preferential|orderAmount|couponCodeValue| totalValue|
    //+---------+------------+-----------+---------------+------------------+
    //| 4033473| 3| 142| 500.0|252430.91999999998|
    //| 13822725| 4| 116| 800.0| 180098.34|
    //| 13823681| 1| 108| 200.0|169946.09999999998|
    //|138230919| 3| 125| 600.0|240661.56999999998|
    //| 13823083| 3| 132| 600.0| 234124.17|
    //+---------+------------+-----------+---------------+------------------+

    // 先设置上我们常用的单词
    // 优惠订单占比
    var preferentiaOrderlPro:String = "preferentiaOrderlPro"
    // 平均优惠金额占比
    var avgPreferentialPro:String = "avgPreferentialPro"
    // 优惠金额占比
    val preferentialMoneyPro: String = "preferentialMoneyPro"

    /\* 获取到想要的字段结果 \*/
       // 优惠订单占比(优惠订单数 / 订单总数)
    val getPSMDF02: DataFrame = getPSMDF01.select(col("memberId"),col("preferential") / col("orderCount") as preferentiaOrderlPro,
      // 平均优惠金额占比(平均优惠金额 / 平均每单应收金额)
      (col("couponCodeValue") / col("preferential")) / (col("totalValue") / col("orderCount")) as avgPreferentialPro,
      // 优惠金额占比(优惠总金额 / 订单总金额)
      col("couponCodeValue") / col("totalValue") as preferentialMoneyPro)

    getPSMDF02.show()
    //+---------+--------------------+-------------------+--------------------+
    //| memberId|preferentiaOrderlPro| avgPreferentialPro|preferentialMoneyPro|
    //+---------+--------------------+-------------------+--------------------+
    //| 4033473| 0.02112676056338028|0.09375502282631092|0.001980739918865724|
    //| 13822725|0.034482758620689655| 0.1288185110423561| 0.00444201762215021|
    //| 13823681|0.009259259259259259|0.12709912142732316|0.001176843716919...|
    //|138230919| 0.024|0.10388031624658645|0.002493127589918075|
    //| 13823083|0.022727272727272728|0.11276067737901643|0.002562742667704919|
    //| 13823431| 0.01639344262295082|0.13461458465166434|0.002206796469699...|
    //| 4034923|0.009259259259259259|0.12882071966768546|0.001192784441367458|
    //| 4033575| 0.032|0.07938713328518321|0.002540388265125...|
    //| 13822841| 0.0| null| 0.0|


    val getPSMDF03: DataFrame = getPSMDF02.select(col("memberId"),col("preferentiaOrderlPro"),col("avgPreferentialPro"),col("preferentialMoneyPro"),(col("preferentiaOrderlPro")+col("avgPreferentialPro")+col("preferentialMoneyPro")) as "PSM" ).filter('PSM isNotNull)

    getPSMDF03.show()
    //+---------+--------------------+-------------------+--------------------+-------------------+
    //| memberId|preferentiaOrderlPro| avgPreferentialPro|preferentialMoneyPro| PSM|
    //+---------+--------------------+-------------------+--------------------+-------------------+
    //| 4033473| 0.02112676056338028|0.09375502282631092|0.001980739918865724|0.11686252330855693|
    //| 13822725|0.034482758620689655| 0.1288185110423561| 0.00444201762215021|0.16774328728519597|
    //| 13823681|0.009259259259259259|0.12709912142732316|0.001176843716919...|0.13753522440350205|
    //|138230919| 0.024|0.10388031624658645|0.002493127589918075| 0.1303734438365045|
    //| 13823083|0.022727272727272728|0.11276067737901643|0.002562742667704919| 0.1380506927739941|


    // 为了方便K-Means计算,我们将数据转换成向量
    val PSMFeature: DataFrame = new VectorAssembler()
      .setInputCols(Array("PSM"))
      .setOutputCol(featureStr)
      .transform(getPSMDF03)


    PSMFeature.show()
    //+---------+--------------------+--------------------+--------------------+-------------------+--------------------+
    //| memberId|preferentiaOrderlPro| avgPreferentialPro|preferentialMoneyPro| PSM| feature|
    //+---------+--------------------+--------------------+--------------------+-------------------+--------------------+
    //| 4033473| 0.02112676056338028| 0.09375502282631092|0.001980739918865724|0.11686252330855693|[0.11686252330855...|
    //| 13822725|0.034482758620689655| 0.1288185110423561| 0.00444201762215021|0.16774328728519597|[0.16774328728519...|
    //| 13823681|0.009259259259259259| 0.12709912142732316|0.001176843716919...|0.13753522440350205|[0.13753522440350...|
    //|138230919| 0.024| 0.10388031624658645|0.002493127589918075| 0.1303734438365045|[0.1303734438365045]|
    //| 13823083|0.022727272727272728| 0.11276067737901643|0.002562742667704919| 0.1380506927739941|[0.1380506927739941]|
    //| 13823431| 0.01639344262295082| 0.13461458465166434|0.002206796469699...|0.15321482374431458|[0.15321482374431...|
    //| 4034923|0.009259259259259259| 0.12882071966768546|0.001192784441367458|0.13927276336831218|[0.13927276336831...|
    //| 4033575| 0.032| 0.07938713328518321|0.002540388265125...|0.11392752155030907|[0.11392752155030...|
    //| 13823153|0.045112781954887216| 0.10559805877421218|0.004763822200340399|0.15547466292943982|[0.15547466292943...|


    // 利用KMeans算法,进行数据的分类
    val KMeansModel: KMeansModel = new KMeans()
      .setK(5) // 设置4类
      .setMaxIter(5) // 迭代计算5次
      .setFeaturesCol(featureStr) // 设置特征数据
      .setPredictionCol(predictStr) // 计算完毕后的标签结果
      .fit(PSMFeature)


    // 将其转换成DF
    val KMeansModelDF: DataFrame = KMeansModel.transform(PSMFeature)

    KMeansModelDF.show()
    //+---------+--------------------+--------------------+--------------------+-------------------+--------------------+-------+
    //| memberId|preferentiaOrderlPro| avgPreferentialPro|preferentialMoneyPro| PSM| feature|predict|
    //+---------+--------------------+--------------------+--------------------+-------------------+--------------------+-------+
    //| 4033473| 0.02112676056338028| 0.09375502282631092|0.001980739918865724|0.11686252330855693|[0.11686252330855...| 4|
    //| 13822725|0.034482758620689655| 0.1288185110423561| 0.00444201762215021|0.16774328728519597|[0.16774328728519...| 4|
    //| 13823681|0.009259259259259259| 0.12709912142732316|0.001176843716919...|0.13753522440350205|[0.13753522440350...| 4|
    //|138230919| 0.024| 0.10388031624658645|0.002493127589918075| 0.1303734438365045|[0.1303734438365045]| 4|
    //| 13823083|0.022727272727272728| 0.11276067737901643|0.002562742667704919| 0.1380506927739941|[0.1380506927739941]| 4|
    //| 13823431| 0.01639344262295082| 0.13461458465166434|0.002206796469699...|0.15321482374431458|[0.15321482374431...| 4|
    //| 4034923|0.009259259259259259| 0.12882071966768546|0.001192784441367458|0.13927276336831218|[0.13927276336831...| 4|
    //| 4033575| 0.032| 0.07938713328518321|0.002540388265125...|0.11392752155030907|[0.11392752155030...| 4|

    // 计算用户的价值
    val clusterCentersSum: immutable.IndexedSeq[(Int, Double)] = for(i <- KMeansModel.clusterCenters.indices) yield (i,KMeansModel.clusterCenters(i).toArray.sum)
    val clusterCentersSumSort: immutable.IndexedSeq[(Int, Double)] = clusterCentersSum.sortBy(_._2).reverse

    clusterCentersSumSort.foreach(println)


![img](https://img-blog.csdnimg.cn/img_convert/82bc098009855e77fd5364880f8afc7c.png)
![img](https://img-blog.csdnimg.cn/img_convert/a7a04805bf08c7392cd40ff396dfcc28.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

.foreach(println)


[外链图片转存中...(img-gOjbEtCF-1715722434404)]
[外链图片转存中...(img-As7Mn4h9-1715722434405)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值