利用SVD-推荐未尝过的菜肴2

时间:2022-08-28 18:36:41

推荐未尝过的菜肴-基于SVD的评分估计

实际上数据集要比我们上一篇展示的myMat要稀疏的多。

from numpy import linalg as la
from numpy import *
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]]

一、计算一下到底有多少个奇异值能达到总能量的90%(下一篇我们将用一个函数实现该功能)

U, Sigma, VT = la.svd(mat(loadExData2()))
Sigma
array([15.77075346, 11.40670395, 11.03044558,  4.84639758,  3.09292055,
2.58097379, 1.00413543, 0.72817072, 0.43800353, 0.22082113,
0.07367823])
总能量:
Sig2 = Sigma ** 2 
sum(Sig2)
541.9999999999995
总能量的90%:
sum(Sig2) * 0.9
487.7999999999996
计算前两个元素所包含的能量:
sum(Sig2[:2])
378.8295595113579
该值低于总能量的90%,计算前三个元素所包含的能量:
sum(Sig2[:3])
500.5002891275793
该值高于总能量的90%,我们将一个11维的矩阵转换成一个三维的矩阵,下面对转换后的三维空间构造出一个相似度计算函数

二、相似度计算(欧式距离、皮尔逊相关系数、余弦相似度)

# 相似度计算
# 计算欧式距离
def ecludSim(inA, inB):
return 1.0 / (1.0 + la.norm(inA - inB)) # pearsim()函数会检查是否存在3个或更多的点
# corrcoef直接计算皮尔逊相关系数,范围[-1, 1],归一化后[0, 1]
def pearsSim(inA, inB):
# 如果不存在,该函数返回1.0,此时两个向量完全相关
if len(inA) < 3:
return 1.0
return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1] # 计算余弦相似度,如果夹角为90度,相似度为0;如果两个向量的方向相同,相似度为1.0
def cosSim(inA, inB):
num = float(inA.T * inB)
denom = la.norm(inA) * la.norm(inB)
return 0.5 + 0.5 * (num / denom)

三、基于SVD的评分估计

# 基于SVD的评分估计
# 在recommend()中,这个函数用于替换对standEst()的调用,该函数对给定用户、给定物品构建了一个评分估计值
def svdEst(dataMat, user, simMeas, item):
"""svdEst() Args:
dataMat 训练数据集
user 用户编号
simMeas 相似度计算方法
item 未评分的物品编号
Returns:
ratSimTotal / simTotal 评分(0~5之间的值)
"""
# 物品数目
n = shape(dataMat)[1]
# 对数据集进行SVD分解
simTotal = 0.0
ratSimTotal = 0.0 # 奇异值分解
# 在SVD分解之后,我们只利用包含了90%能量值的奇异值,这些奇异值会以Numpy数组的形式得以保存
U, Sigma, VT = la.svd(dataMat) # 如果要进行矩阵运算,就必须要用这些奇异值构建出一个对角矩阵
Sig4 = mat(eye(4) * Sigma[: 4]) # 利用U矩阵将物品转换到低维空间中,构建转换后的物品
xformedItems = dataMat.T * U[:, :4] * Sig4.I # 对于给定的用户,for循环在用户对应行的元素上进行遍历
# 这和standEst()函数中的for循环的目的一样,只不过这里的相似度计算是在低维空间下进行的
for j in range(n):
userRating = dataMat[user, j]
if userRating == 0 or j == item:
continue
# 相似度的计算方法也会作为一个参数传递给该函数
similarity = simMeas(xformedItems[item, :].T, xformedItems[j, :].T) # 对相似度不断累加求和
simTotal += similarity
# 对相似度及对应评分值的乘积求和
ratSimTotal += similarity * userRating
if simTotal == 0:
return 0
else:
# 计算估计评分
return ratSimTotal/simTotal

四、排序获取最后的推荐结果

# recommend()函数,就是推荐引擎,它默认调用 svdEst()函数,产生了最高的N个推荐结果
# 如果不指定N的大小,则默认值为3,该函数另外的参数该包括相似度计算方法和估计方法
def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=svdEst):
"""recommend()
Args:
dataMat 训练数据集
user 用户编号
simMeas 相似度计算方法
estMethod 使用的推荐算法
Returns:
返回最终N个推荐结果
"""
# 寻找未评级的物品
# 对给定用户建立一个未评分的物品列表
unratedItems = nonzero(dataMat[user, :].A == 0)[1]
# 如果不存在未评分物品,那么就退出函数
if len(unratedItems) == 0:
return 'you rated everything'
# 物品的编号和评分值
itemScores = []
for item in unratedItems:
# 获取 item 该物品的评分
estimatedScore = estMethod(dataMat, user, simMeas, item)
itemScores.append((item, estimatedScore))
# 按照评分得分,进行逆排序,获取前N个未评级物品进行推荐
return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[: N]
myMat = mat(loadExData2())
recommend(myMat, 1, simMeas=pearsSim)
[(4, 3.346952186702173), (9, 3.33537965732747), (6, 3.3071930278130366)]
这表明用户1(从0开始计数,对应是矩阵第2行),对物品4的预测评分为3.34,对物品9预测评分为3.33,对物品6预测评分为3.30
试试另一种相似度
recommend(myMat, 1, simMeas=cosSim)
[(4, 3.344714938469228), (7, 3.3294020724526967), (9, 3.3281008763900686)]

