使用Python+R做用户购买路径分析

1、需求:

在用户行为分析中重要的一环是对用户行为路径的分析,如先访问什么再访问什、现购买什么再购买什么。找到用户的访问或购买路径,有助于我们对商业流程的理解,也可以帮助我们改善和优化企业产品。

2、题设:

假设我们是一家家电电商网站,拥有所有客户的购买每种家电的详细记录(包括客户id,购买产品,购买日期)。

客户购买记录,数据全是瞎编的

我们希望通过这个数据分析出社会用户在购买家电先后顺序的行为路径。
这个结果的实际用途,例如客户在装修新房后购置抽油烟机,那么我们很可能希望给他推荐热水器或者空调等。我们总不至于像某东网站一样,客户购买了一个冰箱后还给推荐另一个冰箱吧?

3、结果示例:

希望能够得到类似下图的结果:

结果示例

这是百度echarts的Sankey(桑基图)图示例,我们将通过Python+R实现类似的效果。

4、技术路线:

如标题所述,使用Python进行数据处理,形成R绘图直接可用的数据结构;再使用R绘制Sankey图(之所以不使用Python直接绘图,是因为Python在绘制桑基图方面还不够完善——好吧,是我不会!)。
先来看R绘制桑基图networkD3官方给出的示例代码:

#R code
# Load energy projection data
# Load energy projection data
URL <- paste0(
        "https://cdn.rawgit.com/christophergandrud/networkD3/",
        "master/JSONdata/energy.json")
Energy <- jsonlite::fromJSON(URL)
# Plot
sankeyNetwork(Links = Energy$links, Nodes = Energy$nodes, Source = "source",
             Target = "target", Value = "value", NodeID = "name",
             units = "TWh", fontSize = 12, nodeWidth = 30)

访问上述url指向的地址,可以看到数据文件格式,这是一个json文件,结构如下:

#R networkD3绘制桑基图所需的数据格式
{"nodes":[
{"name":"Agricultural 'waste'"},
{"name":"Bio-conversion"},
……
],
"links":[
{"source":0,"target":1,"value":124.729},
{"source":1,"target":2,"value":0.597},
{"source":1,"target":3,"value":26.862}],
……
]}

数据主要包含两个部分:nodes的每条记录表示桑基图中每个节点位置的名称;links的每条记录表示从某个节点到另一个节点出现的次数。source和target后面所跟的数字顺序和nodes后面的数据顺序一致。如0表示节点名字是Agricultural 'waste',1表示节点Bio-conversion,{"source":0,"target":1,"value":124.729}表示从Agricultural 'waste'到Bio-conversion有124.729大的量。
因此,剩下的工作就是如何将上述分笔交易数据转化成上述符合要求的格式。

5、数据整理:

大致分析一下,我们首先需要找到购买了两笔及以上的客户。然后将这些客户中,每个客户成交商品的顺序进行处理。
如一个客户先后购买了:冰箱——洗衣机——电视机,整理出的关系则是:

source    target    value
冰箱       洗衣机     1
洗衣机     电视机     1

(1)首先,需要将购买有2次记录及以上的所有数据筛选出来备用。

#Python code
import pandas as pd
#读取所有数据
base_data=pd.read_excel('C:/Users/Administrator/Desktop/家电购买记录.xlsx')
#找出购买了两次及以上的用户(通过user_id统计次数再作筛选)
buy_times=base_data.groupby('user_id')['product'].count()
re_buy_userid=buy_times[buy_times>1].reset_index()
#筛选所有购买两次及以上用户的购买记录
rebuy_data=base_data[base_data['user_id'].isin(re_buy_userid['user_id'])]

(2)第二步,分析购买先后次序。思路是对每个客户的购买记录进行分析,形成第5部分开头所示的明细列表,然后再对这个明细列表进行汇总,计算出每种对应关系的汇总结果。

#Python code
#分析流向
source_name=[]
target_name=[]
num=[]
#遍历每个购买两次及以上的用户id
for user_id in re_buy_userid['user_id']:
    #取出每个用户购买记录明细,按时间升序排列,重建索引,以便后面取结果时使用
    each_buy=rebuy_data[rebuy_data['user_id']==user_id].sort_values(by='buytime',ascending=True).reset_index()
    #按顺序对上述明细数据进行遍历,分别取当前记录的product和下一条记录的product,即可构成购买先后关系
    for i in range(len(each_buy)-1):
        each_source=each_buy['product'][i]
        each_target=each_buy['product'][i+1]
        source_name.append(each_source)
        target_name.append(each_target)
        num.append(1)
#对结果进行整理,形成一个表格
st_result=pd.DataFrame([source_name,target_name,num],index=['source_name','target_name','num']).T
#获取统计结果
group_result=st_result.groupby(['source_name','target_name']).count().reset_index().sort_values(by='num',ascending=False)

这里我们得到的结果如下:

客户购买路径数据统计结果

实际上,到这里,基本上已经是我们R所需要的数据了,只需要将其转换成json格式即可。
同时,我们可以得出结论:我们的客户通常情况下买了电视机会接着买空调,买了电饭锅通常会买电磁炉,买了空调通常会买微波炉(千万别拿这个当决策,前面说了数据都是我瞎编的)...
(3)第三步,将上述数据转换成json格式,并存储成文件。

#Python code
#转化json所需格式
#定义names,以确定nodes的name顺序
names=group_result['source_name'].append(group_result['target_name']).drop_duplicates().reset_index(drop=True)
#将确定好的name顺序固定,生成一个对应表,用以对group_result里面的中文补充相应的name顺序代号
names_order=names.reset_index().reset_index().rename(columns={'level_0':'source','index':'target',0:'product'})
#添加source_name对应的name代号
mid_data=pd.merge(group_result,names_order[['source','product']],left_on='source_name',right_on='product',how='left')
#添加target_name对应的name代号
path_data=pd.merge(mid_data,names_order[['target','product']],left_on='target_name',right_on='product',how='left')

#生成nodes
name_list=[]
for i in names:
    each_name={'name':i}
    name_list.append(each_name)
#生成links
source_target=[]
for i in range(len(path_data)):
    each_links={'source':path_data['source'][i],'target':path_data['target'][i],'value':path_data['num'][i]}
    source_target.append(each_links)

#生成json格式
rebuy_dict={"nodes":name_list,"links":source_target}
rebuy_json=str(rebuy_dict).replace("'",'"')

#存储为json格式
f=open("d:/rebuy.json","w",encoding="utf-8")
f.write(str(rebuy_json))
f.close()

(4)第四步,使用R绘图

#R code
library(networkD3)
rebuy <- jsonlite::fromJSON('D:/rebuy.json')
sankeyNetwork(Links = rebuy$links, Nodes = rebuy$nodes, Source = "source",
              Target = "target", Value = "value", NodeID = "name",
              units = "TWh", fontSize = 30, nodeWidth = 30,
              fontFamily = "微软雅黑")

来看结果吧:

客户购买路径图

不能更丑了,已经。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容