目录

0. 前言

1. 相似度

1.1. 欧式距离(Euclidean metric)

1.2. 皮尔逊相关系数(Pearson correlation coefficient)

1.3. 余弦相似度(Cosine similarity)

2. 基于内容(物品)的推荐算法

3. 基于用户的推荐算法

4. 基于内容(物品)的协同过滤推荐算法

5. 基于用户的协同过滤推荐算法

6. 实战案例

6.1. 基于物品的协同过滤算法

6.2. SVD压缩数据后,基于物品的协同过滤算法

6.3. 基于用户的协同过滤算法


学习完机器学习实战的推荐系统,简单的做个笔记。文中部分描述属于个人消化后的理解,仅供参考。

所有代码和数据可以访问 我的 github

如果这篇文章对你有一点小小的帮助,请给个关注喔~我会非常开心的~

0. 前言

在推荐算法中,数据通常由一个矩阵构成,每一行(列)代表用户,每一列(行)代表物品,每一个元素代表用户对物品的评分。

推荐系统的基本思想是,预测用户对物品的评分,若评分高,则推荐给该用户。

本篇主要简单介绍四种推荐系统:

  • 基于内容(物品)的推荐算法
  • 基于用户的推荐算法
  • 基于内容(物品)的协同过滤推荐算法
  • 基于用户的协同过滤推荐算法

注:基于内容的算法复杂度会随着内容的增加而增加,基于用户的算法复杂度会随着用户的增加而增加。

1. 相似度

1.1. 欧式距离(Euclidean metric)

欧式距离是两个向量之间的距离,定义如下:

距离越短,说明相似程度越高,因此可通过如下定义,将其转换到  范围内,越接近  ,说明相似度越高:

1.2. 皮尔逊相关系数(Pearson correlation coefficient)

皮尔逊相关系数是两个向量的协方差和标准差的商:

皮尔逊相关系数的取值范围是  ,通过以下定义,将其转换至  范围:

1.3. 余弦相似度(Cosine similarity)

余弦相似度是计算两个向量的夹角余弦值,如果向量正交,则相似度为  :

余弦相似度的取值范围也是  ,通过以下定义,将其转换至  范围:

2. 基于内容(物品)的推荐算法

基于内容的推荐算法要求已知物品的特征属性值,通过计算两个物品属性的相似程度,进行推荐。

根本道理就是,如果这两个物品相似,你喜欢这个物品,就预测你也喜欢另一个。

例如在下述例子中,已知电影的特征属性浪漫程度和动作程度,右侧是用户的评分:

  电影浪漫程度x_1 电影动作程度x_2 用户A 用户B
电影001 0.9 0.1 5分 1分
电影002 0.8 0.2
电影003 0.3 0.7 2分
电影004 0.2 0.8 4分

通过相似度计算,可以发现电影001和电影002相似,电影003和电影004相似,则可以将电影002推荐给喜欢电影001的用户A,将电影003推荐给喜欢电影004的用户B。

同时,也可采用线性回归,将电影浪漫程度和电影动作程度作为特征  ,将单个用户的评分作为标签  ,用参数  进行拟合。对未评分的电影进行预测,按照预测的评分从高到低进行推荐。

3. 基于用户的推荐算法

基于用户的推荐算法要求已知用户的特征属性值,通过计算两个用户的相似程度,进行推荐。

根本道理就是,如果两个人相似,他喜欢的东西,就预测你也喜欢。

例如在下述例子中,已知用户的内向程度和豪放程度,右侧是用户的评分:

  用户内向程度x_1 用户豪放程度x_2 电影001 电影002
用户A 0.9 0.1 5分 1分
用户B 0.8 0.2 2分
用户C 0.3 0.7 2分
用户D 0.2 0.8 4分

通过相似度计算,可以发现用户A和用户B相似,用户C和用户D相似,则可以将用户A喜欢的电影001推荐给用户B,将用户D喜欢的电影002推荐给用户C。

同时,也可采用线性回归,将用户内向程度和用户豪放程度作为特征  ,将单部电影的评分作为标签  ,用参数  进行拟合。对未评分的电影进行预测,将预测评分高的推荐给对应用户。

4. 基于内容(物品)的协同过滤推荐算法

基于内容的协同过滤推荐算法,依旧是根据物品的相似程度进行推荐。

不过衡量相似度的标准不是物品本身的特征属性,而利用大量用户对物品的评分作为特征计算物品的相似度

