本文讲解的是机器学习中一个算法的应用:关联规则分析

整个故事从一张校园卡开始。相信小伙伴们都用过校园卡,它是一种其个人身份认证、校园消费、数据共享等多功能于一体的校园信息集成与管理系统。在它里面存储着大量的数据,包含:学生消费、宿舍门禁、图书馆进出等。

本文使用的是南京某高校学生一卡通在2019年4月1-20号的消费明细数据,从统计可视化分析、关联规则分析,发现学生一卡通的使用情况和学生当中的情侣、基友、闺蜜、渣男和单身狗等有趣信息。

使用的数据集地址如下:https://github.com/Nicole456/Analysis-of-students-consumption-behavior-on-campus

导入数据

import pandas as pd
import numpy as np
import datetime
import plotly_express as px
import plotly.graph_objects as go

1、数据1:每个学生的校园卡基本信息

2、数据2:校园卡每次消费和充值的明细数据

3、数据3:门禁明细数据

数据大小

In [8]:

print("df1: ", df1.shape)
print("df2: ", df2.shape)
print("df3: ", df3.shape)
df1:  (4341, 5)
df2:  (519367, 14)
df3:  (43156, 6)

缺失值

 # 每列缺失值
df1.isnull().sum()
# 每列的缺失值占比
df2.apply(lambda x : sum(x.isnull())/len(x), axis=0)

人数对比

不同性别人数

不同专业人数

In [16]:

df5 = df1["Major"].value_counts().reset_index()df5.columns = ["Major","Number"]
df5.head()

不同专业不同性别人数

In [18]:

df6 = df1.groupby(["Major","Sex"])["CardNo"].count().reset_index()
df6.head()

fig = px.treemap(df6,path=[px.Constant("all"),"Major","Sex"],  # 重点:传递数据路径values="CardNo",color="Major"   # 指定颜色变化的参数
)fig.update_traces(root_color="maroon")
# fig.update_traces(textposition="top right")
fig.update_layout(margin=dict(t=30,l=20,r=25,b=30))fig.show()

进出门禁信息

地址信息

In [21]:

# 1、处理addressaddress = df3["Address"].str.extract(r"(?P<Address_New>[\w]+)\[(?P<Out_In>[\w]+)\]")
address

进出门禁时间

In [25]:

df8 = pd.merge(df3,df1,on="AccessCardNo")
df8.loc[:,'Date'] = pd.to_datetime(df8.loc[:,'Date'],format='%Y/%m/%d %H:%M',errors='coerce')df8["Hour"] = df8["Date"].dt.hour
# df8["Minute"] = df8["Date"].dt.minute# 进出门禁人数统计/小时
df9 = df8.groupby(["Hour","Out_In"]).agg({"AccessCardNo":"count"}).reset_index()
df9.head()

