鲁棒主成分分析RPCA

WHY?

传统的PCA算法对于噪音敏感,于是有人提出了RPCA将一个含有稀疏噪声的数据矩阵分解为低秩矩阵和稀疏噪音矩阵两部分。

WHAT?

鲁棒主成分分析RPCA_第1张图片

HOW?

鲁棒主成分分析RPCA_第2张图片
鲁棒主成分分析RPCA_第3张图片
鲁棒主成分分析RPCA_第4张图片

CODE

import numpy as np
import pandas as pd
'''
 Y数据矩阵
 alpha 步长
 pre 收敛的精度
 r 低秩为多少
'''
def  RPCA(Y,alpha=0.75,pre=0.117,r=245):
    m,n =Y.shape
    #先对Y进行奇异值分解,选取前r个奇异值与前r个
    #左奇异向量的乘积初始化 U,选取前 r个奇异值与前 r个右奇 
    #异向量的乘积初始化V
    U,sigma,VT = np.linalg.svd(Y)
    sigma = np.diag(sigma[0:r])
    U=U[:,0:r]
    V=VT.T[:,0:r]
    U = U @ sigma
    V = V @ sigma
    #稀疏矩阵S为0矩阵
    S =np.zeros((m,n))
    #软阈值函数
    def sorft(a,b):
        if a > b:
            return a - b
        elif a < -b:
            return a + b
        else:
            return 0.0
    i = 0        
    while True:
        i += 1
        #计算T= Y - UVT
        T = Y -U @ V.T
        #计算软阈值
        labda =np.sum(np.abs(T)) * 1.0 * alpha / (m * n)
        #迭代S
        S = pd.DataFrame(T.copy()).applymap(lambda x:sorft(x,labda)).values
        #海森矩阵
        Uh = V.T @ V
        Vh = U.T @ U
        #牛顿迭代
        E = T - S
        U_new= U + E @ V @ np.linalg.inv(Uh)
        V_new= V + E.T @ U @ np.linalg.inv(Vh)
        U = U_new
        V = V_new
        #收敛判断
        L =np.sqrt(np.sum((U @ V.T + S - Y)**2))
        R =np.linalg.norm(S,1)
        Total =np.sqrt(np.sum(Y**2))
        loss =  (L + R) / Total
        if i%10 ==0:
            print(("loss: %f")%(loss))
        if loss < pre:
            break
    return [U,V,S]

EXP

from PIL import Image
import matplotlib.pyplot as plt

im = np.array(Image.open('1.jpg').convert('L'),dtype='float32') /255
U,V,S = RPCA(im)

_,figs = plt.subplots(1,3,figsize=(15,15))
figs[0].imshow(im)
figs[0].set_title('Original')
figs[1].imshow(S)
figs[1].set_title('Noise')
figs[2].imshow(im - S)
figs[2].set_title('After')
for i in range(3):
    figs[i].axes.get_xaxis().set_visible(False)
    figs[i].axes.get_yaxis().set_visible(False)
    
plt.show()

鲁棒主成分分析RPCA_第5张图片

你可能感兴趣的:(降维,线性代数,机器学习,python)