算法流程如下:

  1. 遍历单个用户所有未评分的物品(准备预测评分)
  2. 对于每一个未评分的物品  ,遍历每一个已评分的物品  (准备计算相似度)
  3. 获取同时评价了物品  和物品  的用户的评分,作为两个向量计算相似度 
  4. 将相似度  乘以一个权值,即当前用户对已评分物品  的评分
  5. 对于每一个未评分的物品  ,当遍历完所有已评分的物品后,将每次加权的相似度相加,除以总相似度,作为预测值
  6. 遍历完所有未评分的物品,将预测值排序,从高到低进行推荐

伪代码如下:

5. 基于用户的协同过滤推荐算法

基于用户的协同过滤推荐算法,依旧是根据用户的相似程度,推荐共同喜爱的物品。

不过衡量相似度的标准不是用户本身的特征属性,而利用大量用户对物品的评分作为特征计算用户的相似度

算法流程如下:

  1. 遍历单个物品所有未对其评分的用户(准备预测评分)
  2. 对于每一个未评分的用户  ,遍历每一个已对当前物品评分的用户  (准备计算相似度)
  3. 获取用户  和用户  的同时评价了的物品的评分,作为两个向量计算相似度 
  4. 将相似度  乘以一个权值,即用户  对当前物品的评分
  5. 对于每一个未评分的用户  ,当遍历完所有已评分的用户后,将每次加权的相似度相加,除以总相似度,作为预测值
  6. 遍历完所有未评分的用户,根据预测值的高低,将此物品推荐给这些用户

伪代码如下:

6. 实战案例

以下将展示书中案例的代码段,所有代码和数据可以在github中下载:

6.1. 基于物品的协同过滤算法

# coding:utf-8
from numpy import *
from numpy import linalg as la"""
基于物品的协同过滤算法
"""# 加载数据集
def loadExData2():return [[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]# 欧式距离
def ecludSim(inA, inB):return 1.0 / (1.0 + la.norm(inA - inB))# 皮尔逊相关系数
def pearsSim(inA, inB):if len(inA) < 3:return 1.0return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1]# 余弦相似度
def cosSim(inA, inB):num = float(inA.T * inB)denom = la.norm(inA) * la.norm(inB)return 0.5 + 0.5 * (num / denom)# 预测用户对于单个物品的评分
# dataMat: 数据矩阵
# user: 用户索引
# simMeas: 相似度函数
# item: 物品
def standEst(dataMat, user, simMeas, item):n = shape(dataMat)[1]simTotal = 0.0ratSimTotal = 0.0# 遍历每一个用户评价过的物品for j in range(n):# 用户对于该物品的评分userRating = dataMat[user, j]if userRating == 0:continue# 获取同时评价了该物品和待预测物品的用户的索引overLap = nonzero(logical_and(dataMat[:, item].A > 0,dataMat[:, j].A > 0))[0]if len(overLap) == 0:similarity = 0else:# 以这些用户对该物品的评分和这些用户对待预测物品的评分# 计算相似度similarity = simMeas(dataMat[overLap, item],dataMat[overLap, j])print('the %d and %d similarity is: %f' % (item, j, similarity))# 总相似度simTotal += similarity# 加权相似度ratSimTotal += similarity * userRatingif simTotal == 0:return 0else:return ratSimTotal / simTotal# 推荐算法
def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):# 获取用户未评分的物品的索引unratedItems = nonzero(dataMat[user, :].A == 0)[1]if len(unratedItems) == 0:return 'you rated everything'itemScores = []# 遍历每一个物品,计算相似度for item in unratedItems:estimatedScore = estMethod(dataMat, user, simMeas, item)itemScores.append((item, estimatedScore))return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]if __name__ == '__main__':myMat = mat(loadExData2())print(recommend(myMat, 0))

6.2. SVD压缩数据后,基于物品的协同过滤算法

