作者/朱季謙
故事得從這一張圖開始說起——
可憐的打工人準備下班時,突然收到領導發來的一份電商消費者樣本數據,數據內容是這樣的——
消費者姓名|年齡|性別|薪資|消費偏好|消費領域|常用購物平臺|常用支付方式|單次購買商品數量|優惠券獲取情況|購物動機
Mario Johnston,53,男,12510,性價比,母嬰用品,網易考拉,信用卡,2,折扣優惠,興趣愛好 Daniel Cooper,28,男,11891,社交影響,圖書音像,京東,信用卡,1,折扣優惠,興趣愛好 Amber Powell,28,女,3365,環保可持續,食品飲料,蘇寧易購,貨到付款,1,折扣優惠,日常使用 Olivia Fletcher,32,女,3055,環保可持續,食品飲料,天貓,銀聯支付,7,滿減優惠,日常使用 William Wood,32,男,13492,創新設計,電子產品,網易考拉,貨到付款,9,有優惠券,商品推薦 Sarah Bell,36,男,17791,創新設計,家居用品,亞馬遜,微信支付,1,免費贈品,商品推薦 Cynthia Grant MD,65,男,17847,品牌追求,服裝,唯品會,支付寶,3,有優惠券,跟風購買 ......
這份數據樣本總共五千多條,打工人害怕弄丟了,他決定先上傳到百度網盤,放在這個網盤地址里——
鏈接: 百度網盤 請輸入提取碼 提取碼: wjgw
存好數據后,打工人去跟領導討論一下需要分析哪些畫像,領導給了一下幾個思路——
年齡和性別畫像:根據用戶的年齡和性別信息,了解不同年齡段和性別分布情況。 購物平臺和支付方式畫像:了解用戶首選的電商平臺和支付方式,有助于針對不同渠道進行個性化的營銷活動。 優惠偏好畫像:通過用戶在折扣優惠、免費贈品等方面的選擇,可以了解其在購物時最看重哪些優惠方式。 商品類別偏好畫像:根據用戶對汽車配件、珠寶首飾、圖書音像等不同商品類別的選擇,可以推測用戶的興趣愛好和消費傾向。 購物目的畫像:通過用戶對商品的描述,如性價比、時尚潮流、環保可持續等,推斷其購物的目的和價值觀。
接下來,就是基于這些數據和分析目標,開始基于Spark實現電商用戶畫像案例講解。
在線上生產環境里,樣本數據一般會放到HDFS或者HBase等地方,這些數據可能還會進一步清洗后同步到Hive里,方便直接Hive SQL或者Spark-SQL方式讀取到做計算。本次代碼案例里,暫時不需要涉及那么復雜的存儲,只需了解真實生產線上數據是放HDFS、HBase等倉庫存儲即可。
一、本地樣本文件的存放和讀取清洗
把樣本文件consumers.csv放到項目里路徑為src/main/resources/consumers.csv,通過Spark讀取到內存當中,順便打印看下讀取到的數據情況——
def main(args: Array[String]): Unit = {val conf = new SparkConf().setMaster("local").setAppName("consumer")val ss = SparkSession.builder().config(conf).getOrCreate()val filePath: String = "src/main/resources/consumers.csv"val fileRDD = ss.sparkContext.textFile(filePath) }
打印的結果如下所示——
Gary Mcpherson,37,女,11936,個性定制,食品飲料,京東,支付寶,4,折扣優惠,興趣愛好 Molly Stone,31,女,14962,時尚潮流,汽車配件,拼多多,微信支付,3,無優惠券,商品推薦 Amy Wright,65,女,12855,時尚潮流,運動健身,唯品會,信用卡,3,滿減優惠,日常使用 Anna Christensen,35,男,8201,創新設計,圖書音像,亞馬遜,貨到付款,3,滿減優惠,跟風購買 Samuel Santana,23,男,5061,創新設計,汽車配件,京東,支付寶,10,折扣優惠,跟風購買 Robert Williams,25,女,3038,環保可持續,食品飲料,網易考拉,支付寶,6,有優惠券,日常使用 Christopher Brown,40,女,9087,社交影響,服裝,天貓,貨到付款,5,折扣優惠,跟風購買 Dale Vazquez,40,女,14648,社交影響,食品飲料,亞馬遜,信用卡,2,滿減優惠,興趣愛好 ......
可見,Spark讀取到內存里的數據,還是原始數據格式,我們需要對其進行切割,最簡單的方式,就是通過Spark的map算子,將每一行的字符串,切割后存入到數組結構里,轉換的情況如下圖所示——
只需要一行代碼就可以實現將原始樣本每一行字符數據轉成數組結構——
val consumerRDD = fileRDD.map(_.split(","))
轉換生成的consumerRDD里每一行數據,可以理解成是一個數組,數組索引0~10對應的字段類型如下——
原始樣本處理成上圖情況,后續的操作,其實就純粹可以通過類似SQL形式來計算需要的結果了。
二、畫像數據分析的實現
2.1、商品類別偏好畫像
根據用戶對汽車配件、珠寶首飾、圖書音像等不同商品類別的選擇,可以推測用戶的興趣愛好和消費傾向。
針對這個需求,可以通過以下代碼實現——
def main(args: Array[String]): Unit = {val conf = new SparkConf().setMaster("local").setAppName("consumer")val ss = SparkSession.builder().config(conf).getOrCreate()val filePath: String = "src/main/resources/consumers.csv"val fileRDD = ss.sparkContext.textFile(filePath)val consumerRDD = 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)。
consumerRDD.map(x => (x.apply(5), 1))中的x.apply(5)是對應【消費領域】字段,表示將consumerRDD中每行元素里的消費字段做一個映射,值設置為1,代表一個人關注的消費領域。
reduceByKey(_ + _)表示將具有相同鍵的鍵值對進行合并,將鍵相同的值相加,生成一個新的RDD,其中每個鍵關聯著其對應的累加值,例如服裝這個key,最后累加得到553值。
sortBy(.2, false)表示是按照累加的值大小降序排序。
結合以上函數,就可以實現將consumerRDD中的數據按照【消費領域】字段,聚合出每個領域的消費者數量。
2.2、優惠偏好畫像
通過用戶在折扣優惠、免費贈品、品牌忠誠等方面的選擇,可以了解其在購物時最看重哪些消費習慣。
def main(args: Array[String]): Unit = {val conf = new SparkConf().setMaster("local").setAppName("consumer")val ss = SparkSession.builder().config(conf).getOrCreate()val filePath: String = "src/main/resources/consumers.csv"val fileRDD = ss.sparkContext.textFile(filePath)val consumerRDD = 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、優惠券獲取情況和購物動機的關系
觀察優惠券獲取情況和購物動機之間的聯系,探索消費者是否更傾向于使用優惠券進行購物
def main(args: Array[String]): Unit = {val conf = new SparkConf().setMaster("local").setAppName("consumer")val ss = SparkSession.builder().config(conf).getOrCreate()val filePath: String = "src/main/resources/consumers.csv"val fileRDD = ss.sparkContext.textFile(filePath)val consumerRDD = fileRDD.map(_.split(","))//以下實現將RDD轉換成類似關系型數據庫表的形式val rowRDD = consumerRDD.map {x => Row(x.apply(0), x.apply(1).toInt, x.apply(2), x.apply(3).toInt, x.apply(4), x.apply(5), x.apply(6), x.apply(7), x.apply(8).toInt, x.apply(9), x.apply(10))}//Row里0~10索引數據映射的字段val schema = StructType(Seq(StructField("consumerName", StringType),StructField("age", IntegerType),StructField("gender", StringType),StructField("monthlyIncome", IntegerType),StructField("consumptionPreference", StringType),StructField("consumptionArea", StringType),StructField("shoppingPlatform", StringType),StructField("paymentMethod", StringType),StructField("quantityOfItemsPurchased", IntegerType),StructField("couponAcquisitionStatus", StringType),StructField("shoppingMotivation", StringType) ?))val df = ss.createDataFrame(rowRDD, schema).toDF()//按照【優惠券獲取情況】和【購物動機】分組統計val analysisResult = df.groupBy("couponAcquisitionStatus", "shoppingMotivation").agg(count("*").alias("MotivationCount")).orderBy(desc("MotivationCount")) ?analysisResult.show() }
打印結果如下,可見,當商品同時做【折扣優惠】和【商品推薦】時,消費者數量是最多的,其次就是購買消費有【免費贈品】及出于【興趣愛好】動機消費。針對這類情況,可以做進一步分析,進而調整營銷策略。
+-----------------------+------------------+---------------+ |couponAcquisitionStatus|shoppingMotivation|MotivationCount| +-----------------------+------------------+---------------+ | ? ? ? ? ? ? ? 折扣優惠| ? ? ? ? ?商品推薦| ? ? ? ? ? ?168| | ? ? ? ? ? ? ? 免費贈品| ? ? ? ? ?興趣愛好| ? ? ? ? ? ?167| | ? ? ? ? ? ? ? 免費贈品| ? ? ? ? ?禮物贈送| ? ? ? ? ? ?166| | ? ? ? ? ? ? ? 滿減優惠| ? ? ? ? ?日常使用| ? ? ? ? ? ?166| | ? ? ? ? ? ? ? 無優惠券| ? ? ? ? ?興趣愛好| ? ? ? ? ? ?165| | ? ? ? ? ? ? ? 免費贈品| ? ? ? ? ?商品推薦| ? ? ? ? ? ?162| | ? ? ? ? ? ? ? 免費贈品| ? ? ? ? ?跟風購買| ? ? ? ? ? ?160| | ? ? ? ? ? ? ? 免費贈品| ? ? ? ? ?日常使用| ? ? ? ? ? ?159| | ? ? ? ? ? ? ? 折扣優惠| ? ? ? ? ?跟風購買| ? ? ? ? ? ?158| | ? ? ? ? ? ? ? 有優惠券| ? ? ? ? ?禮物贈送| ? ? ? ? ? ?157| | ? ? ? ? ? ? ? 免費贈品| ? ? ? ? ?促銷打折| ? ? ? ? ? ?157| | ? ? ? ? ? ? ? 折扣優惠| ? ? ? ? ?品牌忠誠| ? ? ? ? ? ?157| | ? ? ? ? ? ? ? 無優惠券| ? ? ? ? ?日常使用| ? ? ? ? ? ?156| | ? ? ? ? ? ? ? 有優惠券| ? ? ? ? ?日常使用| ? ? ? ? ? ?156| | ? ? ? ? ? ? ? 滿減優惠| ? ? ? ? ?禮物贈送| ? ? ? ? ? ?155| | ? ? ? ? ? ? ? 有優惠券| ? ? ? ? ?品牌忠誠| ? ? ? ? ? ?154| | ? ? ? ? ? ? ? 免費贈品| ? ? ? ? ?品牌忠誠| ? ? ? ? ? ?154| | ? ? ? ? ? ? ? 滿減優惠| ? ? ? ? ?商品推薦| ? ? ? ? ? ?154| | ? ? ? ? ? ? ? 無優惠券| ? ? ? ? ?跟風購買| ? ? ? ? ? ?153| | ? ? ? ? ? ? ? 折扣優惠| ? ? ? ? ?禮物贈送| ? ? ? ? ? ?151| +-----------------------+------------------+---------------+
以上是一些簡單的實現,在真實環境里,并不會這么簡單,可能還會涉及一系列數據的清洗和join處理,進而通過一些模型及算法,計算出更多有價值的畫像數據。
樣本處理完后,原以為這個故事結束了,打工人可以下班了,沒想到——