2.6 案例:PySpark实现用户价值分类

2.6 案例:PySpark实现用户价值分类

【实验目的】

1.分析RFM各自的含义

2.创建RFM(R值)得分表

3.创建RFM(F值)得分表

4.创建用户价值分类表

【实验原理】

RFM解读:

RFM分析法对用户进行量化分类,便于对客户进行差异化营销。RFM模型含义如下:

R,Recency,近度指标,表示客户最近一次交易时间到现在的间隔

F,Frequency,频度指标,表示客户在最近一段时间内交易的次数

M,Monetary,额度指标,表示客户在最近一段时间内交易的金额

20231205145101_1665.png

本次分析中,由于缺少消费金额数据,仅从R和F两个维度进行客户分类分析,分类原则如下表:

20231205145107_6299.png

R值定义:

对于R值,作如下定义:

定义消费时间间隔为消费日期距统计周期内最近日期即2018-04-14的时间差;

消费时间间隔大于12天,R=1

消费时间间隔大于等于9天,小于12天,R=2

消费时间间隔大于等于6天,小于9天,R=3

消费时间间隔大于等于3天,小于6天,R=4

消费时间间隔小于3天,R=5

F值定义:

定义消费频次为统计周期内用户的消费天数,同一天多次消费记为1次

消费频次大于等于11,F=5

消费频次大于等于8,小于11,F=4

消费频次大于等于5,小于8,F=3

消费频次大于等于2,小于5,F=2

消费频次小于2,F=1

用户价值分类:

基于创建的用户分类表,根据用户的R,F得分进行分类:

SELECT r.用户ID,

(CASE

WHEN r.用户R值评价='高' AND f.用户F值评价='高' THEN '重要价值客户'

WHEN r.用户R值评价='高' AND f.用户F值评价='低' THEN '重要发展客户'

WHEN r.用户R值评价='低' AND f.用户F值评价='高' THEN '重要保持客户'

WHEN r.用户R值评价='低' AND f.用户F值评价='低' THEN '重要挽留客户'

ELSE NULL END) AS 用户价值分类

FROM 用户r值等级分类表 r INNER JOIN 用户f值等级分类表 f ON r.'用户ID'=f.'用户ID'

【实验环境】

AnolisOS 8.8

hadoop-3.0.0

spark-2.4.3

pyspark

python2.7

【实验内容】

创建用户价值分类表

【实验步骤】

【步骤一:环境准备】

切换用户vmuser(密码:vm123456)

1.打开Linux终端模拟器,创建目录,如果目录已经存在,则无需重复创建

mkdir -p /data/uservalue

2.进入/data/uservalue,使用ls命令查看文件

cd /data/uservalue

ls

说明:如果jdata_action.zip文件已存在,则无需执行下面命令,重复下载数据

wget http://uservalue/jdata_action.zip

sudo chown -R vmuser:vmuser /data/uservalue/jdata_action.zip

3.解压文件

unzip jdata_action.zip

4.切换到/apps/hadoop/sbin目录下,启动hadoop相关进程(如果Hadoop进程已经启动,则无需执行下列启动命令)

cd /apps/hadoop/sbin

./start-all.sh

查看hadoop进程是否已经启动

jps

5.在HDFS上创建目录,将jdata_action.csv上传到HDFS中的uservalue目录下(如果HDFS中已经存在jdata_action.csv ,则无需执行下面命令)

hadoop fs -mkdir -p /uservalue

hadoop fs -put /data/uservalue/jdata_action.csv /uservalue

6.开启PySpark

PYSPARK_PYTHON=python3.6 pyspark

【步骤二:认识数据】

7.创建RDD

使用textFile()方法读取HDFS上的jdata_action.csv文件,赋值给RDD1并统计文件内容有多少行

RDD1 = sc.textFile("/uservalue/jdata_action.csv")

RDD1.count()

8.使用map函数处理每一项数据,用lambda语句创建匿名函数传入line参数,在匿名函数中,line.split(“,”)表示按照逗号分隔获取每一个字段

RDD2=RDD1.map(lambda line:line.split(","))

9.创建DataFrame

导入row模块,通过RDD2创建DataFrame,定义DataFrame的每一个字段名与数据类型

字段说明:

user_id:用户唯一标识

sku_id:商品唯一标识

action_Time:行为时间

module_id:如果是下单,存储订单号;如果是浏览,存储sessionid

type:行为类型:1.浏览;2.下单;3.关注;4.评论;5.加购物车

from pyspark.sql import Row

uservalue_row= RDD2.map(lambda p:

Row(

user_id=p[0],

sku_id=p[1],

action_time=p[2],

module_id=p[3],

type=p[4]

)

)

