标签:系统 降维 str compress original 理解 关系 一个 class
SVD(Singular Value Decomposition,奇异值分解)是一种强大的降维工具
??
很多情况下,数据的一小段携带了大部分信息,其他要么是噪声,要么就是毫不相关的信息,SVD 是矩阵分解的一种,可以把 SVD 看成是从噪声数据中抽取相关特征
??
优点:简化数据,去除噪声,提高算法的结果
缺点:数据的转换可能难以理解
??
应用例子
??隐性语义索引
??推荐系统
??
SVD 将原始的数据集矩阵 \(\small Data\) 分解成三个矩阵 \(\small U\)、\(\small Σ\)、\(\small V^{T}\)
如果原矩阵 \(\small Data\) 是 m 行 n 列,那么 \(\small U\)、\(\small Σ\)、\(\small V^{T}\) 分别是 m 行 m 列、m 行 n 列、n 行 n 列
??
??\(\small Data(m,n) = U(m,m) \times Σ(m,n) \times V^{T}(n,n)\)
??
\(\small Σ\) 矩阵只有对角元素,其他元素均为 0,非 0 元素的个数是 m 或 n (取小的那个)
\(\small Σ\) 的对角元素是从大到小排列的,这些对角元素称为奇异值 (Singular Value),它们对应了原始数据集矩阵 \(\small Data\) 的奇异值,奇异值和特征值是有关系的,这里的奇异值是矩阵 \(\small Data \times Data^{T}\) 的特征值的平方根
??
在科学和工程中,一直存在这样一个普遍事实:在某个奇异值的数目(r个)之后,其他的奇异值都置为 0,这就意味着数据集中仅有 r 个重要特征,而其余特征则都是噪声或冗余特征
??
numpy 解奇异矩阵
"""
data 如果不是矩阵的话,需要通过 np.mat() 函数转换为矩阵
Sigma 以行向量返回,但其代表的是矩阵,维度 m*n
因为该矩阵除了对角线外都是 0,所以用一行代表对角线上的每个值,节省空间
将 Sigma 转换为矩阵
if m > n:
Sigma = np.mat(np.eye(n)*Sigma)
Sigma = np.row_stack((Sigma, np.zeros((m-n,n))))
elif m < n:
Sigma = np.mat(np.eye(m)*Sigma)
Sigma = np.column_stack((Sigma, np.zeros((m,n-m))))
结果满足 data = U * Sigma * VT
"""
U,Sigma,VT = np.linalg.svd(data)
\(\small Σ\) 取前 r 个值,则有
??\(\small Data(m,n) \approx U(m,r) \times Σ(r,r) \times V^{T}(r,n)\)
??
确定要保留的奇异值的数目有很多启发式的策略
??
其中一个典型的做法就是保留矩阵中 90% 的能量信息
将所有的奇异值求平方和,将奇异值的平方和累加到总值的 90% 为止
??
另一个启发式策略就是,当矩阵上有上万的奇异值时,那么就保留前面的 2000 或 3000 个
??
假设 \(\small data\) 每行是用户,每列是物品
则 \(\small V^{T}\) 矩阵会将用户映射到物品分类空间去
类似地 \(\small U\) 矩阵会将物品映射到物品分类空间去
??
基于 SVD 的图像压缩
# coding=utf-8
import numpy as np
def imgCompress(numSV=3, thresh=0.8):
"""
numSV - 保留的奇异值数目
thresh - 阀值,大于这个值当成 1
"""
myl = []
# 将图片读入存储在矩阵中,假设是黑白只有 01 值
for line in open('0_5.txt').readlines():
newRow = []
for i in range(32):
newRow.append(int(line[i]))
myl.append(newRow)
myMat = np.mat(myl)
print "****original matrix******"
printMat(myMat, thresh)
# 求解奇异值矩阵
U, Sigma, VT = np.linalg.svd(myMat)
SigRecon = np.mat(np.zeros((numSV, numSV)))
for k in range(numSV):
# 将 Sigma 转换为 numSV 阶矩阵
SigRecon[k, k] = Sigma[k]
# 通过奇异值矩阵降维
reconMat = U[:, :numSV] * SigRecon * VT[:numSV, :]
print "****reconstructed matrix using %d singular values******" % numSV
printMat(reconMat, thresh)
def printMat(inMat, thresh=0.8):
for i in range(32):
for k in range(32):
if float(inMat[i, k]) > thresh:
print 1,
else:
print 0,
print ''
??
标签:系统 降维 str compress original 理解 关系 一个 class
原文地址:https://www.cnblogs.com/moonlight-lin/p/12494265.html