【Python机器学习】利用SVD简化数据——示例:基于SVD的图像压缩

通过可视化的方式,我们可以很容易的看到SVD对数据近似的效果。在代码库中,有一张手写的数字图像。原始的图形大小是32*32=1024像素,我们可以尝试对图像进行压缩,那么就可以节省空间或带宽开销了。

我们可以使用SVD来对数据降维,从而实现图像的压缩。下面我们可以看到利用SVD的手写数字图像的压缩过程:

def printMat(inMat,thresh=0.8):
    for i in range(32):
        for k in range(32):
            if float(inMat[i,k])>thresh:
                print(1, end=' ')
            else:
                print(0, end=' ')
        print('')
def imgCompress(numSV=3,thresh=0.8):
    myl=[]
    for line in open('test/0_5.txt').readlines():
        newRow=[]
        for i in range(32):
            newRow.append(int(line[i]))
        myl.append(newRow)
    myMat=mat(myl)
    print('*****original matrix*****')
    printMat(myMat,thresh)
    U,Sigma,VT=la.svd(myMat)
    SigRecon=mat(zeros((numSV,numSV)))
    for k in range(numSV):
        SigRecon[k,k]=Sigma[k]
    reconMat=U[:,:numSV]*SigRecon*VT[:numSV,:]
    print('*****reconstruced matrix using %d singular values*****' % numSV)
    printMat(reconMat,thresh)

上述代码中第一个函数printMat()的作用是打印矩阵。由于矩阵包含了浮点数,因此必须定义浅色和深色。这里通过一个阈值来界定,后面也可以调节该值。该函数遍历所有的矩阵元素,当元素大于阈值时打印1,否则打印0。

第二个函数实现了图像的压缩。它允许基于任意给定的奇异值数目来重构图像。该函数构建了一个列表,然后打开文本文件,并从文件中以数值方式读入字符。在矩阵调入之后,我们就可以在屏幕上输出该矩阵了。接下来就开始对原始图像进行SVD分解并重构图像。在代码中,通过将Sigma重新构成SigRecon来实现这一点。Sigma是一个对角矩阵,因此需要建立一个全0矩阵,然后将前面的那些奇异值填充到对角线上,最后通过截断的U和V^{T}矩阵,用SigRecon得到重构后的矩阵,该矩阵通过printMat()函数输出。

下面看实际运行效果:

可以看到,只需要两个奇异值就能相当准确地对图像实现重构。U和V^{T}都是32*2的矩阵,有两个奇异值,因此总数字数目是64+64+2=130,和原数目1024相比,压缩比是接近10倍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值