Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
Ailearning
提交
86cd3f89
A
Ailearning
项目概览
OpenDocCN
/
Ailearning
大约 1 年 前同步成功
通知
12
Star
36240
Fork
11272
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
Ailearning
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
86cd3f89
编写于
9月 14, 2020
作者:
片刻小哥哥
提交者:
GitHub
9月 14, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #607 from jiangzhonglian/master
更新 py3.x - SVD的文档和SVD中降维和压缩在数据上不同的说明
上级
a576e391
4702b55f
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
75 addition
and
32 deletion
+75
-32
docs/ml/14.利用SVD简化数据.md
docs/ml/14.利用SVD简化数据.md
+6
-1
src/py3.x/ml/14.SVD/svdRecommend.py
src/py3.x/ml/14.SVD/svdRecommend.py
+69
-31
未找到文件。
docs/ml/14.利用SVD简化数据.md
浏览文件 @
86cd3f89
...
...
@@ -259,7 +259,12 @@ def svdEst(dataMat, user, simMeas, item):
# 如果要进行矩阵运算,就必须要用这些奇异值构建出一个对角矩阵
Sig4
=
mat
(
eye
(
4
)
*
Sigma
[:
4
])
# 利用U矩阵将物品转换到低维空间中,构建转换后的物品(物品+4个主要的特征)
# 利用U矩阵将物品转换到低维空间中,构建转换后的物品(物品+4个主要的“隐形”特征)
# 公式1(目的是: 降维-改变形状,也改变大小) xformedItems = dataMat.T * U[:, :4] * Sig4.I
# 公式2(目的是: 压缩-不改变形状,改变大小) reconMat = U[:, :4] * Sig4.I * VT[:4, :]
# 其中: imgCompress() 是详细的案例
# 最近看到一篇文章描述,感觉挺有道理的,我就顺便补充一下注释: https://blog.csdn.net/qq_36523839/article/details/82347332
xformedItems
=
dataMat
.
T
*
U
[:,
:
4
]
*
Sig4
.
I
# 对于给定的用户,for循环在用户对应行的元素上进行遍历,
# 这和standEst()函数中的for循环的目的一样,只不过这里的相似度计算时在低维空间下进行的。
...
...
src/py3.x/ml/14.SVD/svdRecommend.py
浏览文件 @
86cd3f89
...
...
@@ -13,17 +13,30 @@ from numpy import *
def
loadExData3
():
# 利用SVD提高推荐效果,菜肴矩阵
# 可以修改原数据集合,用对对比
# return[[2, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5],
# [0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 0],
# [3, 3, 4, 0, 3, 0, 0, 2, 2, 0, 0],
# [5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 5, 0, 0, 5, 0],
# [4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5],
# [0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4],
# [0, 0, 0, 0, 0, 0, 5, 0, 0, 5, 0],
# [0, 0, 0, 3, 0, 0, 0, 0, 4, 5, 0],
# [1, 1, 2, 1, 1, 2, 1, 0, 4, 5, 0]]
# 修改后的数据(增加了第1道菜和最后1到菜,同时有3个人吃,从而计算基于物品的协同过滤效果,原来才一个人)
return
[[
2
,
0
,
0
,
4
,
4
,
0
,
0
,
0
,
0
,
0
,
0
],
[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
5
],
[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
4
,
0
],
[
3
,
3
,
4
,
0
,
3
,
0
,
0
,
2
,
2
,
0
,
0
],
[
3
,
3
,
4
,
0
,
3
,
0
,
0
,
2
,
2
,
0
,
8
],
[
5
,
5
,
5
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
[
0
,
0
,
0
,
0
,
0
,
0
,
5
,
0
,
0
,
5
,
0
],
[
4
,
0
,
4
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
5
],
[
0
,
0
,
0
,
0
,
0
,
4
,
0
,
0
,
0
,
0
,
4
],
[
0
,
0
,
0
,
0
,
0
,
0
,
5
,
0
,
0
,
5
,
0
],
[
0
,
0
,
0
,
3
,
0
,
0
,
0
,
0
,
4
,
5
,
0
],
[
1
,
1
,
2
,
1
,
1
,
2
,
1
,
0
,
4
,
5
,
0
]]
[
1
,
1
,
2
,
1
,
1
,
2
,
1
,
0
,
4
,
5
,
6
]]
def
loadExData2
():
...
...
@@ -114,15 +127,28 @@ def standEst(dataMat, user, simMeas, item):
continue
# 寻找两个用户都评级的物品
# 变量 overLap 给出的是两个物品当中已经被评分的那个元素的索引ID
# logical_and 计算x1和x2元素的真值。
# logical_and 计算x1和x2元素的为True就为True(也就是列的值同时>0), 否则就为False
# item(0): [[ True] [False] [False] [ True] [ True] [False] [ True] [False] [False] [False] [ True]]
# j(10): [[False] [ True] [False] [False] [False] [False] [ True] [ True] [False] [False] [False]]
# +1-- [[False] [False] [False] [False] [False] [False] [ True] [False] [False] [False] [False]]
# +2-- [6]
# print("+++ item(%s): %s --- j(%s): %s" % (item, dataMat[:, item].A > 0, j, dataMat[:, j].A > 0))
# print("+1-- %s" % logical_and(dataMat[:, item].A > 0, dataMat[:, j].A > 0) )
# print("+2-- %s" % overLap)
overLap
=
nonzero
(
logical_and
(
dataMat
[:,
item
].
A
>
0
,
dataMat
[:,
j
].
A
>
0
))[
0
]
# 如果相似度为0,则两着没有任何重合元素,终止本次循环
if
len
(
overLap
)
==
0
:
similarity
=
0
# 如果存在重合的物品,则基于这些重合物重新计算相似度。
else
:
# print("-%s- %s:%s -- %s:%s" % (overLap, item, dataMat[overLap, item], j, dataMat[overLap, j]) )
# 如果 overLap 长度是为3,说明3个人同时吃了 菜A并且也同时吃了菜B
# 那么就要找对 这3个人对应 菜评分的矩阵
# -[ 3 6 10](人)- 0(菜):[[3] [4] [1]] -- 10(菜):[[8] [5] [6]]
# 然后就可以计算出来两个菜之间的相似度
similarity
=
simMeas
(
dataMat
[
overLap
,
item
],
dataMat
[
overLap
,
j
])
# print('the %d and %d similarity is : %f'(iten,j,
similarity))
print
(
'the %d and %d similarity is : %f'
%
(
item
,
j
,
similarity
))
# 相似度会不断累加,每次计算时还考虑相似度和当前用户评分的乘积
# similarity 用户相似度, userRating 用户评分
simTotal
+=
similarity
...
...
@@ -161,13 +187,17 @@ def svdEst(dataMat, user, simMeas, item):
# 如果要进行矩阵运算,就必须要用这些奇异值构建出一个对角矩阵
Sig4
=
mat
(
eye
(
4
)
*
Sigma
[:
4
])
# 利用U矩阵将物品转换到低维空间中,构建转换后的物品(物品+4个主要的特征)
# 利用U矩阵将物品转换到低维空间中,构建转换后的物品(物品+4个主要的“隐形”特征)
# 公式1(目的是: 降维-改变形状,也改变大小) xformedItems = dataMat.T * U[:, :4] * Sig4.I
# 公式2(目的是: 压缩-不改变形状,改变大小) reconMat = U[:, :4] * Sig4.I * VT[:4, :]
# 其中: imgCompress() 是详细的案例
# 最近看到一篇文章描述,感觉挺有道理的,我就顺便补充一下注释: https://blog.csdn.net/qq_36523839/article/details/82347332
xformedItems
=
dataMat
.
T
*
U
[:,
:
4
]
*
Sig4
.
I
print
(
'dataMat'
,
shape
(
dataMat
))
print
(
'U[:, :4]'
,
shape
(
U
[:,
:
4
]))
print
(
'Sig4.I'
,
shape
(
Sig4
.
I
))
print
(
'VT[:4, :]'
,
shape
(
VT
[:
4
,
:]))
print
(
'xformedItems'
,
shape
(
xformedItems
))
#
print('dataMat', shape(dataMat))
#
print('U[:, :4]', shape(U[:, :4]))
#
print('Sig4.I', shape(Sig4.I))
#
print('VT[:4, :]', shape(VT[:4, :]))
#
print('xformedItems', shape(xformedItems))
# 对于给定的用户,for循环在用户对应行的元素上进行遍历
# 这和standEst()函数中的for循环的目的一样,只不过这里的相似度计算时在低维空间下进行的。
...
...
@@ -203,6 +233,11 @@ def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
返回最终 N 个推荐结果
"""
# 寻找未评级的物品
# nonzero(a)函数一般返回两行array()。如果mat()一下,就是个2*N 的矩阵
# 其中 (array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
# 例如: 上下取出来的数据(0, 0) 表示在矩阵的横纵坐标(行、列)的位置
# 由于是2为矩阵,所以 [1] 就是矩阵列,也就是商品ID的为主
# 对给定的用户建立一个未评分的物品列表
unratedItems
=
nonzero
(
dataMat
[
user
,
:].
A
==
0
)[
1
]
# 如果不存在未评分物品,那么就退出函数
...
...
@@ -328,25 +363,28 @@ if __name__ == "__main__":
# 计算相似度的方法
myMat
=
mat
(
loadExData3
())
# print(myMat)
# 计算相似度的第一种方式
print
(
recommend
(
myMat
,
1
,
estMethod
=
svdEst
))
# 计算相似度的第二种方式
print
(
recommend
(
myMat
,
1
,
estMethod
=
svdEst
,
simMeas
=
pearsSim
))
# 默认推荐(菜馆菜肴推荐示例)
print
(
recommend
(
myMat
,
2
))
"""
# 利用SVD提高推荐效果
U, Sigma, VT = la.svd(mat(loadExData2()))
print(Sigma) # 计算矩阵的SVD来了解其需要多少维的特征
Sig2 = Sigma**2 # 计算需要多少个奇异值能达到总能量的90%
print(sum(Sig2)) # 计算总能量
print(sum(Sig2) * 0.9) # 计算总能量的90%
print(sum(Sig2[: 2])) # 计算前两个元素所包含的能量
print(sum(Sig2[: 3])) # 两个元素的能量值小于总能量的90%,于是计算前三个元素所包含的能量
# 该值高于总能量的90%,这就可以了
"""
# 压缩图片
# imgCompress(2)
\ No newline at end of file
# 方式1: 基于物品的协同过滤,通过余弦相似度计算相似度
# print(recommend(myMat, 1))
# 方式2: 基于SVD,通过余弦相似度计算相似度
print
(
recommend
(
myMat
,
1
,
estMethod
=
svdEst
))
# 方式3:
# print(recommend(myMat, 1, estMethod=svdEst, simMeas=pearsSim))
# # 默认推荐(菜馆菜肴推荐示例)
# print(recommend(myMat, 2))
# """
# # 利用SVD提高推荐效果
# U, Sigma, VT = la.svd(mat(loadExData2()))
# print(Sigma) # 计算矩阵的SVD来了解其需要多少维的特征
# Sig2 = Sigma**2 # 计算需要多少个奇异值能达到总能量的90%
# print(sum(Sig2)) # 计算总能量
# print(sum(Sig2) * 0.9) # 计算总能量的90%
# print(sum(Sig2[: 2])) # 计算前两个元素所包含的能量
# print(sum(Sig2[: 3])) # 两个元素的能量值小于总能量的90%,于是计算前三个元素所包含的能量
# # 该值高于总能量的90%,这就可以了
# """
# # 压缩图片
# # imgCompress(2)
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录