python数据挖掘(5.Apriori算法)
数据源
第一章我们介绍了最基础的亲和性分析,尝试了所有的规则计算了所有的置信度和支持度,但是这个方法效率不高而且我们使用的数据集只有5种商品,但是实际生活中即使是小商店的商品也会超过百种,而网店商品的种类则可能更多,依旧使用第一章的亲和性分析,那么随着商品数量的增加,计算量和计算的时间也会急剧增加,所以需要一个聪明的算法来解决这个问题
Apriori算法
Apriori算法诗一个景点的亲和性分析算法,他只从数据集中频繁出现的商品中选取共同出现的商品组成频繁项集,避免上述复杂度呈指数级增长的问题,一旦找到了频繁项集,生成关联规则就很容易了。
Apriori算法首先保证规则在数据集中有足够的支持度,最重要的一个参数就是最小支持度比如要生成商品A B的频繁项集(A,B)要求支持度至少为30,那么A,B都必须至少在数据集中出现30次,更大的频繁项集也要最受这个约定。
这一章我们通过电影推荐的问题来举例。
数据集地址在文章开头
In [1]: import numpy as np In [2]: import pandas as pd In [3]: all_ratings = pd.read_csv('/Users/gn/scikit--learn/ml-100k/u.data',delim...: iter="\t", header=None, names = ["UserID", "MovieID", "Rating", "Datetim...: e"]) In [4]: all_ratings.head()
Out[4]: UserID MovieID Rating Datetime
0 196 242 3 881250949
1 186 302 3 891717742
2 22 377 1 878887116
3 244 51 2 880606923
4 166 346 1 886397596In [5]: all_ratings["Datetime"] = pd.to_datetime(all_ratings['Datetime'],unit='s...: ') In [6]: all_ratings["Favorable"] = all_ratings['Rating'] > 3 In [7]: ratings = all_ratings[all_ratings['UserID'].isin(range(200))] In [8]: ratings.head()
Out[8]: UserID MovieID Rating Datetime Favorable
0 196 242 3 1997-12-04 15:55:49 False
1 186 302 3 1998-04-04 19:22:22 False
2 22 377 1 1997-11-07 07:18:36 False
4 166 346 1 1998-02-02 05:33:16 False
6 115 265 2 1997-12-03 17:51:28 FalseIn [9]: favorable_ratings = ratings[ratings["Favorable"]] In [10]: favorable_ratings.groupby("UserID")["MovieID"]
Out[10]: <pandas.core.groupby.generic.SeriesGroupBy object at 0x11583d9b0>In [11]: favorable_reviews_by_users = dict((k, frozenset(v.values)) for k, v in favorable_ratings.groupby("UserID")["MovieID"]) In [12]: num_favorable_by_movie = ratings[["MovieID", "Favorable"]].groupby("MovieID").sum() In [13]: num_favorable_by_movie.sort_values('Favorable',ascending=False).head()
Out[13]: Favorable
MovieID
50 100.0
100 89.0
258 83.0
181 79.0
174 74.0In [14]: from collections import defaultdict In [15]: frequent_itemsets = {} In [16]: min_support = 50 In [17]: frequent_itemsets[1] = dict((frozenset((movie_id,)), row["Favorable"]) for movie_id,row in num_favorable_by_movie[num_favorable_by_movie['Favorable']>50].iterrows()) In [18]: import sys In [19]: print("有 {} 部电影 获得超过 {} 个好评".format(len(frequent_itemsets[1]), min_support))
有 16 部电影 获得超过 50 个好评
上线一段代码我们读取了数据,获得了一些基本的信息。
下面我们来寻找‘频繁项集’
In [20]: def find_frequent_itemsets(favorable_reviews_by_users, k_1_itemsets, min_support): ...: counts = defaultdict(int) ...: for user,reviews in favorable_reviews_by_users.items(): ...: for itemset in k_1_itemsets: ...: if itemset.issubset(reviews): ...: for other_reviewed_movie in reviews - itemset: ...: current_superset = itemset | frozenset((other_reviewed_movie,)) ...: counts[current_superset] += 1 ...: return dict([(itemset, frequency) for itemset, frequency in counts.items() if frequency >= min_support]) ...: In [21]: for k in range(2, 20): ...: cur_frequent_itemsets = find_frequent_itemsets(favorable_reviews_by_users, frequent_itemsets[k-1],min_support) ...: if len(cur_frequent_itemsets) == 0: ...: print("未发现频数为{}的频繁项集".format(k)) ...: sys.stdout.flush() ...: break ...: else: ...: print("发现 {} 个长度为 {}的频繁项集".format(len(cur_frequent_itemsets), k)) ...: sys.stdout.flush() ...: frequent_itemsets[k] = cur_frequent_itemsets ...:
发现 93 个长度为 2的频繁项集
发现 295 个长度为 3的频繁项集
发现 593 个长度为 4的频繁项集
发现 785 个长度为 5的频繁项集
发现 677 个长度为 6的频繁项集
发现 373 个长度为 7的频繁项集
发现 126 个长度为 8的频繁项集
发现 24 个长度为 9的频繁项集
发现 2 个长度为 10的频繁项集
未发现频数为11的频繁项集
Apriori算法结束后我们得到了一些列频繁项集,这还不算是真正意义上的关联规则,但是很接近。频繁相机是一组达到最小支持度的项目,而关联规则由前提和结论组成。
我们从拼房相机中抽取出关联规则,把其中几部电影作为前提,另一部电影作为结论生成如下形式的规则:“如果用户喜欢前提中的电影,那么他们也会喜欢结论中的电影”
下面我们看一下哪些规则的置信度比较高
In [22]: del frequent_itemsets[1] In [23]: candidate_rules = [] In [24]: for itemset_length, itemset_counts in frequent_itemsets.items(): ...: for itemset in itemset_counts.keys(): ...: for conclusion in itemset: ...: premise = itemset - set((conclusion,)) ...: candidate_rules.append((premise, conclusion)) ...: print("生成 {} 条规则 ".format(len(candidate_rules)))
生成 15285 条规则 In [25]: correct_counts = defaultdict(int) In [26]: incorrect_counts = defaultdict(int) In [27]: for user, reviews in favorable_reviews_by_users.items(): ...: for candidate_rule in candidate_rules: ...: premise, conclusion = candidate_rule ...: if premise.issubset(reviews): ...: if conclusion in reviews: ...: correct_counts[candidate_rule] += 1 ...: else: ...: incorrect_counts[candidate_rule] += 1 ...: rule_confidence = {candidate_rule: correct_counts[candidate_rule] / float(correct_counts[candidate_rule] + incorrect_counts[candidate_rule]) ...: for candidate_rule in candidate_rules} In [28]: min_confidence = 0.9 In [29]: rule_confidence = {rule: confidence for rule, confidence in rule_confidence.items() if confidence > min_confidence} ...: print(len(rule_confidence))
5152In [30]: from operator import itemgetter In [31]: sorted_confidence = sorted(rule_confidence.items(), key=itemgetter(1), reverse=True) In [32]: for index in range(5): ...: print("规则 #{0}".format(index + 1)) ...: (premise, conclusion) = sorted_confidence[index][0] ...: print("规则: 如果有人喜欢电影 {0} 那么他们同样喜欢电影 {1}".format(premise, conclusion)) ...: print(" - 置信度: {0:.3f}".format(rule_confidence[(premise, conclusion)])) ...: print("") ...:
规则 #1
规则: 如果有人喜欢电影 frozenset({98, 181}) 那么他们同样喜欢电影 50- 置信度: 1.000规则 #2
规则: 如果有人喜欢电影 frozenset({172, 79}) 那么他们同样喜欢电影 174- 置信度: 1.000规则 #3
规则: 如果有人喜欢电影 frozenset({258, 172}) 那么他们同样喜欢电影 174- 置信度: 1.000规则 #4
规则: 如果有人喜欢电影 frozenset({1, 181, 7}) 那么他们同样喜欢电影 50- 置信度: 1.000规则 #5
规则: 如果有人喜欢电影 frozenset({1, 172, 7}) 那么他们同样喜欢电影 174- 置信度: 1.000
我们一共生成了15285条规则,之后创建两个字典,一个存储符合规则(correct_counts),另一个储存不符合规则(incorrect_counts),循环我们的数据计算符合和不符合规则的数量,并且计算置信度,最后我们拿出了置信度前五个的规则。
现在结果只显示了电影编号,我们的数据中还有一部分电影信息。下面我们将这部分加进来
In [41]: movie_name_data = pd.read_csv('/Users/gn/scikit--learn/ml-100k/u.item',delimiter='|',header=None,encoding='mac-roman') In [42]: movie_name_data.head()
Out[42]: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
0 1 Toy Story (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Toy%20Story%2... 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 2 GoldenEye (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?GoldenEye%20(... 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
2 3 Four Rooms (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Four%20Rooms%... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
3 4 Get Shorty (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Get%20Shorty%... 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0
4 5 Copycat (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Copycat%20(1995) 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0In [43]: movie_name_data.columns = ["MovieID", "Title", "Release Date", "Video Release", "IMDB", "<UNK>", "Action", "Adventure", ...: "Animation", "Children's", "Comedy", "Crime", "Documentary", "Drama", "Fantasy", "Film-Noir", ...: "Horror", "Musical", "Mystery", "Romance", "Sci-Fi", "Thriller", "War", "Western"] In [44]: movie_name_data.head()
Out[44]: MovieID Title Release Date Video Release IMDB <UNK> Action ... Musical Mystery Romance Sci-Fi Thriller War Western
0 1 Toy Story (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Toy%20Story%2... 0 0 ... 0 0 0 0 0 0 0
1 2 GoldenEye (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?GoldenEye%20(... 0 1 ... 0 0 0 0 1 0 0
2 3 Four Rooms (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Four%20Rooms%... 0 0 ... 0 0 0 0 1 0 0
3 4 Get Shorty (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Get%20Shorty%... 0 1 ... 0 0 0 0 0 0 0
4 5 Copycat (1995) 01-Jan-1995 NaN http://us.imdb.com/M/title-exact?Copycat%20(1995) 0 0 ... 0 0 0 0 1 0 0[5 rows x 24 columns]In [45]: def get_movie_name(movie_id): ...: title_object = movie_name_data[movie_name_data["MovieID"] == movie_id]["Title"] ...: title = title_object.values[0] ...: return title ...: In [46]: for index in range(5): ...: print("规则 #{0}".format(index + 1)) ...: (premise, conclusion) = sorted_confidence[index][0] ...: premise_names = ", ".join(get_movie_name(idx) for idx in premise) ...: conclusion_name = get_movie_name(conclusion) ...: print("规则: 如果有人喜欢电影 {0}那么他们同样喜欢电影 {1}".format(premise_names, conclusion_name)) ...: print(" - 置信度: {0:.3f}".format(rule_confidence[(premise, conclusion)])) ...: print("") ...:
规则 #1
规则: 如果有人喜欢电影 Silence of the Lambs, The (1991), Return of the Jedi (1983)那么他们同样喜欢电影 Star Wars (1977)- 置信度: 1.000规则 #2
规则: 如果有人喜欢电影 Empire Strikes Back, The (1980), Fugitive, The (1993)那么他们同样喜欢电影 Raiders of the Lost Ark (1981)- 置信度: 1.000规则 #3
规则: 如果有人喜欢电影 Contact (1997), Empire Strikes Back, The (1980)那么他们同样喜欢电影 Raiders of the Lost Ark (1981)- 置信度: 1.000规则 #4
规则: 如果有人喜欢电影 Toy Story (1995), Return of the Jedi (1983), Twelve Monkeys (1995)那么他们同样喜欢电影 Star Wars (1977)- 置信度: 1.000规则 #5
规则: 如果有人喜欢电影 Toy Story (1995), Empire Strikes Back, The (1980), Twelve Monkeys (1995)那么他们同样喜欢电影 Raiders of the Lost Ark (1981)- 置信度: 1.000
我们可以拿评估分类算法的那一套来用,训练前,流出一部分数据用作测试,评估发现的规则在测试集上的表现。和之前是差不多的。
In [47]: test_dataset = all_ratings[~all_ratings['UserID'].isin(range(200))] In [48]: test_favorable = test_dataset[test_dataset["Favorable"]] In [49]: test_favorable_by_users = dict((k, frozenset(v.values)) for k, v in test_favorable.groupby("UserID")["MovieID"]) In [50]: test_dataset.head()
Out[50]: UserID MovieID Rating Datetime Favorable
3 244 51 2 1997-11-27 05:02:03 False
5 298 474 4 1998-01-07 14:20:06 True
7 253 465 5 1998-04-03 18:34:27 True
8 305 451 3 1998-02-01 09:20:17 False
11 286 1014 5 1997-11-17 15:38:45 TrueIn [51]: correct_counts = defaultdict(int) ...: incorrect_counts = defaultdict(int) ...: for user, reviews in test_favorable_by_users.items(): ...: for candidate_rule in candidate_rules: ...: premise, conclusion = candidate_rule ...: if premise.issubset(reviews): ...: if conclusion in reviews: ...: correct_counts[candidate_rule] += 1 ...: else: ...: incorrect_counts[candidate_rule] += 1 ...: In [52]: test_confidence = {candidate_rule: correct_counts[candidate_rule] / float(correct_counts[candidate_rule] + incorrect_counts[candidate_rule]) ...: for candidate_rule in rule_confidence} In [53]: sorted_test_confidence = sorted(test_confidence.items(), key=itemgetter(1), reverse=True) In [54]: for index in range(10): ...: print("规则 #{0}".format(index + 1)) ...: (premise, conclusion) = sorted_confidence[index][0] ...: premise_names = ", ".join(get_movie_name(idx) for idx in premise) ...: conclusion_name = get_movie_name(conclusion) ...: print("规则:如果有人喜欢电影 {0} 那么他们同样喜欢电影 {1}".format(premise_names, conclusion_name)) ...: print(" - 训练 置信度: {0:.3f}".format(rule_confidence.get((premise, conclusion), -1))) ...: print(" - 测试 置信度: {0:.3f}".format(test_confidence.get((premise, conclusion), -1))) ...: print("") ...:
规则 #1
规则:如果有人喜欢电影 Silence of the Lambs, The (1991), Return of the Jedi (1983) 那么他们同样喜欢电影 Star Wars (1977)- 训练 置信度: 1.000- 测试 置信度: 0.936规则 #2
规则:如果有人喜欢电影 Empire Strikes Back, The (1980), Fugitive, The (1993) 那么他们同样喜欢电影 Raiders of the Lost Ark (1981)- 训练 置信度: 1.000- 测试 置信度: 0.876规则 #3
规则:如果有人喜欢电影 Contact (1997), Empire Strikes Back, The (1980) 那么他们同样喜欢电影 Raiders of the Lost Ark (1981)- 训练 置信度: 1.000- 测试 置信度: 0.841规则 #4
规则:如果有人喜欢电影 Toy Story (1995), Return of the Jedi (1983), Twelve Monkeys (1995) 那么他们同样喜欢电影 Star Wars (1977)- 训练 置信度: 1.000- 测试 置信度: 0.932规则 #5
规则:如果有人喜欢电影 Toy Story (1995), Empire Strikes Back, The (1980), Twelve Monkeys (1995) 那么他们同样喜欢电影 Raiders of the Lost Ark (1981)- 训练 置信度: 1.000- 测试 置信度: 0.903规则 #6
规则:如果有人喜欢电影 Pulp Fiction (1994), Toy Story (1995), Star Wars (1977) 那么他们同样喜欢电影 Raiders of the Lost Ark (1981)- 训练 置信度: 1.000- 测试 置信度: 0.816规则 #7
规则:如果有人喜欢电影 Pulp Fiction (1994), Toy Story (1995), Return of the Jedi (1983) 那么他们同样喜欢电影 Star Wars (1977)- 训练 置信度: 1.000- 测试 置信度: 0.970规则 #8
规则:如果有人喜欢电影 Toy Story (1995), Silence of the Lambs, The (1991), Return of the Jedi (1983) 那么他们同样喜欢电影 Star Wars (1977)- 训练 置信度: 1.000- 测试 置信度: 0.933规则 #9
规则:如果有人喜欢电影 Toy Story (1995), Empire Strikes Back, The (1980), Return of the Jedi (1983) 那么他们同样喜欢电影 Star Wars (1977)- 训练 置信度: 1.000- 测试 置信度: 0.971规则 #10
规则:如果有人喜欢电影 Pulp Fiction (1994), Toy Story (1995), Shawshank Redemption, The (1994) 那么他们同样喜欢电影 Silence of the Lambs, The (1991)- 训练 置信度: 1.000- 测试 置信度: 0.794
从大量的电影打分数据中找到可以用于电影推荐的关联规则,整个过程分为2大阶段,首先借助Apriori算法寻找频繁项集,然后生成相关规则,再计算置信度。
python数据挖掘(5.Apriori算法)相关推荐
- [数据挖掘] 关联规则 Apriori算法实现到PFP(paralled frequent pattern)算法
数据挖掘--关联规则与Apriori算法 1. 关联分析(Association analysis) 理解: 2. 相关概念 3. Apriori算法查找频繁项集 3.1 Apriori算法的原理: ...
- 利用weka进行数据挖掘——基于Apriori算法的关联规则挖掘实例
文章目录 1. weka安装 2. 先分析一个Apriori算法的关联规则挖掘实例 3. 利用weka进行数据挖掘 3.1 将数据转为ARFF格式 3.2 利用weka进行分析 4. 参考文章 首先, ...
- 数据挖掘|关联规则Apriori算法详解及其在中医医案中的应用
本文简单介绍传统数据挖掘关联规则算法中的Apriori算法,以及在挖掘中医医案辨证规律中的应用.并简单分析传统算法缺点,提出简要的改进思路. 文章目录 一.关联规则简介 二.Apriori算法简介 三 ...
- 数据挖掘关联规则Apriori算法
以超市销售数据为例子,提取关联规则的最大困难在于当存在很多商品时,可能的商品的组合的数目会达到一种令人望而却步的程度.因而各种关联规则分析的算法从不同方面入手,以减少可能的搜索空间的大小以及减少扫描数 ...
- python数据分析 - 关联规则Apriori算法
关联规则Apriori算法 导语 mlxtend实现Apriori算法 导语 关联规则: 是反映一个事物与其他事物之间的相互依存性和关联性 常用于实体商店或在线电商的推荐系统:通过对顾客的购买记录数据 ...
- Apriori算法介绍(Python实现)
导读: 随着大数据概念的火热,啤酒与尿布的故事广为人知.我们如何发现买啤酒的人往往也会买尿布这一规律?数据挖掘中的用于挖掘频繁项集和关联规则的Apriori算法可以告诉我们.本文首先对Apriori算 ...
- apriori算法 python实现
导读: 随着大数据概念的火热,啤酒与尿布的故事广为人知.我们如何发现买啤酒的人往往也会买尿布这一规律?数据挖掘中的用于挖掘频繁项集和关联规则的Apriori算法可以告诉我们.本文首先对Apriori算 ...
- 数据挖掘实验之Apriori算法
数据挖掘实验Apriori算法,在指导书上看着写的,仅供参考. 数据集如下: 购物单号 购物项目 T1 1 3 4 T2 2 3 5 T3 1 2 3 5 T4 2 5 ...
- python晋江文学城数据分析——标签关联规则分析(Apriori算法+R语言)
在学R语言购物篮分析,突然联想到虽然标签算不得商品,但和商品很相似,可以看看作者设置标签时喜欢把什么标签放一块.由于前文一直用的是python,所以准备接着用python,但是整体弄下来后,发现在可视 ...
- apriori算法代码python_Apriori算法原理及Python代码
一.Apriori算法原理 参考:Python --深入浅出Apriori关联分析算法(一)www.cnblogs.com 二.在Python中使用Apriori算法 查看Apriori算法的帮助文 ...
最新文章
- Cubieboard ARM 集群
- 关于CI的服务器与最佳实践,这里有一些思考 1
- C++ 标准库类型 set
- 微信OAuth2.0网页授权设置一个域名需多个域名使用的问题
- Linux内核分析— —计算机是如何工作的(20135213林涵锦)
- 学习爬虫限时只需9.9,还在犹豫什么?
- 2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem(把1到n分为不互质的数对,找最多的对数)
- python web自动化测试实验报告_Python:web自动化测试
- 10 个十分难得的 javascript 开发经验
- Linux清mysql磁盘,mysql与linux ~ 磁盘分析与调优
- php知识点汇总与解答_PHP操作员能力倾向问题与解答
- 算法与数据结构(六):堆排序
- BT.601与BT.656
- 二级缓存:EHCache的使用
- s一般怎么称呼自己的m_上海平面设计工资一般是多少,我该怎么提升自己的平面设计能力?...
- ANDROID中使用开源框架CITYPICKERVIEW实现省市区三级联动选择
- 翻译:Swift中的Operations和OperationQueues入门
- 一个完整的测试计划模板
- JavaScript知识梳理总结
- Modern Radar for Automotive Applications(用于汽车应用的现代雷达)