基于Spark对消费者行为数据进行数据分析开发案例
原創(chuàng)/朱季謙
本文適合入門(mén)Spark RDD的計(jì)算處理。
在日常工作當(dāng)中,經(jīng)常遇到基于Spark去讀取存儲(chǔ)在HDFS中的批量文件數(shù)據(jù)進(jìn)行統(tǒng)計(jì)分析的案例,這些文件一般以csv或者txt文件格式存在。例如,存在這樣一份消費(fèi)者行為數(shù)據(jù),字段包括消費(fèi)者姓名,年齡,性別,月薪,消費(fèi)偏好,消費(fèi)領(lǐng)域,購(gòu)物平臺(tái),支付方式,單次購(gòu)買(mǎi)商品數(shù)量,優(yōu)惠券獲取情況,購(gòu)物動(dòng)機(jī)。
基于這份消費(fèi)者行為數(shù)據(jù),往往會(huì)有以下一些分析目標(biāo):
- 用戶(hù)統(tǒng)計(jì)學(xué)分析:針對(duì)性別、年齡等屬性進(jìn)行統(tǒng)計(jì)分析,了解消費(fèi)者群體的組成和特征。
- 收入與購(gòu)買(mǎi)行為的關(guān)系分析:通過(guò)比較月薪和單次購(gòu)買(mǎi)商品數(shù)量之間的關(guān)系,探索收入水平對(duì)消費(fèi)行為的影響。
- 消費(fèi)偏好和消費(fèi)領(lǐng)域的分析:查看不同消費(fèi)者的消費(fèi)偏好(例如性?xún)r(jià)比、功能性、時(shí)尚潮流等)和消費(fèi)領(lǐng)域(例如家居用品、汽車(chē)配件、美妝護(hù)膚等),以了解他們的興趣和偏好。
- 購(gòu)物平臺(tái)和支付方式的分析:研究購(gòu)物平臺(tái)(例如天貓、淘寶、拼多多等)和支付方式(例如微信支付、支付寶等)的選擇情況,了解消費(fèi)者在電商平臺(tái)上的偏好。
- 優(yōu)惠券獲取情況和購(gòu)物動(dòng)機(jī)的關(guān)系:觀察優(yōu)惠券獲取情況和購(gòu)物動(dòng)機(jī)之間的聯(lián)系,探索消費(fèi)者是否更傾向于使用優(yōu)惠券進(jìn)行購(gòu)物。
針對(duì)這些需求,就可以使用Spark來(lái)讀取文件后,進(jìn)一步分析處理統(tǒng)計(jì)。
接下來(lái),就是針對(duì)以上分析目標(biāo),設(shè)計(jì)一番Spark代碼計(jì)算邏輯,由此可入門(mén)學(xué)習(xí)下Spark RDD常用用法。
獲取一份具備以下字段的csv隨機(jī)假樣本,總共5246條數(shù)據(jù),包括“消費(fèi)者姓名,年齡,性別,月薪,消費(fèi)偏好,消費(fèi)領(lǐng)域,購(gòu)物平臺(tái),支付方式,單次購(gòu)買(mǎi)商品數(shù)量,優(yōu)惠券獲取情況,購(gòu)物動(dòng)機(jī)”。
Amy Harris,39,男,18561,性?xún)r(jià)比,家居用品,天貓,微信支付,10,折扣優(yōu)惠,品牌忠誠(chéng)
Lori Willis,33,女,14071,功能性,家居用品,蘇寧易購(gòu),貨到付款,1,折扣優(yōu)惠,日常使用
Jim Williams,61,男,14145,時(shí)尚潮流,汽車(chē)配件,淘寶,微信支付,3,免費(fèi)贈(zèng)品,禮物贈(zèng)送
Anthony Perez,19,女,11587,時(shí)尚潮流,珠寶首飾,拼多多,支付寶,5,免費(fèi)贈(zèng)品,商品推薦
......
將樣本存放到項(xiàng)目目錄為src/main/resources/consumerdata.csv,然后新建一個(gè)Scala的object類(lèi),創(chuàng)建一個(gè)main方法, 模擬從HDSF讀取數(shù)據(jù),然后通過(guò).map(_.split(","))將csv文件每一行切割成一個(gè)數(shù)組形式的RDD
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/consumerdata.csv"
val consumerRDD = ss.sparkContext.textFile(filePath).map(_.split(","))
可以寫(xiě)一段代碼打印看一下consumerRDD結(jié)構(gòu)——
consumerRDD.foreach(x => {
x.foreach(y => print(y +" "))
println()
})
打印結(jié)果如下——
這個(gè)RDD相當(dāng)于把每一行當(dāng)作里一個(gè)Array[]數(shù)組,第一行的Array0是消費(fèi)者姓名,即Amy Harris,Array1是年齡,即39,以此類(lèi)推。
| 消費(fèi)者姓名 | 年齡 | 性別 | 月薪 | 消費(fèi)偏好 | 消費(fèi)領(lǐng)域 | 購(gòu)物平臺(tái) | 支付方式 | 單次購(gòu)買(mǎi)商品數(shù)量 | 優(yōu)惠券獲取情況 | 購(gòu)物動(dòng)機(jī) |
|---|---|---|---|---|---|---|---|---|---|---|
| Amy Harris | 39 | 男 | 18561 | 性?xún)r(jià)比 | 家居用品 | 天貓 | 微信支付 | 10 | 折扣優(yōu)惠 | 品牌忠誠(chéng) |
| Lori Willis | 33 | 女 | 14071 | 功能性 | 家居用品 | 蘇寧易購(gòu) | 貨到付款 | 1 | 折扣優(yōu)惠 | 日常使用 |
| 。。。 |
獲取到該RDD后,就可以進(jìn)行下一步的統(tǒng)計(jì)分析了。
一、統(tǒng)計(jì)消費(fèi)者支付方式偏好分布
這行代碼意思,x.apply(7)表示取每一行的第八個(gè)字段,相當(dāng)數(shù)組Array[7],第八個(gè)字段是【支付方式】。
- map(x=>(x.apply(7),1))表示是對(duì)RDD里每一行出現(xiàn)過(guò)的支付方式字段設(shè)置為1個(gè),例如,第一行把原本數(shù)組格式Array的RDD做了轉(zhuǎn)換,生成(微信支付,1)格式的新RDD,表示用微信支付的用戶(hù)出現(xiàn)了1次。
- reduceByKey(_ + _)表示按RDD的key進(jìn)行聚合統(tǒng)計(jì),表示統(tǒng)計(jì)微信支付出現(xiàn)的次數(shù),支付寶出現(xiàn)的次數(shù)等。最后,通過(guò)
- sortBy(_._2,false)表示按照key-value當(dāng)中的value進(jìn)行倒序排序,false表示倒敘,true表示升序。
因此就可以按照以上格式,對(duì)文本數(shù)據(jù)里的每一個(gè)字段做相應(yīng)分析,后文其他計(jì)算邏輯也是類(lèi)似。
consumerRDD.map(x => (x.apply(7),1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印結(jié)果如下:
二、統(tǒng)計(jì)購(gòu)物平臺(tái)偏好分布
x.apply(5)表示取每一行的第六個(gè)字段,相當(dāng)數(shù)組Array[5],第六個(gè)字段是【購(gòu)物平臺(tái)】。
同前文的【統(tǒng)計(jì)消費(fèi)者支付方式偏好分布】一樣,通過(guò)map(x=>(x.apply(5),1))生成(購(gòu)物平臺(tái),1)格式的RDD,然后再通過(guò)reduceByKey算子針對(duì)相同的key做統(tǒng)計(jì),最后倒序排序。
consumerRDD.map(x => (x.apply(5), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印結(jié)果——
三、統(tǒng)計(jì)購(gòu)物偏好方式分布
x.apply(4)表示取每一行的第五個(gè)字段,相當(dāng)數(shù)組Array[4],第五個(gè)字段是【消費(fèi)領(lǐng)域】。
consumerRDD.map(x => (x.apply(4), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印結(jié)果:
四、統(tǒng)計(jì)購(gòu)物動(dòng)機(jī)分布
x.apply(10)表示取每一行的第十個(gè)字段,相當(dāng)數(shù)組Array[10],第10個(gè)字段是【購(gòu)物動(dòng)機(jī)】。
consumerRDD.map(x => (x.apply(10), 1)).reduceByKey(_ + _).sortBy(_._2, false).foreach(println)
打印結(jié)果——
五、消費(fèi)者年齡分布
該需求通過(guò)將RDD映射成DataFrame數(shù)據(jù)集,方便用SQL語(yǔ)法處理,按照年齡區(qū)間分區(qū),分別為"0-20","21-30","31-40"
......這個(gè)分區(qū)字符串名,就相當(dāng)key,value表示落在該分區(qū)的用戶(hù)數(shù)量。這時(shí),就可以分組做聚合統(tǒng)計(jì)了,統(tǒng)計(jì)出各個(gè)年齡段的消費(fèi)者數(shù)量。
//取出consumerRDD每一行數(shù)組需要的字段
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))
}
//設(shè)置字段映射
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()
//按年齡分布計(jì)算
val agedf = df.withColumn("age_range",
when(col("age").between(0, 20), "0-20")
.when(col("age").between(21, 30), "21-30")
.when(col("age").between(31, 40), "31-40")
.when(col("age").between(41, 50), "41-50")
.when(col("age").between(51, 60), "51-60")
.when(col("age").between(61, 70), "61-70")
.when(col("age").between(81, 90), "81-90")
.when(col("age").between(91, 100), "91-100")
.otherwise("Unknow")
)
//分組統(tǒng)計(jì)
val result = agedf.groupBy("age_range").agg(count("consumerName").alias("Count")).sort(desc("Count"))
result.show()
打印結(jié)果:
六、統(tǒng)計(jì)年齡分布
類(lèi)似年齡分布的操作。
val sexResult = agedf.groupBy("gender").agg(count("consumerName").alias("Count")).sort(desc("Count"))
sexResult.show()
打印結(jié)果:
除了以上的統(tǒng)計(jì)分析案例之外,還有優(yōu)惠券獲取情況和購(gòu)物動(dòng)機(jī)的關(guān)系、消費(fèi)領(lǐng)域方式等統(tǒng)計(jì),可以進(jìn)一步拓展分析。
本文基于分析消費(fèi)者行為數(shù)據(jù),可以入門(mén)學(xué)習(xí)到,Spark如何讀取樣本文件,通過(guò)map(_.split(","))處理樣本成一個(gè)數(shù)組格式的RDD,基于該RDD,可以進(jìn)一步通過(guò)map、reduceByKey、groupBy等算子做處理與統(tǒng)計(jì),最后獲取該樣本的信息價(jià)值。
總結(jié)
以上是生活随笔為你收集整理的基于Spark对消费者行为数据进行数据分析开发案例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 文心一言 VS 讯飞星火 VS chat
- 下一篇: Altium Designer中'=Sh