数据源
第一章我们介绍了最基础的亲和性分析,尝试了所有的规则计算了所有的置信度和支持度,但是这个方法效率不高而且我们使用的数据集只有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算法)相关推荐

  1. [数据挖掘] 关联规则 Apriori算法实现到PFP(paralled frequent pattern)算法

    数据挖掘--关联规则与Apriori算法 1. 关联分析(Association analysis) 理解: 2. 相关概念 3. Apriori算法查找频繁项集 3.1 Apriori算法的原理: ...

  2. 利用weka进行数据挖掘——基于Apriori算法的关联规则挖掘实例

    文章目录 1. weka安装 2. 先分析一个Apriori算法的关联规则挖掘实例 3. 利用weka进行数据挖掘 3.1 将数据转为ARFF格式 3.2 利用weka进行分析 4. 参考文章 首先, ...

  3. 数据挖掘|关联规则Apriori算法详解及其在中医医案中的应用

    本文简单介绍传统数据挖掘关联规则算法中的Apriori算法,以及在挖掘中医医案辨证规律中的应用.并简单分析传统算法缺点,提出简要的改进思路. 文章目录 一.关联规则简介 二.Apriori算法简介 三 ...

  4. 数据挖掘关联规则Apriori算法

    以超市销售数据为例子,提取关联规则的最大困难在于当存在很多商品时,可能的商品的组合的数目会达到一种令人望而却步的程度.因而各种关联规则分析的算法从不同方面入手,以减少可能的搜索空间的大小以及减少扫描数 ...

  5. python数据分析 - 关联规则Apriori算法

    关联规则Apriori算法 导语 mlxtend实现Apriori算法 导语 关联规则: 是反映一个事物与其他事物之间的相互依存性和关联性 常用于实体商店或在线电商的推荐系统:通过对顾客的购买记录数据 ...

  6. Apriori算法介绍(Python实现)

    导读: 随着大数据概念的火热,啤酒与尿布的故事广为人知.我们如何发现买啤酒的人往往也会买尿布这一规律?数据挖掘中的用于挖掘频繁项集和关联规则的Apriori算法可以告诉我们.本文首先对Apriori算 ...

  7. apriori算法 python实现

    导读: 随着大数据概念的火热,啤酒与尿布的故事广为人知.我们如何发现买啤酒的人往往也会买尿布这一规律?数据挖掘中的用于挖掘频繁项集和关联规则的Apriori算法可以告诉我们.本文首先对Apriori算 ...

  8. 数据挖掘实验之Apriori算法

    数据挖掘实验Apriori算法,在指导书上看着写的,仅供参考. 数据集如下: 购物单号    购物项目 T1    1 3 4 T2    2 3 5 T3    1 2 3 5 T4    2 5 ...

  9. python晋江文学城数据分析——标签关联规则分析(Apriori算法+R语言)

    在学R语言购物篮分析,突然联想到虽然标签算不得商品,但和商品很相似,可以看看作者设置标签时喜欢把什么标签放一块.由于前文一直用的是python,所以准备接着用python,但是整体弄下来后,发现在可视 ...

  10. apriori算法代码python_Apriori算法原理及Python代码

    一.Apriori算法原理 参考:Python --深入浅出Apriori关联分析算法(一)​www.cnblogs.com 二.在Python中使用Apriori算法 查看Apriori算法的帮助文 ...

最新文章

  1. 推荐!最适合初学者的18个经典开源计算机视觉项目
  2. PHP多维数组转为一维数组的方法实例
  3. android 版本28 通知栏图标,【专题分析】应用图标、通知栏适配
  4. 漫画算法:最小栈的实现
  5. msflexgrid允许大选择_特大型矿井提升机结构和布置方式的选择
  6. CentOS 6.9编译安装新版本内核
  7. iOS HTML5的JS交互
  8. 【Gym - 100837 F】Controlled Tournament【竞赛树 状态压缩】
  9. Mac fliqlo 时钟屏保
  10. 计算机的硬盘配额如何更改,磁盘配额怎么设置
  11. linux firefox插件目录,Linux中Firefox常用插件说明
  12. 从0开始制作H5直播源码的教程
  13. 2019 虎鲸杯电子取证大赛赛后复盘总结
  14. 大数据学习笔记之一:Hadoop 常用指令集合与启动注意项
  15. 来自Naval Ravikant 的十句话
  16. 于 HTML5 WebGL 的民航客机飞行监控系统
  17. CSDN【精品专栏】第七期
  18. Mybatis-plus 代码生成器(新)
  19. 一分钟让你明白OKR考核
  20. 科技创业公司最爱的9大工具箱

热门文章

  1. 动态地图开发的未来应用场景有哪些?
  2. 错误使用 mex 未找到支持的编译器。您可以安装免费提供的 MinGW-w64 C/C++ 编译器;请参阅安装 MinGW-w64 编译器 (2)
  3. 苹果cms V10采集插件安装教程
  4. 【Scaled-YOLOv4】
  5. MySQL实现累计求和
  6. 滑动窗口,看这篇就够了(java)
  7. 【极客时间】《Java并发编程实战》学习笔记
  8. 数据结构: 一、数据结构概述
  9. 大学物理(上)-期末知识点结合习题复习(2)——运动的描述考点总结、质点运动学-牛顿运动定律
  10. AMiner论文推荐——3D Spatial Recognition without Spatially Labeled 3D