奇異值分解 (Singular Value Decomposition)SVD 簡單手算範例+PYTHON範例
奇異值分解 (Singular Value Decomposition)SVD 簡單手算範例+PYTHON範例
資料來源:
https://www.cnblogs.com/pinard/p/6251584.html
https://www.itread01.com/content/1545298204.html
https://blog.csdn.net/u012421852/article/details/80439403
GUTHUB: https://github.com/jash-git/Singular-Value-Decomposition
# -*- coding: utf-8 -*- """ @author: 蔚蓝的天空Tom Talk is cheap, show me the code Aim:svd分解降维应用示例的代码实现 CSDN URL:https://mp.csdn.net/postedit/80450590 """ import numpy as np from numpy import linalg as LA class CSVD(object): ''' 实现SVD分解降维应用示例的数学求解过程的Python代码 ''' def __init__(self, data): self.data = data #用户数据 self.S = [] #用户数据矩阵的奇异值序列 singular values self.U = [] #svd后的单位正交向量 self.VT = [] #svd后的单位正交向量 self.k = 0 #满足self.p的最小k值(k表示奇异值的个数) self.SD = [] #对角矩阵,对角线上元素是奇异值 singular values diagonal matrix #svd奇异值分解 self._svd() def _svd(self): ''' 用户数据矩阵的svd奇异值分解 ''' u,s,v = np.linalg.svd(self.data) (self.U, self.S, self.VT) = (u, s, v) return self.U, self.S, self.VT def _calc_k(self, percentge): '''确定k值:前k个奇异值的平方和占比 >=percentage, 求满足此条件的最小k值 :param percentage, 奇异值平方和的占比的阈值 :return 满足阈值percentage的最小k值 ''' self.k = 0 #用户数据矩阵的奇异值序列的平方和 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]) if (svss/total) >= percentge: self.k = i+1 break return self.k def _buildSD(self, k): '''构建由奇异值组成的对角矩阵 :param k,根据奇异值开放和的占比阈值计算出来的k值 :return 由k个前奇异值组成的对角矩阵 ''' #方法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 DimReduce(self, percentage): ''' SVD降维 :param percentage, 奇异值开方和的占比阈值 :return 降维后的用户数据矩阵 ''' #计算k值 self._calc_k(percentage) print('\n按照奇异值开方和占比阈值percentage=%d, 求得降维的k=%d'%(percentage, self.k)) #构建由奇异值组成的对角矩阵singular values diagonal self._buildSD(self.k) k,U,SD,VT = self.k,self.U, self.SD, self.VT #按照svd分解公式对用户数据矩阵进行降维,得到降维压缩后的数据矩阵 print('\n降维前的U,S,VT依次为:') print(np.shape(U), 'U:\n', U) print(np.shape(self.S), 'S:\n', self.S) print(np.shape(VT), 'VT:\n', VT) print('\n降维后的U,SD,VT依次为:') print(np.shape(U[:len(U),k]), 'U=U[:%d,:%d]:\n'%(len(U),k), U[:len(U), :k]) print(np.shape(SD), 'SD=SD[:%d, :%d]:\n'%(k,k), SD[:k, :k]) print(np.shape(VT[:k, :len(VT)]), 'VT=VT[:%d, :%d]:\n'%(k, len(VT)), VT[:k, :len(VT)]) a = U[:len(U), :k] b = np.dot(SD, VT[:k, :len(VT)]) newData = np.dot(a,b) return newData def CSVD_manual(): ##训练数据集,用户对商品的评分矩阵,行为多个用户对单个商品的评分,列为用户对每个商品的评分 data = np.array([[5, 5, 0, 5], [5, 0, 3, 4], [3, 4, 0, 3], [0, 0, 5, 3], [5, 4, 4, 5], [5, 4, 5, 5]]) percentage = 0.9 svdor = CSVD(data) ret = svdor.DimReduce(percentage) print('====================================================') print('原始用户数据矩阵:\n', data) print('降维后的数据矩阵:\n', ret) print('====================================================') if __name__=='__main__': CSVD_manual()
2 thoughts on “奇異值分解 (Singular Value Decomposition)SVD 簡單手算範例+PYTHON範例”
SVD 降維
程式設計師 最高等級 靠數學