运用RFM模型为某汽车租赁公司进行用户画像

本文结构
1、背景
2、主要结论与建议
3、思路和代码展示
4、知识点补充

一:背景

用户画像即用户信息标签化,通过用户画像,可了解用户兴趣偏好→制定策略 →精准触达 →通过数据反馈的方式指导和优化策略。
主要通过收集用户的注册、登录、消费和行为数据进行标签化。

数据源:
包含用户的属性、消费数据和行为数据。共3000条数据。主要列:
‘用户编号’, ‘RR’, ‘FF’, ‘MM’, ‘时租次数’, ‘日租次数’, ‘自取次数’, ‘送车次数’, ‘微信支付次数’,
‘支付宝支付次数’, ‘兑换码支付次数’, ‘余额支付次数’, ‘负债次数’, ‘非网点还车次数’, ‘优惠券使用次数’, ‘优惠金额总数’,
‘周中次数’, ‘早高峰’, ‘晚高峰’, ‘长途次数’, ‘总时长’, ‘总里程’, ‘上午通勤次数’, ‘首单时间’, ‘用车城市’,
‘出生年月’, ‘性别’, ‘最后一次距今天数’, ‘单均价’

需求场景:对用户的行为进行分析,运用RFM模型进行分层,做出用户画像。
主要工具:python、tableau
处理步骤:读取数据→python数据处理→tableau数据可视化展示→产出报告
先看结果展示:

主要结论与建议

1、基础信息方面:
该公司的付费用户主要以男性为主,占比近80%。
年龄段主要分布在46-60岁之间,另外还存在部分60-70岁的人群。
用车城市top 3 主要是西安市、武汉市、大理白族自治州。可以猜测业务可能集中在
非一线城市。会不会是因为一线城市已经趋于饱和,市场占有相对困难?
2、通过RFM对其用户进行分层,发现重要价值用户和一般保持用户相对占比较高,是一个比较健康的用户体系,重点工作可放在转化重要发展用户身上, 留着重点价值用户,转化其他用户为重要价值用户为其长远目标。
3、生命周期方面,我们可以发现95%的用户处于流失期,虽然汽车租赁本身流失率可能相对较高,但是运营侧还是可以通过交叉分析数据,对应的做一些活动,减少用户流失。
4、行为分析:
付费用户的非工作日活跃>付费工作日活跃
付费用户其他时段活跃>晚峰活跃>早峰活跃
自取>送车
月均单量基本都小于6单
支付方式主要是微信支付
有81%的用户不用优惠券 不知道活动?不满足活动条件?
5、用户类型交叉分析
与年龄交叉分析,45-60岁区间是主力军。可以根据不同的年龄层的喜好设计运营 策略,在拉新时也可有清晰定位。
与取车类型交叉分析,可发现重要发展用户的取车习惯时自取和送车几乎平分,这是一个值得深究的点。
与活跃类型交叉分析,可发现重要发展用户非工作日活跃居多,而一般保持用户以工作日活跃居多,在进行用户向更上一级转化时,可充分考虑这些习惯。

以下是用户画像:
在这里插入图片描述

三、思路和代码展示

首先,确定用户画像的标签,如何去展现,都有什么意义?
下面这张思维导图可帮助更好理解用户画像。

在这里插入图片描述
我们有了数据源,就可以去计算得到我们先要的标签信息。

#导入包
import pandas as pd
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import  seaborn as sns
from datetime import datetime
from dateutil.relativedelta import relativedelta #计算差值

# 导入数据 RR最近一次消费时间 FF消费频次(累计消费次数) MM消费总额
data = pd.read_csv('./数据集.csv')
# print(data.head())
#数据处理
print(data.head())
print(data.info())

数据源截图:
在这里插入图片描述
Data columns (total 27 columns):
用户编号 3000 non-null int64
RR 3000 non-null object
FF 3000 non-null int64
MM 3000 non-null float64
时租次数 3000 non-null int64
日租次数 3000 non-null int64
自取次数 3000 non-null int64
送车次数 3000 non-null int64
微信支付次数 3000 non-null int64
支付宝支付次数 3000 non-null int64
兑换码支付次数 3000 non-null int64
余额支付次数 3000 non-null int64
负债次数 3000 non-null int64
非网点还车次数 3000 non-null int64
优惠券使用次数 3000 non-null int64
优惠金额总数 3000 non-null float64
周中次数 3000 non-null int64
早高峰 3000 non-null int64
晚高峰 3000 non-null int64
长途次数 3000 non-null int64
总时长 3000 non-null float64
总里程 3000 non-null int64
上午通勤次数 3000 non-null int64
首单时间 2861 non-null object
用车城市 2861 non-null object
出生年月 3000 non-null object
性别 3000 non-null object
dtypes: float64(3), int64(19), object(5)
memory usage: 632.9+ KB
None

基本了解数据源之后,开始数据清洗
主要包含处理空值、处理重复值、处理不符合业务逻辑的值等等。

# 删除null值  仅保留下单过的用户
data.dropna(how='any',inplace=True)

#用户编号重复值
data[data.duplicated("用户编号")]
data.drop_duplicates("用户编号",inplace=True)

清洗完毕,接下来是非常重要的数据处理,这一步给用户打上标签。

#转时间
data['RR'] = pd.to_datetime(data['RR'])
data['首单时间'] = pd.to_datetime(data['首单时间'])

