> 文档中心 > 手把手教你:基于RFM的用户画像可视化系统

手把手教你:基于RFM的用户画像可视化系统


系列文章

  • 第九章、手把手教你:个人信贷违约预测模型
  • 第八章、手把手教你:基于LSTM的股票预测系统
  • 第七章、手把手教你:基于深度残差网络(ResNet)的水果分类识别系统

目录

  • 系列文章
  • 一、项目简介
    • 1.1 内容简介
    • 1.2 电信运营商的三个典型数据
  • 二、可视化展示界面
  • 三、背景介绍
  • 四、模型构建思路
    • 1.用户画像主流分析方法
    • 2.本项目分析方法
  • 五、代码介绍
    • 1.数据介绍
    • 2.数据预处理
    • 3.电话数据RFM数据制作
    • 4.短信数据RFM数据制作
    • 5.APP数据RFM数据制作
    • 6.数据归一化,最终数据合并,生成标签
    • 7.展示界面
  • 六、代码下载地址


一、项目简介

1.1 内容简介

本文主要介绍如何使用python搭建一个:基于RFM的用户画像可视化系统。

本项目分为2部分:

  • 1、RFM模型构建,用户画像数据输出。
  • 2、网站搭建,提供用户画像查阅功能。

1.2 电信运营商的三个典型数据集

1、通话数据
2、短信数据
3、手机上网数据

  • 基于这三个数据集,结合RFM模型,构建用户标签体系
  • 给每个用户打上标签,对用户进行画像
  • 画像后的数据可以用于推荐、精准营销、客群分析等

博主也参考过机器学习模型的文章,但大多是理论大于方法。很多同学肯定对原理不需要过多了解,只需要搭建出一个可视化系统即可。

也正是因为我发现网上大多的帖子只是针对原理进行介绍,功能实现的相对很少。

如果您有以上想法,那就找对地方了!


不多废话,直接进入正题!

二、可视化展示界面

本项目最终展示界面是基于Django构建的网站,下面就介绍一下画像展示界面。

1.搜索界面

  • 本项目需要对应的用户手机号搜索对应的移动用户画像,在搜索过程中也进行了校验如输入的文本格式不符合手机号,将直接提示错误。
    搜索界面
  • 输入错误提示:
    输入错误提示

2.用户画像展示界面

  • 输入了正确手机号后,会根据搜索用户展示用户的画像

  • 用户:19900000383

用户画像1

  • 用户:19900035430
    用户画像2

三、背景介绍

以客户为中心目标是了解不同客户群体的需求,并向他们提供满足其个性化需求的服务——提供了更多附加值,与此同时也获得高于平均的客户价值。随着电信业产品同质化的趋势越来越明显,企业成功不能再单纯依靠创新产品和产品价格取胜。倾听客户呼声和需求、对不断变化的客户期望迅速作出反应的以客户为中心运营能力——已经成为当今企业能否成功的关键。

市场环境、运营重心和管控模式的转变,要求客户运营更具灵敏性、高效性,以客户洞察为核心的客户经营中心系统实现了“客户-产品”的双向自动匹配,支撑CRM、电子渠道等精准营销策略和客户需求信息的实时信息推送,培养了业务人员客户洞察能力。


四、模型构建思路

1.用户画像主流分析方法

1、历史趋势分析,分析对应客户数的历史变化情况
2、构成分析,按照品牌、地市、VIP等级等维度,分析对应客户数的构成情况
3、关联分析,分析主体与不同标签之间的关联程度
4、对比分析,分析主体与不同标签之间的对比情况

2.本项目分析方法

  • 本实验的第一个步骤:基于通话数据生成RFM模型数据,输出每个客户在每个标签上的RFM标签值,这是一个中间结果集,用于计算最终的标签。

R:最近一次通话时间与统计月末的距离天数
F:通话次数
M:通话时长

  • 最终数据结果示例如下:
手机号码 标签 R值 F值 M值
138* 旅游 1 0 0
138* 美食 0 1 0
138* 健身 1 1 0
131* 旅游 1 0 1
131* 美食 0 1 0
134* 旅游 0 1 1

五、代码介绍

  • 由于代码众多,博客中就不放入最终代码了,有需要的童鞋可以在【代码下载地址】下载所有代码。

1.数据介绍

  • 我们的数据分为2部分,大概思路就是通过找到移动号码拨打的各行业的固定电话,最终收敛形成移动号码画像。重要申明:因电话信息涉及用户个人敏感信息,本文所述所有数据均经过脱敏处理!

1.固定电话清单以及其行业分类:
固定电话清单以及其行业分类
2.移动电话用户,及其呼叫清单:
移动电话用户,及其呼叫清单

2.数据预处理

  • 需要将两种数据进行合并,合并成一个数据表后才能继续操作
data_tele = data_tele_tag.merge(data_tele_detail,left_on="desc_num",right_on='desc_num')
  • 处理完后数据情况:
    处理完后数据情况
  • 需要计算离月底最近的一次通话,所以需要进行日期的计算
data_tele["last_date"] = pd.to_datetime(data_tele.last_date,format='%Y-%m-%d')data_tele["last_date_day"] = data_tele.last_date.dt.daydata_tele["diff_date"] = (31 - data_tele["last_date_day"]).astype('int')
  • 完成数据预处理后数据情况:
    在这里插入图片描述