# coding:utf-8
from numpy import *
from numpy import linalg as la"""
利用SVD处理数据后
基于物品的协同过滤算法
"""# 加载数据集
def loadExData2():return [[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]# 欧式距离
def ecludSim(inA, inB):return 1.0 / (1.0 + la.norm(inA - inB))# 皮尔逊相关系数
def pearsSim(inA, inB):if len(inA) < 3:return 1.0return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1]# 余弦相似度
def cosSim(inA, inB):num = float(inA.T * inB)denom = la.norm(inA) * la.norm(inB)return 0.5 + 0.5 * (num / denom)# 使用SVD分解数据之后
# 预测用户对于单个物品的评分
# dataMat: 数据矩阵
# user: 用户索引
# simMeas: 相似度函数
# item: 物品
def svdEst(dataMat, user, simMeas, item):n = shape(dataMat)[1]simTotal = 0.0ratSimTotal = 0.0# SVD分解数据U, Sigma, VT = la.svd(dataMat)Sig4 = mat(eye(4) * Sigma[:4])# 构建物品列表,维度为 n*4xformedItems = dataMat.T * U[:, :4] * Sig4.I# 遍历每一个用户评价过的物品for j in range(n):# 用户对于该物品的评分userRating = dataMat[user, j]if userRating == 0 or j == item:continue# 对该物品的评分和待预测物品的评分# 计算相似度similarity = simMeas(xformedItems[item, :].T,xformedItems[j, :].T)print('the %d and %d similarity is: %f' % (item, j, similarity))simTotal += similarityratSimTotal += similarity * userRatingif simTotal == 0:return 0else:return ratSimTotal / simTotal# 推荐算法
def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=svdEst):# 获取用户未评分的物品的索引unratedItems = nonzero(dataMat[user, :].A == 0)[1]if len(unratedItems) == 0:return 'you rated everything'itemScores = []# 遍历每一个物品,计算相似度for item in unratedItems:estimatedScore = estMethod(dataMat, user, simMeas, item)itemScores.append((item, estimatedScore))return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]if __name__ == '__main__':myMat = mat(loadExData2())print(recommend(myMat, 0, simMeas=cosSim))

6.3. 基于用户的协同过滤算法

# coding:utf-8
from numpy import *
from numpy import linalg as la"""
基于用户的协同过滤算法
"""# 加载数据集
def loadExData2():return [[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],[1, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]# 欧式距离
def ecludSim(inA, inB):return 1.0 / (1.0 + la.norm(inA - inB))# 皮尔逊相关系数
def pearsSim(inA, inB):if len(inA) < 3:return 1.0return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1]# 余弦相似度
def cosSim(inA, inB):num = float(inA.T * inB)denom = la.norm(inA) * la.norm(inB)return 0.5 + 0.5 * (num / denom)# 预测用户对于单个物品的评分
# dataMat: 数据矩阵
# user: 用户索引
# simMeas: 相似度函数
# item: 物品
def standEst(dataMat, user, simMeas, item):m = shape(dataMat)[0]simTotal = 0.0ratSimTotal = 0.0# 遍历每一个评价过该物品的用户for i in range(m):# 用户对于该物品的评分userRating = dataMat[i, item]if userRating == 0:continue# 获取待预测用户和该用户都评价过的商品列表overLap = nonzero(logical_and(dataMat[user, :].A > 0,dataMat[i, :].A > 0))[1]if len(overLap) == 0:similarity = 0else:# 以该用户对这些物品的评分和待预测用户对这些物品的评分# 计算相似度similarity = simMeas(dataMat[user, overLap].T,dataMat[i, overLap].T)print('the %d and %d similarity is: %f' % (user, i, similarity))# 总相似度simTotal += similarity# 加权相似度ratSimTotal += similarity * userRatingif simTotal == 0:return 0else:return ratSimTotal / simTotal# 推荐算法
def recommend(dataMat, item, N=3, simMeas=cosSim, estMethod=standEst):# 获取未对该物品评分的用户unratedItems = nonzero(dataMat[:, item].A == 0)[0]if len(unratedItems) == 0:return 'everyone rated item'itemScores = []# 遍历每一个用户,计算相似度for user in unratedItems:estimatedScore = estMethod(dataMat, user, simMeas, item)itemScores.append((user, estimatedScore))return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]if __name__ == '__main__':myMat = mat(loadExData2())print(recommend(myMat, 0))

如果这篇文章对你有一点小小的帮助,请给个关注喔~我会非常开心的~