10.创建了uservalue_row之后,使用sqlContext.createDataFrame()方法写入uservalue_row数据,创建DataFrame,然后使用printSchema()方法查看DataFrames的Schema

11.接下来,我们可以使用.show()方法来查看前5行数据

uservalue_df.show(5)

12.我们也可以使用.alias()方法来为DadaFrame创建别名,例如uservalue_df.alias("df"),后续我们就可以使用这个别名执行命令了

df=uservalue_df.alias("df")

df.show(5)

13.创建PySpark SQL

下面我们使用registerTempTable方法将df转换为uservalue_tb表

sqlContext.registerDataFrameAsTable(df, "uservalue_tb")

14.接下来,我们可以使用sqlContext.sql()输入sql语句,使用select关键字查询文件内容行数,并使用from关键字指定要查询的表,最后使用show()方法显示查询结果

sqlContext.sql("select count(*) counts from uservalue_tb").show()

15.编写SQL,查询用户ID、消费时间间隔(从2018-04-14到用户行为时间(下单))。

SQL解读:

GROUP BY user_id:根据用户id分组

type=2:表示下单用户

DATEDIFF('2018-04-14',MAX(action_time)):返回日期从2018-04-14到用户行为时间间隔天数最大差值

sqlContext.sql("""

SELECT user_id,DATEDIFF('2018-04-14',MAX(action_time))

AS con_timeinter

FROM uservalue_tb

WHERE type='2'

GROUP BY user_id

""").show(5)

【步骤三:创建用户R值等级分类表】

(1)创建R值得分表R_SCORE_TB(消费时间间隔得分表)

1.创建RFM得分表(R值),对于R值,作如下定义:

定义消费时间间隔为消费日期距统计周期内最近日期即2018-04-14的时间差;

消费时间间隔大于12天,R=1

消费时间间隔大于等于9天,小于12天,R=2

消费时间间隔大于等于6天,小于9天,R=3

消费时间间隔大于等于3天,小于6天,R=4

消费时间间隔小于3天,R=5

R_SCORE=sqlContext.sql("""

SELECT user_id,

(CASE

WHEN con_timeinter >= 12 THEN 1

WHEN con_timeinter >= 9 AND con_timeinter< 12 THEN 2

WHEN con_timeinter >= 6 AND con_timeinter< 9 THEN 3

WHEN con_timeinter >= 3 AND con_timeinter< 6 THEN 4

WHEN con_timeinter< 3 THEN 5

ELSE 0 END

)AS R_SCORE

FROM

(SELECT user_id,DATEDIFF('2018-04-14',MAX(action_time)) AS con_timeinter

FROM uservalue_tb

WHERE type='2'

GROUP BY user_id) rencency

ORDER BY R_SCORE DESC

""")

我们称R_SCORE为“消费时间间隔”

2. R_SCORE是一个DataFrame,将其转换为表R_SCORE_TB,称为“消费时间间隔得分表”

sqlContext.registerDataFrameAsTable(R_SCORE, "R_SCORE_TB")

3.查看表中数据

sqlContext.sql("select user_id,R_SCORE counts from R_SCORE_TB limit 5").show()

通过上述步骤,我们已经创建了用户RFM(R值)得分表R_SCORE_TB。

(2)创建R值等级分类表USER_R_RANK_TB

4.以平均值作为参照,各维度得分大于其平均值的定义为高,小于等于其平均值的定义为低。

创建“R得分值”平均值表

sqlContext.registerDataFrameAsTable(

sqlContext.sql("""

SELECT AVG(R_SCORE) FROM R_SCORE_TB

""")

, "AVG_R_SCORE_TB")

5.查询表中平均值

sqlContext.sql("""

select * from AVG_R_SCORE_TB

""").show()

说明:平均值约为1.546

6.创建“用户R值等级分类”的DataFrame

USER_R_RANK=sqlContext.sql("""

SELECT user_id,R_SCORE,

(CASE

WHEN R_SCORE > 1.546 THEN 'high'

ELSE 'low' END

) AS User_R_Assess

FROM R_SCORE_TB

""")

查看数据

7.创建“用户R值等级分类表”,将USER_R_RANK转换为表"USER_R_RANK_TB"

sqlContext.registerDataFrameAsTable(USER_R_RANK, "USER_R_RANK_TB")

说明:通过上述步骤,已经完成了“用户R值等级分类表”的创建。

【步骤四:创建用户F值等级分类表】

(1)创建F值得分表F_SCORE_TB(消费频次得分表)

1.创建RFM(F值)得分表,对于F值,作如下定义:

定义消费频次为统计周期内用户的消费天数,同一天多次消费记为1次