3.电话数据RFM数据制作

  • 分别计算不同电话、不同标签的最近一次通话、通话总次数以及通话总时长
def make_rfm(x):    def get_format_rfm(xx): temp_date = xx.nsmallest(1,'diff_date')['diff_date'].iloc[0] temp_count = xx['count'].sum() temp_duration = xx["duration"].sum() tem_series = pd.Series([temp_date,temp_count,temp_duration],index=['last_date','count','duration']) return tem_series    return x.groupby('tag').apply(get_format_rfm)data_tele_rfm = data_tele.groupby("tele_num").apply(make_rfm)data_tele_rfm = data_tele_rfm.reset_index()# 保存data_tele_rfm.to_csv("data/tele数据rfm数据表.csv",encoding='utf-8-sig',index=False)

4.短信数据RFM数据制作

  • 具体制作流程和电话数据是一致的,只是需要加载不同的数据集
#不同sms不同电话标签的RFM值的提取def make_rfm_sms(x):    def get_format_rfm_sms(xx): temp_date = xx.nsmallest(1,'diff_date')['diff_date'].iloc[0] temp_count = xx['count'].sum() temp_duration = xx['count'].sum() tem_series = pd.Series([temp_date,temp_count,temp_duration],index=['last_date','count','duration']) return tem_series    return x.groupby('tag').apply(get_format_rfm_sms)data_sms_rfm = data_sms.groupby("tele_num").apply(make_rfm_sms)data_sms_rfm = data_sms_rfm.reset_index()# 保存data_sms_rfm.to_csv("data/短信数据rfm数据表.csv",encoding='utf-8-sig',index=False)

5.APP数据RFM数据制作

  • 具体制作流程和电话数据是一致的,只是需要加载不同的数据集
#不同app不同标签,的RFM值的提取def make_rfm_app(x):    def get_format_rfm_app(xx): temp_date = xx.nsmallest(1,'diff_date')['diff_date'].iloc[0] temp_count = xx['count'].sum() temp_duration = xx['count'].sum() tem_series = pd.Series([temp_date,temp_count,temp_duration],index=['last_date','count','duration']) return tem_series    return x.groupby('tag').apply(get_format_rfm_app)data_app_rfm = data_app.groupby("tele_num").apply(make_rfm_app)data_app_rfm = data_app_rfm.reset_index()# 保存data_app_rfm.to_csv("data/app数据rfm数据表.csv",encoding='utf-8-sig',index=False)# 此次运行耗时较长,可以直接执行加载数据集的方法,此数据集是上述代码执行的结果

6.数据归一化,最终数据合并,生成标签

  • 最终要生成one-hot矩阵,进行标签确认的前提就是rfm值中超过两个存在,或者flag_duration这个值是1就贴上标签
#对合并后的表中每个用户在每个标签类别的RFM求和data_numbers = data_total.groupby(["tele_num",'tag']).sum().reset_index()#求和后大于0的标为1columns_names = ['flag_days','flag_count','flag_duration']for name in columns_names:    data_numbers[name] = data_numbers[name].apply(lambda x: 1 if x>0 else 0)#通过2个条件过滤无价值用户,只保留RFM中3个值的和为2以上的以及M值为1的有价值用户data_numbers['condition1'] = data_numbers['flag_days']+data_numbers['flag_count']+data_numbers['flag_duration']data_numbers['condition2'] = data_numbers['flag_duration'].apply(lambda x:1 if x==0 else 0)data_result_pre = data_numbers[(data_numbers['condition1']>1) | (data_numbers['condition2']==1)]#添加所有标签对应的列tags = data_result_pre.tag.value_counts().indexfor tag_ in tags:    data_result_pre[tag_] = data_result_pre['tag'].apply(lambda x:1 if x==tag_ else 0)#删除无用列x=[2,3,4,5,6]data_result_pre.drop(data_result_pre.columns[x], axis=1, inplace=True)#合并每个用户的标签data_numbers1 = data_result_pre.groupby(["tele_num"]).sum().reset_index()data_numbers1.head(20)
  • 最终数据效果如前文所展示的:
    最终数据效果如前文所展示的

7.展示界面

  • 完成上述用户画像模型构建后就是页面展示,本项目采用了Django进行展示。
  • 用户验证与输入检测:
def get_ans(request):    text = request.POST["input_text"]    print("获取的号码:", text)    if text is "": context = {     "state": "1",     "text": "输入的内容为空,请重新输入想要查询的号码!" } return render(request, 'error.html', context)    else: if is_number(text):     context = user_get(int(text))     if context == {}:  context = {      "state": "3",      "text": "查询的号码不存在,请输入正确的号码!"  }  return render(request, 'error.html', context)     else:  return render(request, 'user_class.html', context) else:     context = {  "state": "2",  "text": "输入的内容包含其他字符,请输入正确的号码!"     }     return render(request, 'error.html', context)# 输入检测def is_number(s):    try: float(s) return True    except ValueError: pass    try: import unicodedata unicodedata.numeric(s) return True    except (TypeError, ValueError): pass    return False

六、代码下载地址

由于项目代码量和数据集较大,感兴趣的同学可以直接下载代码,使用过程中如遇到任何问题可以在评论区进行评论,我都会一一解答。

代码下载:

  • 【代码分享】手把手教你:基于RFM的用户画像可视化系统