日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

SVD(奇异值分解)Python实现

發(fā)布時間:2024/1/17 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SVD(奇异值分解)Python实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

注:在《SVD(奇異值分解)小結(jié) 》中分享了SVD原理,但其中只是利用了numpy.linalg.svd函數(shù)應(yīng)用了它,并沒有提到如何自己編寫代碼實現(xiàn)它,在這里,我再分享一下如何自已寫一個SVD函數(shù)。但是這里會利用到SVD的原理,如果大家還不明白它的原理,可以去看看《SVD(奇異值分解)小結(jié) 》,或者自行百度/google。

1、SVD算法實現(xiàn)

1.1 SVD原理簡單回顧

有一個\(m \times n\)的實數(shù)矩陣\(A\),我們可以將它分解成如下的形式

\[ A = U\Sigma V^T \tag{1-1} \]

其中\(U\)\(V\)均為單位正交陣,即有\(UU^T=I\)\(VV^T=I\)\(U\)稱為左奇異矩陣,\(V\)稱為右奇異矩陣,\(\Sigma\)僅在主對角線上有值,我們稱它為奇異值,其它元素均為0。上面矩陣的維度分別為\(U \in \mathbf{R}^{m\times m},\ \Sigma \in \mathbf{R}^{m\times n}\),\(\ V \in \mathbf{R}^{n\times n}\)

正常求上面的\(U,V,\Sigma\)不便于求,我們可以利用如下性質(zhì)

\[ AA^T=U\Sigma V^TV\Sigma^TU^T=U\Sigma \Sigma^TU^T \tag{1-2} \]
\[ A^TA=V\Sigma^TU^TU\Sigma V^T=V\Sigma^T\Sigma V^T \tag{1-3} \]

1.2 SVD算法

據(jù)1.1小節(jié),對式(1-3)和式(1-4)做特征值分解,即可得到奇異值分解的結(jié)果。但是樣分開求存在一定的問題,由于做特征值分解的時候,特征向量的正負(fù)號并不影響結(jié)果,比如,我們利用式(1-3)和(1-4)做特征值分解

\[ AA^T\mathbf{u}_i = \sigma_i \mathbf{u}_i\quad \text{or} \quad AA^T(-\mathbf{u}_i) = \sigma_i (-\mathbf{u}_i)\\ A^TA\mathbf{v}_i = \sigma_i \mathbf{v}_i\quad \text{or} \quad A^TA(-\mathbf{v}_i) = \sigma_i (-\mathbf{v}_i) \]