利用SVD-推荐未尝过的菜肴2的更多相关文章

  1. 利用SVD-推荐未尝过的菜肴

    推荐未尝过的菜肴-基于物品相似度的推荐 推荐系统的工作过程:给定一个用户,系统会为此用户返回N个最好的推荐菜 1. 寻找用户没有评级的菜肴,即在用户-物品矩阵中的0值 2. 在用户没有评级的所有物品中 ...

  2. 《机器学习实战》学习笔记——第14章 利用SVD简化数据

    一. SVD 1. 基本概念: (1)定义:提取信息的方法:奇异值分解Singular Value Decomposition(SVD) (2)优点:简化数据, 去除噪声,提高算法的结果 (3)缺点: ...

  3. 【机器学习实战】第14章 利用SVD简化数据

    第14章 利用SVD简化数据 SVD 概述 奇异值分解(SVD, Singular Value Decomposition): 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征.从生 ...

  4. 机器学习实战 - 读书笔记&lpar;14&rpar; - 利用SVD简化数据

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第14章 - 利用SVD简化数据. 这里介绍,机器学习中的降维技术,可简化样品数据. 基 ...

  5. 机器学习——利用SVD简化数据

    奇异值分解(Singular Value Decompositon,SVD),可以实现用小得多的数据集来表示原始数据集. 优点:简化数据,取出噪声,提高算法的结果 缺点:数据的转换可能难以理解 适用数 ...

  6. 《机器学习实战》学习笔记第十四章 —— 利用SVD简化数据

    相关博客: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) <机器学习实战>学习笔记第十三章 —— 利用PCA来简化数据 奇异值分解(SVD)原理与在降维中的应用 机器学习( ...

  7. 利用奇异值分解(SVD)简化数据

    特征值与特征向量 下面这部分内容摘自:强大的矩阵奇异值分解(SVD)及其应用 特征值分解和奇异值分解在机器学习领域都是属于满地可见的方法.两者有着很紧密的关系,在接下来会谈到,特征值分解和奇异值分解的 ...

  8. 机器学习实战 &lbrack;Machine learning in action&rsqb;

    内容简介 机器学习是人工智能研究领域中一个极其重要的研究方向,在现今的大数据时代背景下,捕获数据并从中萃取有价值的信息或模式,成为各行业求生存.谋发展的决定性手段,这使得这一过去为分析师和数学家所专属 ...

  9. SVD在餐馆菜肴推荐系统中的应用

    SVD在餐馆菜肴推荐系统中的应用 摘要:餐馆可以分为很多类别,比如中式.美式.日式等等.但是这些类别不一定够用,有的人喜欢混合类别.对用户对菜肴的点评数据进行分析,可以提取出区分菜品的真正因素,利用这 ...

随机推荐

  1. FFT的分析以及matlab实验

    FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换(DFT)的快速算法. 采样得到的数字信号,做FFT变换,N个采样点,经过FFT之后,就可以得到N个点 ...

  2. extern的用法

    extern作为外部函数声明的用法: 1. 可以扩展函数的应用范围: 107.h #ifndef _107H_ #def _107H_ extern void func(); #endif 107.c ...

  3. Qt5&plus;VS2012编程

    安装配置 http://www.bogotobogo.com/Qt/Qt5_Visual_Studio_Add_in.php Qt5+GL http://qt-project.org/doc/qt-5 ...

  4. 由Spring框架中的单例模式想到的

    单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例 注:Spring源码的版本4.3.4 Spring依赖注入Bean实例默认 ...

  5. 【原创】大叔问题定位分享(3)Kafka集群broker进程逐个报错退出

    kafka0.8.1 一 问题现象 生产环境kafka服务器134.135.136分别在10月11号.10月13号挂掉: 134日志 [2014-10-13 16:45:41,902] FATAL [ ...

  6. MapperScan和ComponentScan同时使用问题

    @MapperScan:1.首先了解@Mapper    在接口上添加了@Mapper,在编译之后就会生成相应的接口实现类.    不过需要在每个接口上面进行配置,为了简化开发,就有了 @Mapper ...

  7. HDU 2516 斐波那契博弈

    点这里去看题 n为斐波那契数时,先手败,推断方法见算法讲堂 #include<bits/stdc++.h> using namespace std; int main() { ],i,n, ...

  8. 方差&plus;标准差&plus;四分位数&plus;z-score公式

    一.方差公式 $S^2 = \frac{1}{N}\sum_{i=1}^{N}(X_i - \mu)^2 = \frac{1}{N}[(X_1-\mu)^2 + (X_2-\mu)^2 + ... + ...

  9. Integer Array Ladder questions

    1.这个题不难,关键在于把题目意思理解好了.这个题问的不清楚.要求return new length,很容易晕掉.其实就是return 有多少个单独的数. import java.util.Array ...

  10. c&num;读取Sybase中文乱码的解决办法

    最近需要从Sybase数据库中获取数据.用Sybase.Data.AseClient连接的话比较简单,但中文数据会有乱码.用Sybase自带的工具SQL Advantage设置好编码和语言,是可以正常 ...