数据源
第一章我们介绍了最基础的亲和性分析,尝试了所有的规则计算了所有的置信度和支持度,但是这个方法效率不高而且我们使用的数据集只有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. Cubieboard ARM 集群
  2. 关于CI的服务器与最佳实践,这里有一些思考 1
  3. C++ 标准库类型 set
  4. 微信OAuth2.0网页授权设置一个域名需多个域名使用的问题
  5. Linux内核分析— —计算机是如何工作的(20135213林涵锦)
  6. 学习爬虫限时只需9.9,还在犹豫什么?
  7. 2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem(把1到n分为不互质的数对,找最多的对数)
  8. python web自动化测试实验报告_Python:web自动化测试
  9. 10 个十分难得的 javascript 开发经验
  10. Linux清mysql磁盘,mysql与linux ~ 磁盘分析与调优
  11. php知识点汇总与解答_PHP操作员能力倾向问题与解答
  12. 算法与数据结构(六):堆排序
  13. BT.601与BT.656
  14. 二级缓存:EHCache的使用
  15. s一般怎么称呼自己的m_上海平面设计工资一般是多少,我该怎么提升自己的平面设计能力?...
  16. ANDROID中使用开源框架CITYPICKERVIEW实现省市区三级联动选择
  17. 翻译:Swift中的Operations和OperationQueues入门
  18. 一个完整的测试计划模板
  19. JavaScript知识梳理总结
  20. Modern Radar for Automotive Applications(用于汽车应用的现代雷达)

热门文章

  1. win7计算机信息服务,Win7怎么打开系统服务?Win7查看系统服务信息方法
  2. Sitecore 随笔
  3. 上新!欧洲柔性密集仓储机器人
  4. Tarjan算法:重边的影响及跑有向图和无向图的区别
  5. python 美化ppt_2018年python制作ppt-word范文 (17页)
  6. 拉普拉斯------拉普拉斯算子
  7. 物联网的体系结构、关键技能、结点分类和发展趋势
  8. 西门子s7 200smart与台达变频器485通讯
  9. 京东新成立一家旅行社公司,对旅行社有什么启示?
  10. 设置字体同时为粗体、斜体