如果在計算過程取,取上面的\(\mathbf{u}_i\)組成左奇異矩陣\(U\),取\(-\mathbf{v}_i\)組成右奇異矩陣\(V\),此時\(A\ne U\Sigma V^T\)。因此求\(\mathbf{v}_i\)時,要根據(jù)\(\mathbf{u}_i\)來求,這樣才能保證\(A= U\Sigma V^T\)。因此,我們可以得出如下1.1計算SVD的算法。它主要是先做特性值分解,再根據(jù)特征值分解得到的左奇異矩陣\(U\)間接地求出部分的右奇異矩陣\(V'\in \mathbf{R}^{m\times n}\)

算法1.1:SVD

輸入:樣本數(shù)據(jù) 輸出:左奇異矩陣,奇異值矩陣,右奇異矩陣
  • 計算特征值: 特征值分解\(AA^T\),其中\(A \in \mathbf{R}^{m\times n}\)為原始樣本數(shù)據(jù)

    \[ AA^T=U\Sigma \Sigma^TU^T \]

    得到左奇異矩陣\(U \in \mathbf{R}^{m \times m}\)和奇異值矩陣\(\Sigma' \in \mathbf{R}^{m \times m}\)

  • 間接求部分右奇異矩陣:\(V' \in \mathbf{R}^{m \times n}\)

    利用\(A=U\Sigma'V'\)可得

    \[ V' = (U\Sigma')^{-1}A = (\Sigma')^{-1}U^TA \tag{1-4} \]

  • 返回\(U,\ \Sigma',\ V'\),分別為左奇異矩陣,奇異值矩陣,右奇異矩陣。

  • 注:這里得到的\(\Sigma'\)\(V'\)與式(1-2)所得到的\(\Sigma,\ V\)有區(qū)別,它們的維度不一樣。\(\Sigma'\)是只取了前\(m\)個奇異值形成的對角方陣,即\(\Sigma' \in \mathbf{R}^{m \times m}\)\(V'\)不是一個方陣,它只取了\(V \in \mathbf{R}^{m \times n}\)的前\(m\)行(假設(shè)\(m < n\)),即有\(V' = V(:m,\cdot)\)。這樣一來,我們同樣有類似式(1-1)的數(shù)學(xué)關(guān)系成立,即
    \[ A = U\Sigma' (V')^T\tag{1-5} \]

    我們可以利用此關(guān)系重建原始數(shù)據(jù)。

    2、SVD的Python實現(xiàn)

    以下代碼的運行環(huán)境為python3.6+jupyter5.4。

    2.1 SVD實現(xiàn)過程

    讀取數(shù)據(jù)

    這里面的數(shù)據(jù)集大家隨便找一個數(shù)據(jù)就好,如果有需要我的數(shù)據(jù)集,可以下在面留言。

    import numpy as np import pandas as pd from scipy.io import loadmat# 讀取數(shù)據(jù),使用自己數(shù)據(jù)集的路徑。 train_data_mat = loadmat("../data/train_data2.mat") train_data = train_data_mat["Data"] print(train_data.shape)

    特征值分解

    # 數(shù)據(jù)必需先轉(zhuǎn)為浮點型,否則在計算的過程中會溢出,導(dǎo)致結(jié)果不準(zhǔn)確 train_dataFloat = train_data / 255.0 # 計算特征值和特征向量 eval_sigma1,evec_u = np.linalg.eigh(train_dataFloat.dot(train_dataFloat.T))

    計算右奇異矩陣

    #降序排列后,逆序輸出 eval1_sort_idx = np.argsort(eval_sigma1)[::-1] # 將特征值對應(yīng)的特征向量也對應(yīng)排好序 eval_sigma1 = np.sort(eval_sigma1)[::-1] evec_u = evec_u[:,eval1_sort_idx] # 計算奇異值矩陣的逆 eval_sigma1 = np.sqrt(eval_sigma1) eval_sigma1_inv = np.linalg.inv(np.diag(eval_sigma1)) # 計算右奇異矩陣 evec_part_v = eval_sigma1_inv.dot((evec_u.T).dot(train_dataFloat))

    上面的計算出的evec_u, eval_sigma1, evec_part_v分別為左奇異矩陣,所有奇異值,右奇異矩陣。

    2.2 SVD降維后重建數(shù)據(jù)

    取不同個數(shù)的奇異值,重建圖片,計算出均方誤差,如圖2-1所示。從圖中可以看出,隨著奇異值的增加,均方誤差(MSE)在減小,且奇異值和的比率正快速上升,在100維時,奇異值占總和的53%。


    圖2-1 奇值分解維度和均方誤差變化圖

    注: 均方誤差MSE有如下計算公式
    \[ \text{MSE} = \frac{1}{n}\left((y_1-y_1')^2+(y_2-y_2')^2+\cdots+(y_n-y_n')^2\right) \]

    我們平時聽到的\(\text{RMSE}=\sqrt{\text{MSE}}\)

    將圖和10、50、100維的圖進(jìn)行比較,如圖2-2所示。在直觀上,100維時,能保留較多的信息,此時能從圖片中看出車輛形狀。


    圖2-2 原圖與降維重建后的圖比較

    總結(jié)

    SVD與特征值分解(EVD)非常類似,應(yīng)該說EVD只是SVD的一種特殊懷況。我們可以通過它們在實際的應(yīng)用中返過來理解特征值/奇異值的含義:特征值/奇異值代表著數(shù)據(jù)的信息量,它的值越大,信息越多。

    最近作業(yè)是真的多呀,冒著生命危險來分享,希望能給大家?guī)韼椭?

    轉(zhuǎn)載于:https://www.cnblogs.com/endlesscoding/p/10058532.html

    總結(jié)

    以上是生活随笔為你收集整理的SVD(奇异值分解)Python实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。