机器学习之桑基图(用于用户行为分析)
一、用户行为分析
1.1 用户路径
- 用户在网站或APP中的访问行为路径,为了衡量网站/APP的优化效果或营销推广效果,了解用户的行为偏好,要对访问路径的数据进行分析。
1.2 用户路径分析价值
- 用户路径分析:以目标时间为起点或终点,通过描述用户的行为路径,可以查看某个时间节点用户的流向,科学的路径分析能够带来以下的价值:
1)可视化用户流向,对海量用户的行为习惯行程宏观了解;
通过用户路径分析,可以将整个用户路径的上下游进行可视化展示。即可看到用户群体的登录、跳转、流失、成交等事件的情况。运用人员可通过用户整体的行为路径找到不同行为间的关系,挖掘规律并找到瓶颈。
2)行为影响转化的因素,推动产品的优化与改进;
路径分析对产品设计的优化与改进有着很大的帮助,聊些用户从登陆到购买整体行为的主路径和次路径,根据用户路径中各个环节的转化率,发现用户的行为规律和偏好,也用于检测和定位用户路径走向中存在的问题,判断影响转化的主要因素和次要因素,也可发现某些冷门的功能点。
1.3 路径分析与漏斗分析
-
路径分析模型: 行为路径分析是用来追踪用户从某个事件开始到某个事件结束过程中的全部动线的分析方法。对于用户的行为路径,我们虽然可以通过产品设计进行引导,但却无法控制。因此我们分析用户的行为路径可以了解用户的实际操作行为,让产品顺应用户,通过优化界面交互让产品用起来更加流畅和符合用户习惯,产出更多价值,多用桑基图展示。
-
漏斗分析模型: 是一套流程式数据分析,它能够科学反映用户行为状态以及从起点到终点各阶段用户转化率情况,是一种重要的分析模型。漏斗分析模型已经广泛应用于网站和APP用户行为分析的流量监控、电商行业、零售的购买转化率、产品营销和销售等日常数据运营与数据分析的工作中。
二、桑基图
2.1 数据导入
from pyecharts import options as opts
from pyecharts.charts import Sankey
import pandas as pd
data = pd.read_excel(r'./train.xlsx')
data
2.2 数据提取
cols = data.columns.tolist()[:-1] #取出数据列名,除了ID列
cols1 = cols[:-1]
cols2 = cols[1:]
print('cols1=',cols1,'\n','cols2=',cols2)
data1 = pd.DataFrame()
for i in zip(cols1,cols2):
datai = data.pivot_table('ID',index=list(i),aggfunc='count').reset_index() #数据透视表
datai.columns=['col1','col2','count']
data1 = data1.append(datai)
data1
'''
cols1= ['登船港口', '票类', '性别', '年龄']
cols2= ['票类', '性别', '年龄', '是否存活']
col1 col2 count
0 C港口 1类 74
1 C港口 2类 15
2 C港口 3类 38
3 Q港口 1类 2
4 Q港口 2类 2
5 Q港口 3类 24
6 S港口 1类 107
7 S港口 2类 153
8 S港口 3类 290
0 1类 女 83
1 1类 男 100
2 2类 女 74
3 2类 男 96
4 3类 女 100
5 3类 男 252
0 女 0岁-10岁 28
1 女 10岁-20岁 45
2 女 20岁-30岁 72
3 女 30岁-40岁 59
4 女 40岁-50岁 32
5 女 50岁-60岁 18
6 女 60岁-70岁 3
7 男 0岁-10岁 27
8 男 10岁-20岁 57
9 男 20岁-30岁 148
10 男 30岁-40岁 107
11 男 40岁-50岁 57
12 男 50岁-60岁 30
13 男 60岁-70岁 15
14 男 70岁-80岁 6
15 男 80岁-90岁 1
0 0岁-10岁 死亡 24
1 0岁-10岁 生存 31
2 10岁-20岁 死亡 61
3 10岁-20岁 生存 41
4 20岁-30岁 死亡 143
5 20岁-30岁 生存 77
6 30岁-40岁 死亡 94
7 30岁-40岁 生存 72
8 40岁-50岁 死亡 55
9 40岁-50岁 生存 34
10 50岁-60岁 死亡 28
11 50岁-60岁 生存 20
12 60岁-70岁 死亡 13
13 60岁-70岁 生存 5
14 70岁-80岁 死亡 6
15 80岁-90岁 生存 1
'''
2.3 生成节点
# 生成nodes
nodes = []
# 先添加几个顶级的父节点
nodes.append({'name':'C港口'})
nodes.append({'name':'Q港口'})
nodes.append({'name':'S港口'})
# 添加其他节点
for i in data1['col2'].unique():
dic = {}
dic['name'] = i
nodes.append(dic)
nodes
'''
[{'name': 'C港口'},
{'name': 'Q港口'},
{'name': 'S港口'},
{'name': '1类'},
{'name': '2类'},
{'name': '3类'},
{'name': '女'},
{'name': '男'},
{'name': '0岁-10岁'},
{'name': '10岁-20岁'},
{'name': '20岁-30岁'},
{'name': '30岁-40岁'},
{'name': '40岁-50岁'},
{'name': '50岁-60岁'},
{'name': '60岁-70岁'},
{'name': '70岁-80岁'},
{'name': '80岁-90岁'},
{'name': '死亡'},
{'name': '生存'}]
'''
2.4 生成连接关系
#生成link
links = []
for i in data1.values:
dic = {}
dic['source'] = i[0]
dic['target'] = i[1]
dic['value'] = i[2]
links.append(dic)
links
'''
[{'source': 'C港口', 'target': '1类', 'value': 74},
{'source': 'C港口', 'target': '2类', 'value': 15},
{'source': 'C港口', 'target': '3类', 'value': 38},
{'source': 'Q港口', 'target': '1类', 'value': 2},
{'source': 'Q港口', 'target': '2类', 'value': 2},
{'source': 'Q港口', 'target': '3类', 'value': 24},
{'source': 'S港口', 'target': '1类', 'value': 107},
{'source': 'S港口', 'target': '2类', 'value': 153},
{'source': 'S港口', 'target': '3类', 'value': 290},
{'source': '1类', 'target': '女', 'value': 83},
{'source': '1类', 'target': '男', 'value': 100},
{'source': '2类', 'target': '女', 'value': 74},
{'source': '2类', 'target': '男', 'value': 96},
{'source': '3类', 'target': '女', 'value': 100},
{'source': '3类', 'target': '男', 'value': 252},
{'source': '女', 'target': '0岁-10岁', 'value': 28},
{'source': '女', 'target': '10岁-20岁', 'value': 45},
{'source': '女', 'target': '20岁-30岁', 'value': 72},
{'source': '女', 'target': '30岁-40岁', 'value': 59},
{'source': '女', 'target': '40岁-50岁', 'value': 32},
{'source': '女', 'target': '50岁-60岁', 'value': 18},
{'source': '女', 'target': '60岁-70岁', 'value': 3},
{'source': '男', 'target': '0岁-10岁', 'value': 27},
{'source': '男', 'target': '10岁-20岁', 'value': 57},
{'source': '男', 'target': '20岁-30岁', 'value': 148},
{'source': '男', 'target': '30岁-40岁', 'value': 107},
{'source': '男', 'target': '40岁-50岁', 'value': 57},
{'source': '男', 'target': '50岁-60岁', 'value': 30},
{'source': '男', 'target': '60岁-70岁', 'value': 15},
{'source': '男', 'target': '70岁-80岁', 'value': 6},
{'source': '男', 'target': '80岁-90岁', 'value': 1},
{'source': '0岁-10岁', 'target': '死亡', 'value': 24},
{'source': '0岁-10岁', 'target': '生存', 'value': 31},
{'source': '10岁-20岁', 'target': '死亡', 'value': 61},
{'source': '10岁-20岁', 'target': '生存', 'value': 41},
{'source': '20岁-30岁', 'target': '死亡', 'value': 143},
{'source': '20岁-30岁', 'target': '生存', 'value': 77},
{'source': '30岁-40岁', 'target': '死亡', 'value': 94},
{'source': '30岁-40岁', 'target': '生存', 'value': 72},
{'source': '40岁-50岁', 'target': '死亡', 'value': 55},
{'source': '40岁-50岁', 'target': '生存', 'value': 34},
{'source': '50岁-60岁', 'target': '死亡', 'value': 28},
{'source': '50岁-60岁', 'target': '生存', 'value': 20},
{'source': '60岁-70岁', 'target': '死亡', 'value': 13},
{'source': '60岁-70岁', 'target': '生存', 'value': 5},
{'source': '70岁-80岁', 'target': '死亡', 'value': 6},
{'source': '80岁-90岁', 'target': '生存', 'value': 1}]
'''
c = (
Sankey(init_opts=opts.InitOpts(width="1200px", height="600px"))
.add(
"桑基图",
nodes=nodes,
links=links,
linestyle_opt=opts.LineStyleOpts(opacity=0.2, curve=0.5, color="source"), #配置样式
label_opts=opts.LabelOpts(position="right") #node显示在右侧,如S港口
)
.set_global_opts(title_opts=opts.TitleOpts(title="桑基图")) #设置图标题
#.render("./image.html")#保存到本地html文件
)
c.render_notebook() #在jupyter notebook页面展示