本文主要介绍如何使用python搭建一个:基于Django的用户画像可视化系统。
本项目分为2部分:
1、通话数据
2、短信数据
3、手机上网数据
博主也参考过机器学习模型的文章,但大多是理论大于方法。很多同学肯定对原理不需要过多了解,只需要搭建出一个可视化系统即可。
也正是因为我发现网上大多的帖子只是针对原理进行介绍,功能实现的相对很少。
如果您有以上想法,那就找对地方了!
不多废话,直接进入正题!
本项目最终展示界面是基于Django构建的网站,下面就介绍一下画像展示界面。
输入了正确手机号后,会根据搜索用户展示用户的画像
用户:19900000383
以客户为中心目标是了解不同客户群体的需求,并向他们提供满足其个性化需求的服务——提供了更多附加值,与此同时也获得高于平均的客户价值。随着电信业产品同质化的趋势越来越明显,企业成功不能再单纯依靠创新产品和产品价格取胜。倾听客户呼声和需求、对不断变化的客户期望迅速作出反应的以客户为中心运营能力——已经成为当今企业能否成功的关键。
市场环境、运营重心和管控模式的转变,要求客户运营更具灵敏性、高效性,以客户洞察为核心的客户经营中心系统实现了“客户-产品”的双向自动匹配,支撑CRM、电子渠道等精准营销策略和客户需求信息的实时信息推送,培养了业务人员客户洞察能力。
1、历史趋势分析,分析对应客户数的历史变化情况
2、构成分析,按照品牌、地市、VIP等级等维度,分析对应客户数的构成情况
3、关联分析,分析主体与不同标签之间的关联程度
4、对比分析,分析主体与不同标签之间的对比情况
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.移动电话用户,及其呼叫清单:
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.day
data_tele["diff_date"] = (31 - data_tele["last_date_day"]).astype('int')
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)
#不同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)
#不同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)
# 此次运行耗时较长,可以直接执行加载数据集的方法,此数据集是上述代码执行的结果
#对合并后的表中每个用户在每个标签类别的RFM求和
data_numbers = data_total.groupby(["tele_num",'tag']).sum().reset_index()
#求和后大于0的标为1
columns_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().index
for 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)
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
由于项目代码量和数据集较大,感兴趣的同学可以直接下载代码,使用过程中如遇到任何问题可以在评论区进行评论,我都会一一解答。
代码下载: