svd降维 python案例_聊聊SVD(奇异值分解)降维

SVD(Singular Value Decomposition,奇异值分解)是机器学习领域中很常用的算法;比如在文本分类场景中,在求解完语料的Tfidf后,紧跟着会进行SVD降维,然后建模。另外在推荐系统、自然语言处理等领域中均有应用;今天主要聊一聊SVD的降维。

下图展示了一个利用SVD对图片压缩降噪的例子;在取不同比例奇异值时,图片信息的损失变化情况不同。在取80%奇异值时,原图片整体表现清晰,轮廓明显;60%奇异值时,信息损失较大,人脸已不太清楚,但图片人物整体轮廓依旧明显;通过降维使得图片保留了主要信息而剔除掉了很多不重要的数据。

那么究竟什么是SVD?

SVD是对矩阵进行分解,假如待分解的矩阵A是一个

矩阵,那么对矩阵A的SVD分解即:

其中U是一个

的矩阵;Σ是一个

的矩阵,Σ除了主对角线上的元素以外其他元素全为0,主对角线上元素称为奇异值;V是一个

矩阵。为了更容易理解,我绘制了下图:

那么如何求解奇异值?

更详细的推导过程,读者可以参考链接:

此处不再对原理做过多阐述,主要从python实现上结合例子给大家展示。

如何快速上手?

基于开头图片处理的例子,我们可以利用PIL.Image和numpy.linalg.svd来实现操作,具体是

from PIL import Image

import numpy as np

import matplotlib.pyplot as plt

def rebuild_img(u, sigma, v, p):

"""u:矩阵Usigma:矩阵sigmav:矩阵Vp:奇异值的百分比"""

a = np.zeros((len(u), len(v))) # a是sigma矩阵的空壳

count = (int)(sum(sigma)) # 统计所有奇异值之和,方便后续按其计算百分比

m,k = 0,0

while m <= count * p:

a[k,k] = sigma[k]

m += sigma[k]

k += 1

a = np.dot(np.dot(u,a),v) # 矩阵计算

a = np.clip(a,0,255)

return np.rint(a).astype("uint8")

b = np.array(Image.open('/.../dota2/火女.jpg', 'r'))

for p in np.arange(0.0, 1.2, 0.2):

u, sigma, v = np.linalg.svd(b[:, :, 0])

R = rebuild_img(u, sigma, v, p)

u, sigma, v = np.linalg.svd(b[:, :, 1])

G = rebuild_img(u, sigma, v, p)

u, sigma, v = np.linalg.svd(b[:, :, 2])

B = rebuild_img(u, sigma, v, p)

I = np.stack((R, G, B), 2)

plt.figure("beauty")

plt.imshow(I)

plt.axis('off')

plt.show() # 绘图输出

从公式或者代码示例中都可以看出,SVD在计算过程中原矩阵的维度其实是不变的 ,但是在取n%的奇异值时,重新计算回去的原矩阵中元素值显著降低,秩也降低,整体来看数据得到了压缩和衰减;或许这一称之为一种降维吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值