PythonでNumpyを使った特異値分解(SVD)の方法を解説する

スポンサーリンク

SVD(Singular Value Decomposition)は、次元削減のために広く用いられている手法の1つです。

SVDは、行列を3つの行列に分解します。

行列を空間の線形変換を引き起こすものと見なすと、特異値分解では1つの変換を3つの動きに分解することになります。

この記事では、SVDを実装するさまざまな方法について見ていきます。

スポンサーリンク

特異値分解の基本

SVDは1つの行列をU,D,V*の各行列に分解します。

import numpy as np
 
#Creating a matrix A
A = np.array([[3,4,3],[1,2,3],[4,2,1]])
 
#Performing SVD
U, D, VT = np.linalg.svd(A)
 
#Checking if we can remake the original matrix using U,D,VT
A_remake = (U @ np.diag(D) @ VT)
print(A_remake)

ここで

U と V** は直交行列です。

* Dは特異値を表す対角行列です。

SVDは、1つの複雑な変換を3つの単純な変換(回転、拡大縮小、回転)に分解したものと見ることもできる。

変換の観点からは

  • 行列 U と V* は回転を引き起こす。
  • 対角行列Dはスケーリングになります。

つまり、基本的には元の行列を低ランク行列の線形結合で表現することができるのです。

最初の数個の特異値だけが大きい。

最初の数個以外の項は、情報をあまり失うことなく無視することができるので、SVDは次元削減技術と呼ばれています。

PythonによるSVDの実装

まずはPythonでSVDを実装してみましょう。

複数のライブラリを使って、どのように実装を進めていくかを示していきます。

1. Numpyの使用

Python Numpy はほとんどの線形代数手法を実装することができ、SVD を簡単に実装することができます

numpy.linalgモジュールを使用し、svdクラスを使用して行列のSVDを実行します。

#Importing required modules
import numpy as np
from sklearn.decomposition import TruncatedSVD
 
#Creating array
A = np.array([[3,4,3],[1,2,3],[4,2,1]])
 
#Fitting the SVD class
trun_svd =  TruncatedSVD(n_components = 2)
A_transformed = svd.fit_transform(A)
 
#Printing the transformed matrix
print("Transformed Matrix:")
print(A_transf)
SVD
SVD

D は 2 次元配列ではなく、1 次元配列です。

D はほとんどの値が 0 で終わる対角行列で、このような行列をスパース行列と呼びますが、スペースを節約するために 1 次元配列として返されます。

2. U

まとめ

今回は、Numpyやscikit-learnなどのライブラリを使ってSVD(Singular Value Decomposition)を実装する方法について紹介しました。

タイトルとURLをコピーしました