#计算最近一次消费时间距今的时间
data['最后一次距今天数'] =data['RR'].map(lambda x: (datetime.today().date()-x.date()).days)
data['单均价'] = (data['MM']/data['FF']).map(lambda x: round(x,2))
#月数的算法有很多,算出的结果也不一样,一定需要先确定业务方想要的效果,不然可能会存在误差
data['月数'] = data['首单时间'].map(lambda x:
                              (relativedelta(datetime.today().date(),x.date()).years)*12
     +(relativedelta(datetime.today().date(),x.date()).months)
                             )
#-----用户标签------
data["年龄"] =data['出生年月'].map(lambda x: datetime.today().year-int(x[0:4]))
data['时租占比'] = np.where(data['时租次数']/data['FF']>0.5,'时租居多','日租居多')
data['取车偏好'] = np.where(data['自取次数']/data['FF']>0.5,'自取居多','送车居多')
data['还车偏好'] = np.where(data['非网点还车次数']/data['FF']>0.5,'网点外还车居多','网点还车居多')

#支付方式占比
def pay_type(f,v,z,y):
    if v/f  > 0.5 :
        p_type = '微信支付居多'
    elif z/f > 0.5 :
        p_type = "支付宝支付居多"
    elif y/f > 0.5 :
        p_type = "余额支付居多"
    else:
        p_type = "他支付方式居多"
    return p_type
data['支付方式占比'] = data.apply(lambda row: 
                            pay_type(row['FF'],row['微信支付次数'], 
                            row['支付宝支付次数'],
                            row['余额支付次数']), axis=1)

data['优惠券金额占比'] = (data['优惠金额总数']/(data['MM']+data['优惠金额总数'])).map(lambda x: round(x,4))

data["使用优惠券情况"] = np.where((data['优惠券使用次数']/data['FF'])>1,"全用",
         np.where((data['优惠券使用次数']/data['FF'] >0)&(data['优惠券使用次数']/data['FF'] <1),"半用",
                  '不用'))
data['月均单量情况'] = np.where(data['FF']/data['月数']>=6,"月均单数大于6","月均单数小于6")
data['单均价情况'] = np.where(data['单均价']>=40,"单均大于40","单均小于40")
data["活跃情况"] = np.where((data['FF']-data['周中次数'])>=0.5,"非工作日活跃",
         np.where((data['周中次数']/data['FF'])>=0.5,'工作日活跃','全周活跃'))
data["上下午活跃情况"] = np.where((data['FF']-data['上午通勤次数'])/data['FF']>=0.5,"下午活跃",
         np.where((data['上午通勤次数']/data['FF'])>=0.5,'上午活跃','全天活跃'))
data["活跃集中情况"] = np.where(data['早高峰']/data['FF']>=0.5,"早峰活跃",
         np.where((data['晚高峰']/data['FF'])>=0.5,'晚峰活跃','其他活跃'))
data['长短途情况'] = np.where(data['总里程'] /data['FF'] >=30,"长途居多","短途居多")

#三元运算符
data['R'] = np.where(data['最后一次距今天数']<data['最后一次距今天数'].median() , "低" , "高")
data['F'] = np.where(data['FF']<data['FF'].median() , "低" , "高")
data['M'] = np.where(data['MM']<data['MM'].median() , "低" , "高")
#进行用户分层
def level(x):
    if x == "高高高":
        y ="重要价值用户"
    elif x=="高低高":
        y =  "重要保持用户"
    elif x=="低高高":
        y =  "重要发展用户"
    elif x=="低低高":
        y =  "重要挽留用户"
    elif x=="高高低":
        y =  "一般价值用户"
    elif x=="高低低":
        y =  "一般发展用户"
    elif x=="低高低":
        y =  "一般保持用户"
    elif x=="低低低":
        y =  "一般挽留用户"
    else:
        y = ""
    return y
data['RFMlevel'] = (data['R']+data['F']+data['M']).map(lambda x:level(x) )
#按最后一次付费至今的日期进行用户生命周期标记
def life_cycle(a,b):
    if a==1 and b <=15 :
        y = "引入期"
    elif a>1 and a and b <=70 :
        y = "成长期"
    elif a>=4 and b <=90 :
        y = "休眠期"
    elif  b >90:
        y = "流失期"
    elif a==1 and b >15 :
        y = "流失期"
    else:
        y = "esle"
    return y
#进行了2次函数的调用 一次lambda 一次自定义函数
data['生命周期'] = data.apply(lambda row: life_cycle(row['FF'], row['最后一次距今天数']), axis=1)      

# df.apply(lambda row: my_test(row['a'], row['c']), axis=1)
print(data.tail())

print(data.info())
#导出数据  做可视化
data.to_excel('./用户画像源数据.xlsx')

数据处理完毕,可以导出做可视化,我这篇选择用tableau去做可视化,主要觉得相对轻松一点,可能用代码去做可视化更耗时,且效果不一定理想。如果用excel做的话,可能灵活性不够高。其实写完代码后发现,如果需要长期监控,很多标签放在tableau处理更好。

四、知识点补充

运营相关知识
用户生命周期

在这里插入图片描述

RFM模型
百度解释在这里插入图片描述

代码知识
函数
map()
apply()
应用与区别
pandas包在处理数据方面很是擅长,除了一些基础的dateframe的函数,要学会自己自定义一些函数,用map()和apply去调用,这样可以对一列或者多列的单个数据进行操作。

np.where() 三目运算法 np.where(condition, x, y)
np.where用法详解
非常好用,和if-elif-else的功能相同,可以多层嵌套,处理起来更加高效,基本上需要判断返回值的都可以用这个

from datetime import datetime
from dateutil.relativedelta import relativedelta
导入的时间处理的模块,可以高效的获取当前时间日期,计算时间差
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值