apriori推荐算法
大数据时代开始流行推荐算法,所以作者写了一篇教程来介绍apriori推荐算法。
推荐算法大致分为:
- 基于物品和用户本身
- 基于关联规则
- 基于模型的推荐
基于物品和用户本身
基于物品和用户本身的,这种推荐引擎将每个用户和每个物品都当作独立的实体,预测每个用户对于每个物品的喜好程度,这些信息往往是用一个二维矩阵描述的。由于用户感兴趣的物品远远小于总物品的数目,这样的模型导致大量的数据空置,即我们得到的二维矩阵往往是一个很大的稀疏矩阵。同时为了减小计算量,我们可以对物品和用户进行聚类, 然后记录和计算一类用户对一类物品的喜好程度,但这样的模型又会在推荐的准确性上有损失。
基于关联规则
基于关联规则的推荐(Rule-based Recommendation):关联规则的挖掘已经是数据挖掘中的一个经典的问题,主要是挖掘一些数据的依赖关系,典型的场景就是“购物篮问题”,通过关联规则的挖掘,我们可以找到哪些物品经常被同时购买,或者用户购买了一些物品后通常会购买哪些其他的物品,当我们挖掘出这些关联规则之后,我们可以基于这些规则给用户进行推荐。
基于模型的推荐
基于模型的推荐(Model-based Recommendation):这是一个典型的机器学习的问题,可以将已有的用户喜好信息作为训练样本,训练出一个预测用户喜好的模型,这样以后用户在进入系统,可以基于此模型计算推荐。这种方法的问题在于如何将用户实时或者近期的喜好信息反馈给训练好的模型,从而提高推荐的准确度。
其实在现在的推荐系统中,很少有只使用了一个推荐策略的推荐引擎,一般都是在不同的场景下使用不同的推荐策略从而达到最好的推荐效果,例如 Amazon 的推荐,它将基于用户本身历史购买数据的推荐,和基于用户当前浏览的物品的推荐,以及基于大众喜好的当下比较流行的物品都在不同的区域推荐给用户,让用户可以从全方位的推荐中找到自己真正感兴趣的物品。探索推荐引擎内部的秘密,第 1 部分: 推荐引擎初探
Apriori算法 是一种最有影响力的 挖掘布尔关联规则 的频繁项集的算法,这个算法是属于上面第二条基于关联规则
推荐的算法,本文着重讲解该算法的计算。
按照网上最简单的例子来进行分析:
支持度support=P(AB),指的是事件A和事件B同时发生的概率。
置信度confidence=P(B|A)=P(AB)/P(A),指的是发生事件A的基础上发生事件B的概率。
大致步骤为:
扫描
->计数
->剪枝
->频繁集
->强规则
扫描
扫描候选项集,并将所有的种类汇总,上图可知有种类["A","B","C","D","E"]
计数
计数即统计种类的个数,上图可知:{'A': 2, 'C': 3, 'D': 1, 'E': 3, 'B': 3}
剪枝
剪枝就是把不满足支持度的部分给去掉,支持度自己设定,上图第一次剪枝去掉了D,那么数据库中的所有D也要被去掉,即下次计算不被包含
频繁集
第一次剪枝后就得到了第一个频繁集L1,L1还能继续压缩,所以继续重复前面的几个步骤,直到无法再压缩
前面这些步骤用python写了代码如下:
# !/usr/bin/python3.4
# -*- coding: utf-8 -*-
# 获取所有元素种类
def getkinds(array):
arr = []
for item in array:
for value in item:
if value in arr:
pass
else:
if value != "+":
arr.append(value)
return arr
# 候选集长度
def getcount(array, support):
# 第一次扫描
# C1
dict = {}
for item in array:
for key in item:
if key in dict.keys():
dict[key] += 1
else:
dict[key] = 1
# 第一次剪枝
newdict = judge_spport(dict, support)
# 第二次扫描
# 构造项集C2
# 两两组合
arr = []
kinds = getkinds(newdict.keys())
for m in range(0, len(kinds)):
for n in range(m + 1, len(kinds)):
arr.append(kinds[m] + "+" + kinds[n])
# 计数
dict = {}
for item in array:
for values in arr:
value = values.split("+")
if value[0] in item and value[1] in item:
if values in dict:
dict[values] += 1
else:
dict[values] = 1
# print(dict)
# {'B+A': 1, 'A+E': 1, 'C+E': 2, 'B+E': 3, 'C+B': 2, 'C+A': 2}
# 第二次剪枝
newdict = judge_spport(dict, support)
# print(newdict)
# {'C+E': 2, 'B+E': 3, 'C+B': 2, 'C+A': 2}
# 第三次扫描
# 构造项集C2
# 两两组合
arr = []
kinds = getkinds(newdict.keys())
for m in range(0, len(kinds)):
for n in range(m + 1, len(kinds)):
for k in range(n + 1, len(kinds)):
arr.append(kinds[m] + "+" + kinds[n] + "+" + kinds[k])
# 计数
dict = {}
for item in array:
for values in arr:
value = values.split("+")
if value[0] in item and value[1] in item and value[2] in item:
if values in dict:
dict[values] += 1
else:
dict[values] = 1
# print(dict)
# {'E+B+A': 1, 'E+C+A': 1, 'E+B+C': 2, 'B+C+A': 1}
# 第三次剪枝
newdict = judge_spport(dict, support)
# {'B+E+C': 2}
return newdict
# 剪枝
# 删除不符合支持度的key
def judge_spport(dict, support):
dic = dict.copy()
for key in dict.keys():
if dict[key] < support:
del dic[key]
return dic
if __name__ == '__main__':
support = 2
info = [["A", "C", "D"], ["B", "C", "E"], ["A", "B", "C", "E"], ["B", "E"]]
dict = getcount(info, support)
print(dict)
打印结果为:
{'C+B+E': 2}
强规则计算
上文可知频繁集{C,B,E}的非空真子集有{B,C},{B,E},{C,E},{B},{C}和{E},对应置信度如下:
B&&C->E confidence=2/2=100%
B&&E->C confidence=2/3=66%
C&&E->B confidence=2/2=100%
B ->C&&E confidence=2/3=66%
C ->B&&E confidence=2/3=66%
E ->B&&C confidence=2/3=66%
对于规则" If B and E then C",同时购买B和E的人中,有66.67%会购买C。
即置信度confidence=P(B|A)=P(AB)/P(A)
计算强规则的代码为:
# 计算强规则
def getconfidence(dict,array):
# 一一组合
kinds = getkinds(dict.keys())
arr = kinds
newdict = {}
for i in range(0,len(arr)):
denominator1 = 0
numerator1 = 0
denominator2 = 0
numerator2 = 0
for item in array:
if arr[i] in item:
denominator1 += 1
temp = getkinds(dict.keys())
temp.remove(arr[i])
if temp[0] in item and temp[1] in item:
numerator1 += 1
key1 = arr[i] + "->" + temp[0] + "+" + temp[1]
for item in array:
temp = getkinds(dict.keys())
temp.remove(arr[i])
if temp[0] in item and temp[1] in item:
numerator2 += 1
if arr[i] in item:
denominator2 += 1
key2 = temp[0] + "+" + temp[1] + "->" + arr[i]
if denominator1 == 0:
newdict[key1] = str(numerator1) + "denominator1"
else:
newdict[key1] = str(numerator1) + "/" + str(denominator1)
if numerator2 == 0:
newdict[key2] = str(denominator2) + "numerator2"
else:
newdict[key2] = str(denominator2) + "/" + str(numerator2)
return newdict
打印结果为:
{'B->E+C': '2/3', 'B+C->E': '2/2', 'E+C->B': '2/2', 'E->B+C': '2/3', 'C->B+E': '2/3', 'B+E->C': '2/3'}
结果解说
可以知道购买B和C的人很可能买E,买了E和C的人很可能买B,而其他的概率可能要小一些,例如购买了B的人,很可能买E和C。
apriori推荐算法的更多相关文章
- FP-tree推荐算法
推荐算法大致分为: 基于物品和用户本身 基于关联规则 基于模型的推荐 基于物品和用户本身 基于物品和用户本身的,这种推荐引擎将每个用户和每个物品都当作独立的实体,预测每个用户对于每个物品的喜好程度,这 ...
- python 推荐算法
每个人都会有这样的经历:当你在电商网站购物时,你会看到天猫给你弹出的“和你买了同样物品的人还买了XXX”的信息:当你在SNS社交网站闲逛时,也会看到弹出的“你可能认识XXX“的信息:你在微博添加关注人 ...
- Mahout推荐算法API详解
转载自:http://blog.fens.me/mahout-recommendation-api/ Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, ...
- 【笔记3】用pandas实现矩阵数据格式的推荐算法 (基于用户的协同)
原书作者使用字典dict实现推荐算法,并且惊叹于18行代码实现了向量的余弦夹角公式. 我用pandas实现相同的公式只要3行. 特别说明:本篇笔记是针对矩阵数据,下篇笔记是针对条目数据. ''' 基于 ...
- 推荐算法——距离算法
本文内容 用户评分表 曼哈顿(Manhattan)距离 欧式(Euclidean)距离 余弦相似度(cos simliarity) 推荐算法以及数据挖掘算法,计算"距离"是必须的~ ...
- 将 Book-Crossing Dataset 书籍推荐算法中 CVS 格式测试数据集导入到MySQL数据库
本文内容 最近看<写给程序员的数据挖掘指南>,研究推荐算法,书中的测试数据集是 Book-Crossing Dataset 提供的亚马逊用户对书籍评分的真实数据.推荐大家看本书,写得不错, ...
- 美团网基于机器学习方法的POI品类推荐算法
美团网基于机器学习方法的POI品类推荐算法 前言 在美团商家数据中心(MDC),有超过100w的已校准审核的POI数据(我们一般将商家标示为POI,POI基础信息包括:门店名称.品类.电话.地址.坐标 ...
- Mahout推荐算法基础
转载自(http://www.geek521.com/?p=1423) Mahout推荐算法分为以下几大类 GenericUserBasedRecommender 算法: 1.基于用户的相似度 2.相 ...
- Apriori 关联算法学习
1. 挖掘关联规则 1.1 什么是关联规则 一言蔽之,关联规则是形如X→Y的蕴涵式,表示通过X可以推导“得到”Y,其中X和Y分别称为关联规则的先导(antecedent或left-hand-sid ...
随机推荐
- 《C++primer》v5 第8章 IO库 读书笔记 习题答案
8.1.8.2 这一章不咋会啊.. istream &read(istream &is) { int a; auto old_state=is.rdstate(); is.clear( ...
- Android Studio下SlidingMenu的导入与基础使用
一.关于这个控件,其实我们现在很多app都在用,最简单的,你打开QQ,当看资料卡的时候,首先要侧拉一下,那个就是SlidingMenu 这几天查了很多资料,各种方法都试了,但是一直都没有成功,最后在一 ...
- Android侧滑菜单代码实现
前两天学习了hyman老师讲的Android侧滑菜单的实现,经过自己的整理分享出来给大家学习一下 现在很多APP都有菜单侧滑的功能,本篇文章主要讲解使用自定义的HorizontalScrollView ...
- Bat文件, Services
创建Bat文件自启动Windows Service; Services: sc stop/delete/query/find "service name"; Service Fol ...
- Excel 改变列表头显示方式, Excel显示列数字
'显示数字列号 Sub showCellNumber() Application.ReferenceStyle = xlR1C1 End Sub '显示字母列号 Sub showCellZimu() ...
- liunx中字符驱动编写的简单模板
下面是关于字符驱动两个程序,主要是说明驱动编写的思想,理解驱动是怎么一步一步被实现的. 驱动的第一个实现程序,是相对于裸机编程的,主要是体会一下驱动编程思想: cdev.h: 所包含的头文件 #ifn ...
- wordpress视频教程
wordpress还不错的一套自动赚钱视频教程 http://www.ggfenxiang8.com/?p=256
- 小技巧:addobject: 和 addobjectsFromArray 的区别
NSArray *array1 = [NSArray alloc]init]; NSArray *array2 = [NSArray alloc]init]; [array1 addobject: a ...
- win7绕过开机密码攻略
访问windows机器,经常会因为忘记了开机密码而苦恼.当然你也可以选择重装,这样最简单粗暴.如果有重要数据保存在C盘之类的(个人严重推荐不要保存到C盘),那就不是重装能解决的问题了.2014年12月 ...
- qt 设置等待事件
QElapsedTimer et;et.start();while(et.elapsed() < 1000) QCoreApplication::processEvents();