# 准备画布
fig = go.Figure()# 添加不同的数据
fig.add_trace(go.Scatter(  x=df9.query("Out_In == '出门'")["Hour"].tolist(),y=df9.query("Out_In == '出门'")["AccessCardNo"].tolist(),mode='lines + markers', # mode模式选择name='出门')) # 名字fig.add_trace(go.Scatter(  x=df9.query("Out_In == '进门'")["Hour"].tolist(),y=df9.query("Out_In == '进门'")["AccessCardNo"].tolist(),mode='lines + markers', name='进门')) fig.show()

消费信息

In [30]:

# 数据合并  只取出两个字段:卡号和性别df10 = pd.merge(df2,df1[["CardNo","Sex"]],on="CardNo")

合并信息

In [32]:

df10["Card_Sex"] = df10["CardNo"].apply(lambda x: str(x)) + "_" + df10["Sex"]

主要地点

In [33]:

# Card_Sex:统计消费人次
# Money:统计消费金额df11 = (df10.groupby("Dept").agg({"Card_Sex":"count","Money":sum}).reset_index().sort_values("Money",ascending=False))df11.head(10)

fig = px.bar(df11,x="Dept",y="Card_Sex")
fig.update_layout(title_text='不同地方的消费人数',xaxis_tickangle=45) fig.show()

fig = px.bar(df11,x="Dept",y="Money")
fig.update_layout(title_text='不同地方的消费金额',xaxis_tickangle=45) fig.show()

关联规则挖掘

时间处理

时间处理主要是两个点:

  • 时间格式的转换

  • 时间离散化:每5分钟一个类型

在这里我们默认:如果两个时间在同一个类型中,认为两人在一起消费

import datetimedef change_time(x):# 转成标准时间格式result = str(datetime.datetime.strptime(x, "%Y/%m/%d %H:%M"))return resultdef time_five(x):# ‘2022-02-24 15:46:09’ ---> '2022-02-24 15_9'res1 = x.split(":")[0]res2 = str(round(int(x.split(":")[1]) / 5))return res1 + "_" + res2df10["New_Date"] = df10["Date"].apply(change_time)
df10["New_Date"] = df10["New_Date"].apply(time_five)
df10.head(3)

提起每个时间类型的人员信息:

# 方式1df11 = df10.groupby(["New_Date"])["Card_Sex"].apply(list).reset_index()
# 每个列表中的元素去重
df11["Card_Sex"] = df11["Card_Sex"].apply(lambda x: list(set(x)))
all_list = df11["Card_Sex"].tolist()# 方式2
# all_list = []
# for i in df10["New_Date"].unique().tolist():
#     lst = df10[df10["New_Date"] == i]["Card_Sex"].unique().tolist()
#     all_list.append(lst)

频繁项集寻找

In [44]:

import efficient_apriori as ea# itemsets:频繁项  rules:关联规则
itemsets, rules = ea.apriori(all_list,min_support=0.005,  min_confidence=1)

一个人

一个人消费的数据最多:2565条数据,单身毕竟多!

len(itemsets[1])  # 2565条# 部分数据
{('181539_男',): 52,('180308_女',): 47,('183262_女',): 100,('182958_男',): 88,('180061_女',): 83,('182936_男',): 80,('182931_男',): 87,('182335_女',): 60,('182493_女',): 75,('181944_女',): 67,('181058_男',): 93,('183391_女',): 63,('180313_女',): 82,('184275_男',): 69,('181322_女',): 104,('182391_女',): 57,('184153_女',): 31,('182711_女',): 40,('181594_女',): 36,('180193_女',): 84,('184263_男',): 61,

两个人

len(itemsets[2])  # 378条

查看了全部的数据,统计了下面的结果:

('180433_男', '180499_女'): 34
# 可疑渣男1
('180624_男', '181013_女'): 36,
('180624_男', '181042_女'): 37,
# 可疑渣男2
('181461_男', '180780_女'): 38,
('181461_男', '180856_女'): 34,('181597_男', '183847_女'): 44,('181699_男', '181712_女'): 31,('181889_男', '180142_女'): 33,
# 可疑渣男3:NB
('182239_男', '182304_女'): 39,
('182239_男', '182329_女'): 40,
('182239_男', '182340_女'): 37,
('182239_男', '182403_女'): 35,('182873_男', '182191_女'): 31,('183343_男', '183980_女'): 44,

1、可疑男生1-180624

回到原始数据,查看他和不同女生在时间上消费的交集情况。

(1)和女生181013的交集:

  • 4月1号早上7.36:应该是一起吃了早餐;11点54一起吃了午饭

  • 4.10、4.12等不同时间点的交集

(2)和女生181042的交集:

2、看看可疑的渣男3

这哥们实在是厉害呀~数据挖掘显示居然和4个女生同时存在一定的关联!

('182239_男', '182304_女'): 39
('182239_男', '182329_女'): 40
('182239_男', '182340_女'): 37
('182239_男', '182403_女'): 35

除了可能的男女朋友关系,在2元数据中更多的是基友或者闺蜜:

('180450_女', '180484_女'): 35,
('180457_女', '180493_女'): 31,
('180460_女', '180496_女'): 31,
('180493_女', '180500_女'): 47,
('180504_女', '180505_女'): 43,
('180505_女', '180506_女'): 35,
('180511_女', '181847_女'): 42,
('180523_男', '182415_男'): 34,
('180526_男', '180531_男'): 33,
('180545_女', '180578_女'): 41,
('180545_女', '180615_女'): 47,
('180551_女', '180614_女'): 31,
('180555_女', '180558_女'): 36,
('180572_女', '180589_女'): 31,
('181069_男', '181103_男'): 44,
('181091_男', '181103_男'): 33,
('181099_男', '181102_男'): 31,
('181099_男', '181107_男'): 34,
('181102_男', '181107_男'): 35,
('181112_男', '181117_男'): 43,
('181133_男', '181136_男'): 52,
('181133_男', '181571_男'): 45,
('181133_男', '181582_男'): 33,

3-4个人

3-4元的数据可能是一个宿舍的同学或者朋友一起的,相对数量会比较少:

len(itemsets[3])  # 18条{('180363_女', '181876_女', '183979_女'): 40,('180711_女', '180732_女', '180738_女'): 35,('180792_女', '180822_女', '180849_女'): 35,('181338_男', '181343_男', '181344_男'): 40,('181503_男', '181507_男', '181508_男'): 33,('181552_男', '181571_男', '181582_男'): 39,('181556_男', '181559_男', '181568_男'): 35,('181848_女', '181865_女', '181871_女'): 35,('182304_女', '182329_女', '182340_女'): 36,('182304_女', '182329_女', '182403_女'): 32,('183305_女', '183308_女', '183317_女'): 32,('183419_女', '183420_女', '183422_女'): 49,('183419_女', '183420_女', '183424_女'): 45,('183419_女', '183422_女', '183424_女'): 48,('183420_女', '183422_女', '183424_女'): 51,('183641_女', '183688_女', '183690_女'): 32,('183671_女', '183701_女', '183742_女'): 35,('183713_女', '183726_女', '183737_女'): 36}

4元数据只有一条:

总结

关联规则分析是一个经典数据挖掘算法,在消费明细数据、超市购物篮数据、金融保险、信用卡等领域应用的十分广泛。

当我们运用关联分析技术挖掘出频繁出现的组合和强关联规则之后,就可以指定相应的营销策略或者找到不同对象之间的关系。

上面的数据挖掘过程,其实也存在一定的缺陷:

完整代码点这里获取

  • 约束太宽:仅仅是根据时间间隔类型进行分组统计,忽略了学生的专业、消费地点等信息

  • 时间太窄:5分钟的时间间隔过去窄,会过滤掉很多信息

Python关联规则挖掘情侣、基友、渣男和狗。学会这个就非常牛逼了。相关推荐

  1. 【机器学习】情侣、基友、渣男和狗-基于时空关联规则的影子账户挖掘

    故事从校园一卡通开始,校园一卡通是集身份认证.金融消费.数据共享等多项功能于一体的信息集成系统,也就是学生卡.积累了大量的历史记录,其中蕴含着学生的消费行为和财务状况等信息.是一个数据分析比赛的数据, ...

  2. 情侣、基友、渣男和狗-基于时空关联规则的影子账户挖掘

    故事从校园一卡通开始,校园一卡通是集身份认证.金融消费.数据共享等多项功能于一体的信息集成系统,也就是学生卡.积累了大量的历史记录,其中蕴含着学生的消费行为和财务状况等信息.是一个数据分析比赛的数据, ...

  3. 【干货+福利】情侣、基友、渣男和狗-基于SynchroTrap+LPA算法的团伙账户挖掘

    本文目的:把经常一起行动的人找出来,并划分成一个Group,仅利用时间关系,无需其他介质 上一期的文章,没有解决相隔时间近但是不在同一个5min切片内的的问题,为了解决这个问题,我研究了一些关于时序的 ...

  4. python关联规则挖掘_python数据挖掘 pycaret.arules 关联规则学习

    1.关联算法应用介绍 关联规则分析是数据挖掘中最活跃的研究方法之一,目的是在一个数据集中找出各项之间的关联关系,而这种关系并没有在数据中直接表示出来.常见于与购物篮分析. 常用关联算法表如下,简单理解 ...

  5. python关联规则挖掘_Python3:文本关联规则挖掘实现案例分析

    支持度 Support(支持度):表示同时包含A和B的事务占所有事务的比例.如果用P(A)表示使用A事务的比例,那么Support=P(A&B) 苍天不负有心人啊,我玩了两三个周的文本挖掘,终 ...

  6. ㊙️【教你用python挣零花钱】自动化简历内推,学弟直呼牛逼!!

    最近,小编在处理简历时,发现大量简历需要一个个打开文件,复制姓名.邮箱.电话号码.学历等关键信息,效率特别低且部分文件无法直接复制.于是,小编便写了简历解析处理的脚本,支持文件格式有:doc,docx ...

  7. 详解python实现FP-TREE进行关联规则挖掘(带有FP树显示功能)附源代码下载(3)

    详解python实现FP-TREE进行关联规则挖掘(带有FP树显示功能)附源代码下载(3) 上一节简单讲了下FP树的生成,在这一节我将描述FP树的挖掘过程. 首先我们回顾一下要挖掘的特征项及样本空间: ...

  8. 【Python数据挖掘课程笔记】八.关联规则挖掘及Apriori实现购物推荐

    #2018-03-23 10:48:40 March Friday the 12 week, the 082 day SZ SSMR[Python数据挖掘课程笔记]八.关联规则挖掘及Apriori实现 ...

  9. 渣男,你为什么有这么多小姐姐的照片?因为我Python爬虫学的好啊❤️!

    渣男,你为什么有这么多小姐姐的照片?因为我Python爬虫学的好啊❤️! 前言 程序说明 爬虫程序 观察网页结构 页面解析 创建图片保存路径 图片下载 爬取结果展示 完整程序 最后 前言 大家心心念的 ...

最新文章

  1. 导师:寒假复现几篇顶会论文?答:3天1篇!
  2. 水准网测量平差matlab_【干货】史诗级测量大神分享道路测量全过程经验
  3. Btrace详细指南(JDK7,监控HashMap扩容)
  4. [译】Diving Into The Ethereum VM
  5. linux complete函数,Linux驱动中completion接口浅析(wait_for_complete例子,很好)
  6. c语言课程设计修改订单流程图,C语言课程设计————写下流程图! 谢谢
  7. LeetCode 863. 二叉树中所有距离为 K 的结点(公共祖先/ DFS+BFS)
  8. 打败 IE 的葵花宝典:CSS Bug Table
  9. maven项目pom.xml中parent标签的使用
  10. 学建模从软件开始,8款超级好用的3d建模软件(内有安装包领取途径)
  11. Android:Glide异步加载图片,设置默认图片和错误图片
  12. 有些MP4只有音频没有视频的解决办法
  13. python 爬取海量网易云评论并写入数据库
  14. 野路子玩Qt,第十集,八音盒
  15. 在keil MDK中定义非初始化(noini)变量
  16. 什么是CF , correlation filer ? 【无标题】
  17. 无处不在_电动汽车无处不在。 那丰田为什么还要继续投资氢呢?
  18. 视频监控网络传输计算方法
  19. 网络爬虫---用urllib模块爬取京东笔记本电脑的数据、并对其做一个可视化
  20. %f在c语言中是什么意思,在C语言中,%d,%c,%f都是什么意思,请详细的说一下,谢谢了...

热门文章

  1. sqlserver调用mysql存储过程_sqlserver里存储过程怎么调用存储过程
  2. 案例:华为FusionInsight_HD 低配版(三台)安装实例 -- 手动安装
  3. LFU缓存算法及Java实现
  4. http跨域时的options请求
  5. 华米科技Amazfit智能手表荣获2019年iF设计大奖
  6. 洞见数字时代的创新原力,数云原力大会暨2023TECH第五届数字中国技术年会开幕
  7. 另一个小程序 返回的支付结果如何得到_都火遍全球了,你却还在为电商支付功能开发犯难...
  8. java mysql重要吗_干了三年的Java,你竟然还不会MySQL性能优化
  9. 自然语言处理NLP星空智能对话机器人系列:深入理解Transformer自然语言处理 Workshop on Machine Translation (WMT)
  10. php怎么运行网页_「Dev」 - PHP运行环境