推荐算法大致分为:
- 基于物品和用户本身
- 基于关联规则
- 基于模型的推荐
基于物品和用户本身的,这种推荐引擎将每个用户和每个物品都当作独立的实体,预测每个用户对于每个物品的喜好程度,这些信息往往是用一个二维矩阵描述的。由于用户感兴趣的物品远远小于总物品的数目,这样的模型导致大量的数据空置,即我们得到的二维矩阵往往是一个很大的稀疏矩阵。同时为了减小计算量,我们可以对物品和用户进行聚类, 然后记录和计算一类用户对一类物品的喜好程度,但这样的模型又会在推荐的准确性上有损失。
基于关联规则的推荐(Rule-based Recommendation):关联规则的挖掘已经是数据挖掘中的一个经典的问题,主要是挖掘一些数据的依赖关系,典型的场景就是“购物篮问题”,通过关联规则的挖掘,我们可以找到哪些物品经常被同时购买,或者用户购买了一些物品后通常会购买哪些其他的物品,当我们挖掘出这些关联规则之后,我们可以基于这些规则给用户进行推荐。
基于模型的推荐(Model-based Recommendation):这是一个典型的机器学习的问题,可以将已有的用户喜好信息作为训练样本,训练出一个预测用户喜好的模型,这样以后用户在进入系统,可以基于此模型计算推荐。这种方法的问题在于如何将用户实时或者近期的喜好信息反馈给训练好的模型,从而提高推荐的准确度。
其实在现在的推荐系统中,很少有只使用了一个推荐策略的推荐引擎,一般都是在不同的场景下使用不同的推荐策略从而达到最好的推荐效果,例如 Amazon 的推荐,它将基于用户本身历史购买数据的推荐,和基于用户当前浏览的物品的推荐,以及基于大众喜好的当下比较流行的物品都在不同的区域推荐给用户,让用户可以从全方位的推荐中找到自己真正感兴趣的物品。探索推荐引擎内部的秘密,第 1 部分: 推荐引擎初探
Apriori算法 是一种最有影响力的 挖掘布尔关联规则 的频繁项集的算法,这个算法是属于上面第二条基于关联规则
推荐的算法,本文着重讲解该算法的计算。
- 对某个时间段内的事件进行记录,例如上图中的T1,T2,T3,T4
- 统计每个时间段的单事件发生的频数,例如图中项集C1,即1项频繁项集
- 根据之前定好的最小支持度对项集C1进行剪枝,剔除掉小于最小支持度的数据,得到L1
- 对2项频繁项集里面的元素进行两两组合,得到C2,即2项频繁项集
- 在原始数据中,统计C2中元素出现的个数,不要求按顺序,只要存在就行。即得到下一个C2
- 根据C2的频数再利用最小支持度进行剪枝,得到L2
- L2中的元素只有A、B、C、E,得到的3项频繁项为:[{A,B,C},{A,C,E},{B,C,E}],对其3项频繁项集进行计数,只有{B,C,E}大于等于最小支持度,所以最后保留{B,C,E}
- 即得到最强规则为频繁项{B,C,E}
- 将B,C,E拆开组合可以得到如下事物:
{B,C->E},{B,E->C},{C,E->B},{B ->C,E},{C->B,E},{E ->B,C}
上述组合只看存在与否,不考虑排序。首先看第一条,存在B,C的数据为T2,T3;存在B,C后还存在E的为T2,T3,因此置信度为 confidence=2/2=100%
又例如存在B,E的为T2,T3,T4,存在B,E后还存在C的为T2,T3,因此置信度为 confidence=2/3=66%
所以上述所有的置信度为:
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%
假设设置最小置信度为80%,那么强关联规则的组合为 B,C->E
和 C,E->B
即买了B,C的肯定会买E;买了C,E的肯定会买B。
按照网上最简单的例子来进行分析:
支持度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。
源码下载:
爬虫代码不知道怎么写
关注公众号让作者帮你解决!
在使用 `import org.apache.spark.ml.feature.VectorAssembler` 转换特征后,想要放入 `import org.apache.spark.mllib.classification.SVMWithSGD` 去训练的时候出现错误 阅读全文 » |
Python3 打包exe方式 阅读全文 » |
《漫威》系列电影中,距离《复仇者联盟4》上映一周,豆瓣分都是8.1分的钢铁侠》和《复仇者联盟3》,《钢铁侠》有353695人评价打分,《复仇者联盟3》有557491人评价打分,这两部电影是否一样好看? 阅读全文 » |
昨天收到公众号粉丝的爬虫需求:抓取平台:天猫或者淘宝;爬取对象:某个商品的各分类的价格和库存数 阅读全文 » |
在flask页面下载excel 阅读全文 » |
java.lang.NoSuchMethodError: org.apache.spark.sql.DataFrameNaFunctions.fill(JLscala/collection/Seq;)Lorg/apache/spark/sql/Dataset 阅读全文 » |
import org.apache.spark.ml.feature.{HashingTF, IDF}库中,TFIDF结果的字段含义 阅读全文 » |
spark读CSV为Dataframe和spark将Dataframe写入CSV 阅读全文 » |
将dataframe利用pyspark列合并为一行,类似于sql的GROUP_CONCAT函数。spark和pyspark的方式不能共用 阅读全文 » |
想看下最近房价是否能入手,抓取链家二手房、新房的信息,发现广州有些精装修88平米的3房2厅首付只要 29 万,平均 1.1万/平,果然钱不够信息来凑,总能发现便宜的房子! 阅读全文 » |
hive新建分区表 阅读全文 » |
hive删除表和表中的数据,以及按分区删除数据 阅读全文 » |
csdn目前设置每日使用5次后必须登录才能看到阅读更多的内容,异常恶心。因此搜罗了方法去解决这个问题 阅读全文 » |
pandas和spark的dataframe互转 阅读全文 » |
需要将代码转换为html使其显示好看一些,可以在这里进行装换 阅读全文 » |
需要调用命令行来执行某些命令,主要是用subprocess实时获取结果和捕获错误,发现subprocess的很多坑 阅读全文 » |
ubuntu的vim取消缩进 阅读全文 » |
需要实现两台机器的信息交互,使用 `socket` 进行调度 阅读全文 » |
centos7开放端口和防火墙设置 阅读全文 » |
python获取set-cookies 阅读全文 » |
记录在TensorFlow中使用GPU的一些操作 阅读全文 » |
pandas的apply操作类似于Scala的udf一样方便 阅读全文 » |
将dataframe利用pandas列合并为一行,类似于sql的GROUP_CONCAT函数 阅读全文 » |
python读取了一个list是字符串形式的[11.23,23.34],想转换成list类型 阅读全文 » |
python中使用了pandas的一些操作,特此记录下来。 阅读全文 » |
python中使用了numpy的一些操作,特此记录下来。 阅读全文 » |
Python3+Flask+uwsgi部署web服务,实现在新的IP下打开网址 阅读全文 » |
在python中,需要将整数均分成N等分。python divide integers N equal parts sum 阅读全文 » |
在Windows7下需要安装pyspark,写下教程步骤 阅读全文 » |
对于python数组的操作有点混乱,所以特此记录下来 阅读全文 » |
马尔科夫链转移矩阵计算方式 阅读全文 » |
需要将dataframe中的某一行变换为列 阅读全文 » |
scala获取某个时间间隔的时间 阅读全文 » |
Linux查看文件夹大小 阅读全文 » |
需要对dataframe按照某几列为key,对另外几列进行计算,考虑到scala的reduceByKey比groupByKey快速很多,所以使用了这个操作 阅读全文 » |
需要将Spark Dataframe转换为Scala Map集合 阅读全文 » |
Caused by: org.elasticsearch.hadoop.EsHadoopException: Could not write all entries [1/1] (Maybe ES was overloaded?). Error sample... 阅读全文 » |
spark调用distinct只能删除完全相同的行,而需要一种方法按照某几列作为唯一ID来删除重复,利用dropDuplicates可以完美解决这个问题 阅读全文 » |
spark调用elsticsearch的API对elasticsearch进行增删查改 阅读全文 » |
在 hadoop中,基于Linux命令可以给hdfs创建文件和文件夹,或者删除文件和文件夹 阅读全文 » |
spark调用hdfsAPI查询文件名字、删除文件 阅读全文 » |
hadoop使用出现安全模式错误Name node is in safe mode,退出安全模式 阅读全文 » |
在提取dataframe里面的列时,需要传入不定参数,即dataframe.select(args) 阅读全文 » |
github pages一直想添加代码高亮highlighter,基于jekyll 3.0的rouge终于搞定了 阅读全文 » |
System memory * must be at least *.Please increase heap size using the --driver--memory option or spark.driver.memory 阅读全文 » |
python万能库 阅读全文 » |
spark计算两个DataFrame的差集、交集、合集 阅读全文 » |
记录Linux查看的系统的命令,Linux查看系统、核数、CPU、位数 阅读全文 » |
任何一个电子商务公司想要存活下去,必须要时时掌控市场的动态,淘宝天猫上面的商品数据刚好能满足这样子的需求,所以写下这篇抓取教程 阅读全文 » |
特定环境下需要安装Linux suse 11 sp1,走过太多的坑,所以记录下安装的过程方便以后再使用 阅读全文 » |
在抓取网页的时候只想抓取主要的文本框,所以用了一个比较暴力的方法去识别 阅读全文 » |
在抓取网页的时候只想抓取主要的文本框,所以用了一个比较暴力的方法去识别 阅读全文 » |
python之BeautifulSoup使用 阅读全文 » |
selenium操控浏览器下拉到页面最底端 阅读全文 » |
一种去除dataframe中null、NaN和空字符串的方法,基于scala下 阅读全文 » |
chardet库是python的字符编码检测器,能够检测出各种编码的类型 阅读全文 » |
记录python读写2003和2007版本的excel的一些方式 阅读全文 » |
scala时间和时间戳互转 阅读全文 » |
在给代码带包成jar后,放到环境中运行出现No FileSystem for scheme file错误,找到解决办法 阅读全文 » |
在spark中给dataframe增加一列的方法一般使用withColumn,但是个人感觉少了很多功能,不如使用udf 阅读全文 » |
Scala查询dataFrame结构 阅读全文 » |
在使用数据库的时候,需要将查询出来的一列按照逗号合并成一行 阅读全文 » |
日志文件太多,需要清空 阅读全文 » |
安装了 `ubuntu-14` ,为了连接 `xshell` ,做出的一些配置 阅读全文 » |
在scala里面存在 调用Linux命令行的函数,得到返回的结果 阅读全文 » |
在scala中远程连接Linux,并发送相关命令到Linux上,得到返回的结果 阅读全文 » |
`spark` 中的 `reduce` 非常的好用,`reduce` 可以对 `dataframe` 中的元素进行计算、拼接等等 阅读全文 » |
很多人的个人博客用的是多说评论,但是最近多说突然说要关闭了... 阅读全文 » |
网上很多人问绑定域名要不要备案,很多人的回答是... 阅读全文 » |
从数据库提取出来的时间为 `String` 格式,现在需要转换为 `date` 并提取出里面的 *小时* 时间段 阅读全文 » |
为了加密 `.py` 文件,以前一般使用打包成exe ,但是最近发现可以将其编译成二进制文件pyc,虽然反编译难度不大,但是也需要一些水平 阅读全文 » |
python批量启动多线程 阅读全文 » |
Linux发现ctrl+c无法中断程序 阅读全文 » |
scala中spark运行内存不足 阅读全文 » |
scala打包jar并在Linux下运行 阅读全文 » |
scala的input 阅读全文 » |
scala的break和continue 阅读全文 » |
scala合并Array 阅读全文 » |
scala读取配置文件 阅读全文 » |
scala读取解析json文件 阅读全文 » |
scala判断数据类型 阅读全文 » |
IntelliJ的Scala配置 阅读全文 » |
scala的map操作 阅读全文 » |
python获取当前路径 阅读全文 » |
python的StringIO 阅读全文 » |
此方法相当于 `Linux` 系统下的`diff`,或者是 `git` 下的 `checkout` 阅读全文 » |
Linux查找文件内容 阅读全文 » |
python日志syslog运用 阅读全文 » |
python连接Linux命令行 阅读全文 » |
由于 `python` 频繁打印会导致IDE或者系统奔溃,因此将其打印信息写入日志文件中 阅读全文 » |
scala安装教程图文解说 阅读全文 » |
python获取当前运行程序的名字 阅读全文 » |
python获取文件夹名字 阅读全文 » |
python时间和时间戳互转 阅读全文 » |
python判断文件是否存在 阅读全文 » |
python创建递归文件夹 阅读全文 » |
sklearn的kmeans测试代码 阅读全文 » |
当使用库的时候,需要传递不确定个数的参数,那么写法是怎样的? 阅读全文 » |
python安装万能仓库的whl文件出错,原来是文件名弄错了 阅读全文 » |
安装sklearn库需要很多前提条件,而且不能pip3 install sklearn,因此写下教程 阅读全文 » |
Oracle查询得到的时间都是1970...,在python下将其转为时间戳 阅读全文 » |
过年很多人会发微信的红包,但是为毛很多人说自己得不到最佳,因此作者写了一个微信红包发送的算法 阅读全文 » |
在Linux下安装python3且不影响系统的python2 阅读全文 » |
hadoop完全分布式搭建 阅读全文 » |
最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Bayesian Model,NBM),本文讲解朴素贝叶斯 阅读全文 » |
数据挖掘中的ID3决策树算法,再次进行一个初步的学习 阅读全文 » |
虚拟机VMwareWorkstation下安装Linux系统centOS 阅读全文 » |
微信小程序在2017-01-09正式上线,本着跟上时代潮流的精神,写一份教程来看看 阅读全文 » |
埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数 阅读全文 » |
层次聚类是另一种主要的聚类方法,它具有一些十分必要的特性使得它成为广泛应用的聚类方法 阅读全文 » |
K近邻(KNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一 阅读全文 » |
以前使用聚类是用spss,现在用python自己写了一次 阅读全文 » |
大数据时代开始流行推荐算法,所以作者写了一篇教程来介绍FP-tree推荐算法 阅读全文 » |
学习了一些chrome插件的基本用法 阅读全文 » |
大数据时代开始流行推荐算法,所以作者写了一篇教程来介绍apriori推荐算法 阅读全文 » |
海龟画图很好看,试着玩了一下 阅读全文 » |
做github静态博客,学习安装jekyll 阅读全文 » |
在破解Amazon的验证码的时候,利用机器学习得到验证码破解精度超过70%,主要是训练样本不够,如果在足够的样本下达到90%是非常有可能的。 阅读全文 » |
妹子要去招聘会工作,奈何网上仅仅提供招聘会的公司名字,没有提供招聘的职位,SO我写了个小代码给妹子在智联上面搜索职位,由于时间紧迫,前程的就不写了 阅读全文 » |
selenium设置浏览器属性 阅读全文 » |
javascript获取浏览器属性 阅读全文 » |
javascript操控浏览器 阅读全文 » |
为了获取网站js渲染后的html,需要利用selenium加载网站,但是会出现加载时间过长的现象,因此可以限制其加载时间以及强制关掉加载 阅读全文 » |
win10安装配置golang 阅读全文 » |
pycharm基本设置,省得每次都要去网上找 阅读全文 » |
百度指数抓取,再用图像识别得到指数 阅读全文 » |
selenium之xpath定位和input文本 阅读全文 » |
selenium在同一浏览器下多个窗口切换 阅读全文 » |
selenium识别下拉框 阅读全文 » |
假如外出工作,需要在另一台电脑上面pull自己的某个git远程项目到本地 阅读全文 » |
妹纸推荐书籍《御伽草纸》,网上找了很久都找不到下载,估计是被Amazon版权了,但是在网易云阅读看到有书,所以就写个代码下载下来。 阅读全文 » |
标签云是现在大数据里面最喜欢使用的一种展现方式,其中在python3下也能实现标签云的效果 阅读全文 » |
RGB颜色对照图 阅读全文 » |
python3的多线程很多人无法理解是怎么运行的,因此本文从程序猿的日常生活出发,写了一个由浅入深的多线程教程,这样子大家就不会觉得陌生了,多线程真的很简单很简单! 阅读全文 » |
selenium是处理异步加载的一种方法 阅读全文 » |
python数据库操作pymysql 阅读全文 » |
详解如何搞定瀑布流 阅读全文 » |
详解如何搞定瀑布流 阅读全文 » |
java从零到变身爬虫大神 阅读全文 » |
github上传本地项目 阅读全文 » |
没事玩了一下matlab 阅读全文 » |
mysql在大学学了,现在忘记得差不多了,复习复习一下 阅读全文 » |
css初学 阅读全文 » |
学习了一些html的基本用法 阅读全文 » |
学习了一些html的基本用法 阅读全文 » |
学习了一些html的基本用法 阅读全文 » |
EDM营销:全称Email Direct Marketing,即电子邮件营销 阅读全文 » |
老板要画雷达图,但是数据好多组怎么办?不能一个一个点excel去画吧,那么可以利用python进行批量制作 阅读全文 » |
markdown初学 阅读全文 » |
在上一篇算法中,逻辑回归作为一种二分类的分类器,一般的回归模型也是是判别模型,也就根据特征值来求结果概率。形式化表示为 p(y|x;θ),在参数 θ 确定的情况下,求解条件概率 p(y|x) 。 阅读全文 » |
在上一篇算法中,线性回归实际上是 连续型 的结果,即 y∈R ,而逻辑回归的 y 是离散型,只能取两个值 y∈{0,1},这可以用来处理一些分类的问题。 阅读全文 » |
今天我们这里要讲第一个有监督学习算法,他可以用于一个回归任务,这个算法叫做 线性回归 阅读全文 » |
网站已运行
公元 年 月 农历年 年
|