1 环境搭建
本次作业使用的环境和软件如下:
(1)Linux操作系统:Ubuntu 16.04
(2)Python:3.5.2
(3)Hadoop:3.1.3
(4)Spark:2.4.0
具体的安装步骤参考林子雨的教程基于零售交易数据的Spark数据处理与分析
2 数据处理
数据处理及分析参考链接在这里
数据清洗的操作主要有:
- 数据缺失值处理:删除CustomerID为空值的135037条数据
- 数据去重:删除数据集中重复的、无价值的数据5268条
- 时间序列的处理:将InvoiceDate转换为时间序列InvoiceTime
- 异常值处理:删除Quantity数量和UnitPrice单价中小于等于0的值
处理好的数据还余392692条,保存为sales_success.csv文件。
然后将数据上传到hdfs:(假设你的数据保存在/home/hadoop/下载/中)
./bin/hdfs dfs -put /home/hadoop/下载/sales_success.csv
3 用户画像
本节需要安装jupyter,参考教程也是林子雨老师的使用Jupyter Notebook调试PySpark程序
用户画像参考链接点击
3.1 读取数据
from pyspark import SparkContext
from pyspark import SQLContext
from pyspark.sql import SparkSession
from pyspark.sql.functions import split, concat, lit, substring
from pyspark.sql.functions import col, max as max_
from pyspark.sql.types import TimestampType
from pyspark.sql.functions import to_timestamp
from pyspark.sql.functions import unix_timestamp
from pyspark.sql.functions import rank,sum,to_date, datediff, max, count,to_utc_timestamp, unix_timestamp,expr,mean
import pyspark.sql.functions as F
spark = SparkSession \
.builder \
.appName("pySpark RFM") \
.config("spark.some.config.option", "some-value") \
.getOrCreate()
df = spark.read.format('com.databricks.spark.csv').\
options(header='true', \
inferschema='true').\
load("sales_success.csv",header=True);
查看数据前5行:
df.show(5)
3.2 RFM用户画像
3.2.1 时间序列
df = df.withColumn("InvoiceTime", to_timestamp(col("InvoiceTime"), 'yyyy-MM-dd HH:mm:ss'))
df.show(5)
3.2.2 计算R、F、M值
-
最近一次的消费时间(Recency):
一般考虑最近一次消费到某固定时间点的间隔时长,这个维度需要结合业务的特点加以考虑。基于历史数据的分析,大概率上满足,消费频率越高的用户粘性更大,也更可能成为忠实用户。此时,如何预防用户出现厌倦流失等状况,如何稳定住这批客户是需要关注的问题。而对于那些早期有过消费但很快流失的客户,则需要从更多的数据中尝试挖掘出共性。 -
一段时间内的消费频次(Frequency):
一段时间内,对于购买消费频次更高的用户,其忠诚度更高,在很大概率上也更容易产生下一次消费行为。基于历史交易数据分析用户的消费频次数据,一般情况下也是满足周期性或者比较稳定的规律;如果出现了比较异常的数据,可能更需要在业务角度提供推荐、优惠、回访等方式进行关注。 -
一段时间内的累计消费额(Monetary):
一般是累积某时间段内用户消费的总金额,比如一年内,一个月内的消费总额;一般的,消费越多的用户有更大概率去购买更用心和更高级的产品;这类用户可能在消费观上更愿意接受新产品,此时通过建立合适的 VIP 机制或者类似的用户回馈机制,可以提高用户的体验。 -
计算时间间距
rfm = df\
.groupBy("CustomerID")\
.agg(max_("InvoiceTime").alias('LastDate'))
max_date = df.agg({
"InvoiceTime": "max"}).collect()[0][0]
rfm = rfm.withColumn("RecentDate", lit(max_date))
- R值
rfm = rfm.withColumn("recency", datediff(col("RecentDate"), col("LastDate")))
rfm = rfm.select("CustomerID", "recency")
- M值
monetary = df.groupBy("CustomerID").agg(sum("SumPrice").alias('monetary'))
- F值
freq = df.groupBy("CustomerID").agg(count("StockCode").alias('frequency'))
- 合并起来
rfm = rfm.join(monetary, [