机器学习实战(十三)推荐系统(协同过滤 Collaborative Filtering)相关推荐

  1. 推荐系统:协同过滤collaborative filtering

    http://blog.csdn.net/pipisorry/article/details/51788955 (个性化)推荐系统构建三大方法:基于内容的推荐content-based,协同过滤col ...

  2. Python机器学习实战教学——基于协同过滤的电影推荐系统(超详细教学,算法分析)

    注重版权,转载请注明原作者和原文链接 作者:Yuan-Programmer 结尾处有效果展示 文章目录 引言 一.技术原理 (一)推荐算法介绍 (二)主流距离计算法 (三)余弦距离计算法 二.数据介绍 ...

  3. 基于关联规则(Apriori)+协同过滤(collaborative filtering)实现电影推荐系统

    基于关联规则算法+协同过滤算法的电影推荐系统 一.前言 1.数据集介绍 2.方法概述 3.运行环境 二.数据准备与预处理 1.数据熟悉 2.数据读取 3.数据预处理 3.1 无用属性删除 3.2 缺失 ...

  4. 协同过滤(collaborative filtering)

    Author: Summer; Email: huangmeihong11@sina.com Datawhale 协同过滤简介 协同过滤是推荐算法中最常用的算法之一,它根据user与item的交互,发 ...

  5. Andrew Ng机器学习课程笔记--week9(下)(推荐系统协同过滤)

    本周内容较多,故分为上下两篇文章. 本文为下篇. 一.内容概要 1. Anomaly Detection Density Estimation Problem Motivation Gaussian ...

  6. 机器学习编程作业ex8(matlab/octave实现)-吴恩达coursera 异常检测与推荐系统/协同过滤

    程序打包网盘地址提取码1111 一.(Week 9)内容回顾 非监督学习问题的两种应用:异常检测与推荐系统 1.1 Anomaly Detection 异常检测 1.Density Estimatio ...

  7. [推荐系统]协同过滤介绍

    在现今的推荐技术和算法中,最被大家广泛认可和采用的就是基于协同过滤的推荐方法.本文将带你深入了解协同过滤的秘密.下面直接进入正题 1 什么是协同过滤 协同过滤是利用集体智慧的一个典型方法.要理解什么是 ...

  8. 在线新闻推荐网 Python+Django+Mysql开发技术 基于用户、物品的协同过滤推荐算法 个性化新闻推荐系统 协同过滤推荐算法在新闻网站中的运用 个性化推荐算法、机器学习、分布式大数据、人工智

    在线新闻推荐网 Python+Django+Mysql开发技术 基于用户.物品的协同过滤推荐算法 个性化新闻推荐系统 协同过滤推荐算法在新闻网站中的运用 个性化推荐算法.机器学习.分布式大数据.人工智 ...

  9. 在线图书推荐网 Python+Django+Mysql开发技术 个性化图书推荐系统 协同过滤推荐算法在图书网站中的运用 基于用户、物品的协同过滤推荐算法 个性化推荐算法、机器学习、分布式大数据、人工智

    在线图书推荐网 Python+Django+Mysql开发技术 个性化图书推荐系统 协同过滤推荐算法在图书网站中的运用 基于用户.物品的协同过滤推荐算法 个性化推荐算法.机器学习.分布式大数据.人工智 ...

最新文章

  1. 解决Mysql复制Relay log read failure 的问题
  2. 基于cropper和sweetalert的简单图片/头像裁剪上传
  3. 第十、十一周项目-阅读程序,写出这些程序的运行结果(2)
  4. LeetCode 406 Queue Reconstruction by Height
  5. NFS服务器主配置文件名,NFS服务器的搭建与配置
  6. [css] width属性的min-content和max-content有什么作用
  7. curl error code 60 51 代码解决方式
  8. JS代码实现浏览器切换页面时网页标题动态切换
  9. 江苏2021168查询高考成绩,重磅!高考成绩查询!!
  10. linux电路图软件有哪些,新手福利,推荐一款好用的电路图绘制软件!
  11. 问题:宇视摄像机如何对接第三方录像机
  12. 插值算法(数学建模学习)
  13. 华为外包员工是什么样的群体?
  14. python12306买票_Python 使用 selenium 实现半自动购买12306火车票
  15. Unbuntu20.04环境下一款开源翻译软件:goldendict的安装与配置(图文)
  16. SpringDataJPA学习笔记
  17. Makefile之wildcard
  18. 我学历不高,怎样找前端的工作?
  19. C++ vector详细用法
  20. 奇虎360 2013校园招聘笔试题

热门文章

  1. c#仿照qq登录界面编辑框内容操作
  2. SQLServer查询锁表
  3. 高性能滚动 scroll 及页面渲染优化
  4. python与冒泡排序
  5. JavaWeb之Servlet入门(一)
  6. 几个性能测试工具/框架的比较
  7. PowerDesigner12.5 破解,汉化下载(转载)
  8. JZOJ 3503. 粉刷(paint)
  9. [Objective-C语言教程]数组(14)
  10. (4)理解 neutron ml2---port创建流程代码解析