消费频次小于2,F=1

消费频次大于等于2,小于5,F=2

消费频次大于等于5,小于8,F=3

消费频次大于等于8,小于11,F=4

消费频次大于等于11,F=5

F_SCORE=sqlContext.sql("""

SELECT user_id,

(CASE

WHEN con_freq >= 11 THEN 5

WHEN con_freq >= 8 AND con_freq< 11 THEN 4

WHEN con_freq >= 5 AND con_freq< 8 THEN 3

WHEN con_freq >= 2 AND con_freq< 5 THEN 2

WHEN con_freq< 2 THEN 1 ELSE 0 END

)AS F_SCORE

FROM

(SELECT user_id,COUNT(DISTINCT action_time) AS con_freq

FROM uservalue_tb

WHERE type='2'

GROUP BY user_id) frequency

ORDER BY F_SCORE DESC

""")

2.我们称F_SCORE为“消费频次得分”,F_SCORE是一个DataFrame,将其转换为表F_SCORE_TB,称为“消费频次得分表”

sqlContext.registerDataFrameAsTable(F_SCORE, "F_SCORE_TB")

3.查看表中数据

sqlContext.sql("select user_id,F_SCORE counts from F_SCORE_TB").show(5)

通过上述步骤,我们已经创建了用户RFM(R值)得分表F_SCORE_TB。

(2)创建F值等级分类表USER_F_RANK_TB

4.创建“F得分值”平均值表

sqlContext.registerDataFrameAsTable(

sqlContext.sql("""

SELECT AVG(F_SCORE) FROM F_SCORE_TB

""")

, "AVG_F_SCORE_TB")

5.获取平均值

sqlContext.sql("""

select * from AVG_F_SCORE_TB

""").show()

说明:平均值约为1.16

6.创建“用户F值等级分类”USER_F_RANK

USER_F_RANK=sqlContext.sql("""

SELECT user_id,F_SCORE,

(CASE

WHEN F_SCORE > 1.16 THEN 'high'

ELSE 'low' END

) AS User_F_Assess

FROM F_SCORE_TB

""")

USER_F_RANK.show(5)

7.创建用户F值等级分类表,将USER_F_RANK转换为表USER_F_RANK_TB

sqlContext.registerDataFrameAsTable(USER_F_RANK, "USER_F_RANK_TB")

通过上述步骤,我们已经创建了用户R值等级分类表USER_R_RANK_TB和F值等级分类表USER_F_RANK_TB。

通过上述步骤,我们已经创建了用户R值等级分类表USER_R_RANK_TB和F值等级分类表USER_F_RANK_TB。

【步骤五:创建用户分类表】

1. 基于创建的用户分类表,根据用户的R,F得分进行分类:

重要价值客户:用户R值评价='高' 并且 用户F值评价='高'

重要发展客户:用户R值评价='高' 并且 用户F值评价='低'

重要保持客户:用户R值评价='低' 并且 用户F值评价='高'

重要挽留客户:用户R值评价='低' 并且 用户F值评价='低'

编写查询用户价值分类的SQL

User_Value_Class= sqlContext.sql("""

SELECT r.user_id,

(CASE

WHEN r.User_R_Assess='high' AND f.User_F_Assess='high' THEN 'Imp_Value_Cus'

WHEN r.User_R_Assess='high' AND f.User_F_Assess='low' THEN 'Imp_Develop_Cus'

WHEN r.User_R_Assess='low' AND f.User_F_Assess='high' THEN 'Imp_Keep_Cus'

WHEN r.User_R_Assess='low' AND f.User_F_Assess='low' THEN 'Imp_Stay_Cus'

ELSE NULL END) AS User_Value_Class

FROM USER_R_RANK_TB r INNER JOIN USER_F_RANK_TB f ON r.user_id=f.user_id

""")

2.查看数据

user_Value_Class.show()

3.创建用户价值分类表User_Value_Class_TB

sqlContext.registerDataFrameAsTable(User_Value_Class, "User_Value_Class_TB")

4.保存用户价值分类结果

User_Value_Class.coalesce(1).write.option("header","true").save("/uservalue/User_Value_Class.parquet")

参数解读:

coalesce(1):文件分区设置为1

write.mode("overwrite"):保存方式为覆盖

option("header","true"):保存表列名

save("/uservalue/User_Value_Class.parquet"):保存为parquet文件格式,存储路径为集群的/uservalue/

通过本实验任务,我们已经创建了用户价值分类表User_Value_Class_TB并查看分类后的结果。

至此,实验结束!

posted @ 2024-06-05 10:30  jhtchina  阅读(33)  评论(0编辑  收藏  举报