1.SVD奇异值分解的基本原理介绍
参见前面博客:SVD奇异值分解的基本原理介绍
2.Python代码
SVD奇异值分解公式的Python实现比较简单,人肉出品,代码如下所示。
后面博客会给出基于SVD的商品推荐系统的Python实现。
# -*- coding: utf-8 -*-
"""
@author: 蔚蓝的天空Tom
Talk is cheap, show me the code
Aim:svd奇异值分解公式求解的代码实现
"""
import numpy as np
from numpy import linalg as LA
class CSVD(object):
'''
实现svd推荐系统
'''
def __init__(self, data, percentage):
self.data = data #用户数据
self.p = percentage #奇异值平方和占比的阈值
self.S = [] #用户数据矩阵的奇异值序列 singular values
self.U = [] #svd后的单位正交向量
self.V = [] #svd后的单位正交向量,注意self.V是SVD奇异值分解公式USV.T中的V.T,即公式中V矩阵的转置矩阵
self.k = 0 #满足self.p的最小k值(k表示奇异值的个数)
self.SD = [] #对角矩阵,对角线上元素是奇异值 singular values diagonal matrix
self._svd()
self._calc_k()
self._buildSD()
#debug
print('奇异值序列:\n', self.S)
print('k值:', self.k)
print('k阶的奇异值对角矩阵:\n', self.SD)
def _svd(self):
'''
用户数据矩阵的svd奇异值分解
'''
u,s,v = np.linalg.svd(self.data)
(self.U, self.S, self.V) = (u, s, v)
return self.U, self.S, self.V
def _calc_k(self):
'''确定k值:前k个奇异值的平方和占比 >=percentage, 求满足此条件的最小k值
:param percentage, 奇异值平方和的占比的阈值
:return 满足阈值percentage的最小k值
'''
#用户数据矩阵的奇异值序列的平方和
total = sum(np.square(self.S))
#
svss = 0 #奇异值平方和 singular values square sum
for i in range(np.shape(self.S)[0]):
svss += np.square(self.S[i])
print(svss/total)
if (svss/total) >= self.p:
self.k = i+1
return
return self.k
def _buildSD(self):
'''构建由奇异值组成的对角矩阵
'''
#方法1:用数组乘方法
self.SD = np.eye(self.k) * self.S[:self.k]
#方法2:用自定义方法
e = np.eye(self.k)
for i in range(self.k):
e[i,i] = self.S[i]
return self.SD
def CSVD_manual():
##训练数据集,用户对商品的评分矩阵,行为多个用户对单个商品的评分,列为用户对每个商品的评分
data = np.array([[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]])
percentage = 0.8
svdor = CSVD(data, percentage)
if __name__=='__main__':
CSVD_manual()
3.运行结果
用户数据矩阵:
[[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]]
奇异值平方和占比的阈值percentage: 0.8
奇异值序列:
[ 15.77075346 11.40670395 11.03044558 4.84639758 3.09292055
2.58097379 1.00413543 0.72817072 0.43800353 0.22082113
0.07367823]
k值: 3
k阶的奇异值对角矩阵:
[[ 15.77075346 0. 0. ]
[ 0. 11.40670395 0. ]
[ 0. 0. 11.03044558]]
(end)