大数据时代开始流行推荐算法,所以作者写了一篇教程来介绍apriori推荐算法。

推荐算法大致分为:

  1. 基于物品和用户本身
  2. 基于关联规则
  3. 基于模型的推荐

基于物品和用户本身

基于物品和用户本身的,这种推荐引擎将每个用户和每个物品都当作独立的实体,预测每个用户对于每个物品的喜好程度,这些信息往往是用一个二维矩阵描述的。由于用户感兴趣的物品远远小于总物品的数目,这样的模型导致大量的数据空置,即我们得到的二维矩阵往往是一个很大的稀疏矩阵。同时为了减小计算量,我们可以对物品和用户进行聚类, 然后记录和计算一类用户对一类物品的喜好程度,但这样的模型又会在推荐的准确性上有损失。

基于关联规则

基于关联规则的推荐(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推荐算法的更多相关文章

  1. FP-tree推荐算法

    推荐算法大致分为: 基于物品和用户本身 基于关联规则 基于模型的推荐 基于物品和用户本身 基于物品和用户本身的,这种推荐引擎将每个用户和每个物品都当作独立的实体,预测每个用户对于每个物品的喜好程度,这 ...

  2. python 推荐算法

    每个人都会有这样的经历:当你在电商网站购物时,你会看到天猫给你弹出的“和你买了同样物品的人还买了XXX”的信息:当你在SNS社交网站闲逛时,也会看到弹出的“你可能认识XXX“的信息:你在微博添加关注人 ...

  3. Mahout推荐算法API详解

    转载自:http://blog.fens.me/mahout-recommendation-api/ Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, ...

  4. 【笔记3】用pandas实现矩阵数据格式的推荐算法 (基于用户的协同)

    原书作者使用字典dict实现推荐算法,并且惊叹于18行代码实现了向量的余弦夹角公式. 我用pandas实现相同的公式只要3行. 特别说明:本篇笔记是针对矩阵数据,下篇笔记是针对条目数据. ''' 基于 ...

  5. 推荐算法——距离算法

    本文内容 用户评分表 曼哈顿(Manhattan)距离 欧式(Euclidean)距离 余弦相似度(cos simliarity) 推荐算法以及数据挖掘算法,计算"距离"是必须的~ ...

  6. 将 Book-Crossing Dataset 书籍推荐算法中 CVS 格式测试数据集导入到MySQL数据库

    本文内容 最近看<写给程序员的数据挖掘指南>,研究推荐算法,书中的测试数据集是 Book-Crossing Dataset 提供的亚马逊用户对书籍评分的真实数据.推荐大家看本书,写得不错, ...

  7. 美团网基于机器学习方法的POI品类推荐算法

    美团网基于机器学习方法的POI品类推荐算法 前言 在美团商家数据中心(MDC),有超过100w的已校准审核的POI数据(我们一般将商家标示为POI,POI基础信息包括:门店名称.品类.电话.地址.坐标 ...

  8. Mahout推荐算法基础

    转载自(http://www.geek521.com/?p=1423) Mahout推荐算法分为以下几大类 GenericUserBasedRecommender 算法: 1.基于用户的相似度 2.相 ...

  9. Apriori 关联算法学习

    1. 挖掘关联规则 1.1   什么是关联规则 一言蔽之,关联规则是形如X→Y的蕴涵式,表示通过X可以推导“得到”Y,其中X和Y分别称为关联规则的先导(antecedent或left-hand-sid ...

随机推荐

  1. 工厂方法模式与IoC/DI

    IoC——Inversion of Control  控制反转 DI——Dependency Injection   依赖注入 1:如何理解IoC/DI        要想理解上面两个概念,就必须搞清 ...

  2. [抓紧小长假的尾巴] 分析一个KeyFileMe

    系统 : Windows xp 程序 : keyfileme 程序下载地址 :http://pan.baidu.com/s/1qYVfvu0 要求 : 编写KeyFile 使用工具 : OD 可在看雪 ...

  3. C# Substring的用法

    方法1  Substring(Int32) 从此实例检索子字符串. 子字符串在指定的字符位置开始并一直到该字符串的末尾. 方法2 Substring(Int32, Int32) 从此实例检索子字符串. ...

  4. C#的IPAddress IPEndPoint

    以前觉得什么都能记住 翻一遍书就能去考试了,现在回过头来想一些东西,突然有种模糊的陌生感,应了那句好记性不如烂笔头.做笔记终归是利大于弊的.麻烦一点但是却受用. 突然想从头开始,看一些过去的书,补一些 ...

  5. LayaAir引擎——(五)

    LayaAir引擎——关于地图详解 所需要的软件: LayaAirIDE1.0.2版本 在LayaAir引擎中与地图相关的类: 1.laya.map.TiledMap TiledMap类   地图以层 ...

  6. Python 基础之在ubuntu系统下安装双版本python

    前言:随着python升级更新,新版本较于老版本功能点也有不同地方,作为一个初学者应该了解旧版本的规则,也要继续学习新版本的知识.为了能更好去学习python,我在ubuntu安装python2和py ...

  7. OpenGL坐标变换及其数学原理,两种摄像机交互模型(附源程序)

    实验平台:win7,VS2010 先上结果截图(文章最后下载程序,解压后直接运行BIN文件夹下的EXE程序): a.鼠标拖拽旋转物体,类似于OGRE中的“OgreBites::CameraStyle: ...

  8. linux 查找文件与进程常用命令

    Linux的五个查找命令 1. find find是最常见和最强大的查找命令,你可以用它找到任何你想找的文件. find的使用格式如下: $ find <指定目录> <指定条件> ...

  9. scrollView中可以自由滚动的listview

    直接在scrollView中写listview等可滚动控件会出现子控件高度计算的问题,为了解决这个问题,找到的方案是重写listview中的onmeasure方法: @Override public ...

  10. CLR via C# 3rd - 07 - Constants and Fields

    1. Constants        A constant is a symbol that has a never-changing value. When defining a constant ...