可怜的打工人准备下班时,突然收到领导发来的一份电商消费者样本数据,数据内容是这样的——
消费者姓名|年龄|性别|薪资|消费偏好|消费领域|常用购物平台|常用支付方式|单次购买商品数量|优惠券获取情况|购物动机
存好数据后,打工人去跟领导讨论一下需要分析哪些画像,领导给了一下几个思路——
年龄和性别画像:根据用户的年龄和性别信息,了解不同年龄段和性别分布情况。购物平台和支付方式画像:了解用户首选的电商平台和支付方式,有助于针对不同渠道进行个性化的营销活动。优惠偏好画像:通过用户在折扣优惠、免费赠品等方面的选择,可以了解其在购物时最看重哪些优惠方式。商品类别偏好画像:根据用户对汽车配件、珠宝首饰、图书音像等不同商品类别的选择,可以推测用户的兴趣爱好和消费倾向。购物目的画像:通过用户对商品的描述,如性价比、时尚潮流、环保可持续等,推断其购物的目的和价值观。接下来,就是基于这些数据和分析目标,开始基于Spark实现电商用户画像案例讲解。
在线上生产环境里,样本数据一般会放到HDFS或者HBase等地方,这些数据可能还会进一步清洗后同步到Hive里,方便直接HiveSQL或者Spark-SQL方式读取到做计算。本次代码案例里,暂时不需要涉及那么复杂的存储,只需了解真实生产线上数据是放HDFS、HBase等仓库存储即可。
把样本文件consumers.csv放到项目里路径为src/main/resources/consumers.csv,通过Spark读取到内存当中,顺便打印看下读取到的数据情况——
defmain(args:Array[String]):Unit={valconf=newSparkConf().setMaster("local").setAppName("consumer")valss=SparkSession.builder().config(conf).getOrCreate()valfilePath:String="src/main/resources/consumers.csv"valfileRDD=ss.sparkContext.textFile(filePath)}打印的结果如下所示——
只需要一行代码就可以实现将原始样本每一行字符数据转成数组结构——
valconsumerRDD=fileRDD.map(_.split(","))转换生成的consumerRDD里每一行数据,可以理解成是一个数组,数组索引0~10对应的字段类型如下——
原始样本处理成上图情况,后续的操作,其实就纯粹可以通过类似SQL形式来计算需要的结果了。
根据用户对汽车配件、珠宝首饰、图书音像等不同商品类别的选择,可以推测用户的兴趣爱好和消费倾向。
针对这个需求,可以通过以下代码实现——
defmain(args:Array[String]):Unit={valconf=newSparkConf().setMaster("local").setAppName("consumer")valss=SparkSession.builder().config(conf).getOrCreate()valfilePath:String="src/main/resources/consumers.csv"valfileRDD=ss.sparkContext.textFile(filePath)valconsumerRDD=fileRDD.map(_.split(","))consumerRDD.map(x=>(x.apply(5),1)).reduceByKey(_+_).sortBy(_._2,false).foreach(println)}打印结果如下,可见这批样本里,受消费者消费倾向最多的前TOP3,分别是服装、家居用品、图书音像——
(服装,553)(家居用品,542)(图书音像,539)(珠宝首饰,535)(母婴用品,530)(美妆护肤,526)(汽车配件,523)(电子产品,506)(食品饮料,500)(运动健身,492)实现的核心是通过这行代码consumerRDD.map(x=>(x.apply(5),1)).reduceByKey(_+).sortBy(._2,false)。
reduceByKey(_+_)表示将具有相同键的键值对进行合并,将键相同的值相加,生成一个新的RDD,其中每个键关联着其对应的累加值,例如服装这个key,最后累加得到553值。
sortBy(.2,false)表示是按照累加的值大小降序排序。
结合以上函数,就可以实现将consumerRDD中的数据按照【消费领域】字段,聚合出每个领域的消费者数量。
通过用户在折扣优惠、免费赠品、品牌忠诚等方面的选择,可以了解其在购物时最看重哪些消费习惯。
defmain(args:Array[String]):Unit={valconf=newSparkConf().setMaster("local").setAppName("consumer")valss=SparkSession.builder().config(conf).getOrCreate()valfilePath:String="src/main/resources/consumers.csv"valfileRDD=ss.sparkContext.textFile(filePath)valconsumerRDD=fileRDD.map(_.split(","))consumerRDD.map(x=>(x.apply(10),1)).reduceByKey(_+_).sortBy(_._2,false).foreach(println)}打印结果如下,可以看到,在这批消费者样本里,基于日常使用、礼物赠送、商品推荐等消费方式受众最多,那么可以基于商品消费做进一步优化——
(日常使用,777)(礼物赠送,773)(商品推荐,762)(兴趣爱好,750)(品牌忠诚,750)(跟风购买,724)(促销打折,710)2.3、优惠券获取情况和购物动机的关系观察优惠券获取情况和购物动机之间的联系,探索消费者是否更倾向于使用优惠券进行购物
+-----------------------+------------------+---------------+|couponAcquisitionStatus|shoppingMotivation|MotivationCount|+-----------------------+------------------+---------------+|折扣优惠|商品推荐|168||免费赠品|兴趣爱好|167||免费赠品|礼物赠送|166||满减优惠|日常使用|166||无优惠券|兴趣爱好|165||免费赠品|商品推荐|162||免费赠品|跟风购买|160||免费赠品|日常使用|159||折扣优惠|跟风购买|158||有优惠券|礼物赠送|157||免费赠品|促销打折|157||折扣优惠|品牌忠诚|157||无优惠券|日常使用|156||有优惠券|日常使用|156||满减优惠|礼物赠送|155||有优惠券|品牌忠诚|154||免费赠品|品牌忠诚|154||满减优惠|商品推荐|154||无优惠券|跟风购买|153||折扣优惠|礼物赠送|151|+-----------------------+------------------+---------------+以上是一些简单的实现,在真实环境里,并不会这么简单,可能还会涉及一系列数据的清洗和join处理,进而通过一些模型及算法,计算出更多有价值的画像数据。
样本处理完后,原以为这个故事结束了,打工人可以下班了,没想到——