天天看點

【機器學習中的矩陣分解】LU分解、QR分解、SVD分解

學習總結

文章目錄

  • ​​學習總結​​
  • ​​一、三角分解(LU分解)​​
  • ​​1.1 高斯消元​​
  • ​​1.2 LU分解原理​​
  • ​​1.3 LU分解python代碼​​
  • ​​1.4 LU分解算法​​
  • ​​二、QR分解​​
  • ​​2.1 Schmid 正交化​​
  • ​​2.2 使用 Schmid 施密特正交化過程求 QR 分解​​
  • ​​2.3 QR分解的栗子​​
  • ​​三、SVD分解​​
  • ​​3.1 SVD定義​​
  • ​​3.2 SVD基本理論​​
  • ​​(1)線性變換​​
  • ​​(2)SVD推導(略)​​
  • ​​(3)SVD栗子​​
  • ​​四、SVD圖像壓縮​​
  • ​​五、SVD手寫體識别​​
  • ​​Reference​​

一、三角分解(LU分解)

1.1 高斯消元

1.2 LU分解原理

1.3 LU分解python代碼

1.4 LU分解算法

二、QR分解

2.1 Schmid 正交化

2.2 使用 Schmid 施密特正交化過程求 QR 分解

2.3 QR分解的栗子

三、SVD分解

3.1 SVD定義

Singular Value Decomposition。

SVD是一種基于矩陣分解的,提取資訊的強大工具,能夠發現資料中的潛在模式。應用領域比如:

  • 隐性語義分析 (Latent Semantic Analysis, LSA) 或隐性語義索引 (Latent Semantic Indexing, LSI);
  • 推薦系統 (Recommender system),可以說是最有價值的應用點(不過現在推薦系統很多都是基于深度學習模型);
  • 矩陣形式資料(主要是圖像資料)的壓縮。

3.2 SVD基本理論

(1)線性變換

以2×2的線性變換矩陣為例,現在有一個對角矩陣

對角矩陣M是将二維平面上的點(x,y)經過線性變換到另一個點的變換矩陣(變換效果:平面沿着x水準方向進行3倍拉伸,垂直方向沒變化):

(2)SVD推導(略)

從幾何角度了解二維SVD:借助SVD可将一個互相垂直的網絡(orthogonal grid)變換到另一個互相垂直的網絡。

【機器學習中的矩陣分解】LU分解、QR分解、SVD分解

實際應用中,我們僅需保留着三個比較小的矩陣,就能表示A,不僅節省存儲量,在計算的時候更是減少了計算量。SVD在資訊檢索(隐性語義索引)、圖像壓縮、推薦系統、金融等領域都有應用。

(3)SVD栗子

其中正交矩陣的特征值和特征向量的求解可以複習線性代數。

【機器學習中的矩陣分解】LU分解、QR分解、SVD分解
【機器學習中的矩陣分解】LU分解、QR分解、SVD分解

四、SVD圖像壓縮

(1)下載下傳​

​cv2​

​​:​

​pip install opencv-python​

​。

(2)其中​

​np.linalg.svd(a, full_matrices=1, compute_uv=1)​

​函數:

  • input參數:
  • ​a​

    ​是一個形如(M,N)矩陣
  • ​full_matrices​

    ​的取值是為0或者1,預設值為1,這時u的大小為(M,M),v的大小為(N,N) 。否則u的大小為(M,K),v的大小為(K,N) ,K=min(M,N)。
  • ​compute_uv​

    ​的取值是為0或者1,預設值為1,表示計算u,s,v。為0的時候隻計算s。
  • output參數(三個):
  • u大小為(M,M),s大小為(M,N),v大小為(N,N)。
  • A = usv
  • 其中s是對矩陣a的奇異值分解。s除了對角元素不為0,其他元素都為0,并且對角元素從大到小排列。s中有n個奇異值,一般排在後面的比較接近0,是以僅保留比較大的r個奇異值。

(3)​

​numpy.stack​

​​函數:将多個數組進行堆疊,按照指定的次元,可參考​​部落格​​。

# -*- coding: utf-8 -*-
"""
Created on Sat Dec 11 23:14:35 2021

@author: 86493
"""
import cv2
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt

#轉為u8類型
def restore1(u, sigma, v, k):
    
    m = len(u)
    n = len(v)
    a = np.zeros((m, n))
    a = np.dot(u[:, :k], np.diag(sigma[:k])).dot(v[:k, :])
    # s1 =  np.size(u[:, :k])
    # s1+= np.size(np.diag(sigma[:k]))
    # s1+= np.size(np.diag(v[:k, :]))
    # s2 = np.size(a)
    # print("壓縮率:",s1/s2)
    a[a < 0] = 0
    a[a > 255] = 255
    return np.rint(a).astype('uint8')

def SVD(frame,K=10):
    a = np.array(frame)
    #由于是彩色圖像,是以3通道。a的最内層數組為三個數,分别表示RGB,用來表示一個像素
    u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
    u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
    u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])

    
    R = restore1(u_r, sigma_r, v_r, K)
    G = restore1(u_g, sigma_g, v_g, K)
    B = restore1(u_b, sigma_b, v_b, K)
    I = np.stack((R, G, B), axis = 2)
    return I
      

if __name__ == "__main__":
    mpl.rcParams['font.sans-serif'] = [u'simHei']
    mpl.rcParams['axes.unicode_minus'] = False
    # frame = cv2.imread("./liuyifei.bmp",-1)
    frame = cv2.imread("pig.jpg",-1)
    I = SVD(frame,40)
    plt.imshow(I)
    cv2.imwrite("out.bmp",I)      

原圖為:

【機器學習中的矩陣分解】LU分解、QR分解、SVD分解

圖像壓縮後的圖為:

五、SVD手寫體識别

Reference