データ前処理シリーズ:(十二)遮断奇異値で次元を分解する


著作権の所有、転載は作者に連絡してそして出典を明記して下さいhttp://blog.csdn.net/u013719780
博主简介:风雪夜帰子(英语名:Allen)、机械学习アルゴリズム攻城狮、Machine Learningのブラックテクノロジーを研究することが好きで、Deep LearningとArtificial Intelligenceに兴味を持って、kaggleデータマイニングコンテストプラットフォームによく注目して、データ、Machine LearningとArtificial Intelligenceに兴味のある子供靴は一绪に検讨することができます.個人CSDNブログ:http://blog.csdn.net/u013719780?viewmode=contents
切り捨て奇異値で次元を分解する
カットオフ特異値分解(Truncated singular value decomposition,TSVD)はマトリックスMをUに分解するマトリックス因数分解(factorization)技術である.ΣΣとV.PCAに似ていますが、SVD分解はデータマトリクス上で行われ、PCAはデータの共分散マトリクス上で行われます.通常、SVDはマトリックスの主成分を発見するために使用される.
Getting ready
TSVDは、一般的なSVDとは異なり、指定された次元の分解行列を生成することができる.例えば、n×n行列はSVD分解後もn×n行列、TSVDは指定された次元の行列を生成することができる.これで次元ダウンを実現できます.
ここでは、TSVDをirisデータセットで実証する.
In [1]:
from sklearn.datasets import load_iris
iris = load_iris()
iris_data = iris.data

How to do it...
TSVDオブジェクトの使い方は他のオブジェクトと似ています.まず必要なクラスをインポートし、初期化し、次にフィットします.
In [5]:
from sklearn.decomposition import TruncatedSVD

In [6]:
svd = TruncatedSVD(2)
iris_transformed = svd.fit_transform(iris_data)
iris_data[:5]

Out[6]:
array([[ 5.1,  3.5,  1.4,  0.2],
       [ 4.9,  3. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2],
       [ 4.6,  3.1,  1.5,  0.2],
       [ 5. ,  3.6,  1.4,  0.2]])

In [7]:
iris_transformed[:5]

Out[7]:
array([[ 5.91220352, -2.30344211],
       [ 5.57207573, -1.97383104],
       [ 5.4464847 , -2.09653267],
       [ 5.43601924, -1.87168085],
       [ 5.87506555, -2.32934799]])

最終結果を下図に示します.
In [10]:
%matplotlib inline
import matplotlib.pyplot as plt
f = plt.figure(figsize=(5, 5))
ax = f.add_subplot(111)

ax.scatter(iris_transformed[:, 0], iris_transformed[:, 1], c=iris.target)
ax.set_title("Truncated SVD, 2 Components")

Out[10]:


How it works...
次にscikit-learnのTruncatedSVDモジュールを実証し、scipyだけで詳細を学ぶことを見てみましょう.
まず、SVDをscipylinalgで処理します.
In [12]:
import numpy as np
from scipy.linalg import svd
D = np.array([[1, 2], [1, 3], [1, 4]])
D

Out[12]:
array([[1, 2],
       [1, 3],
       [1, 4]])

In [13]:
U, S, V = svd(D, full_matrices=False)
U.shape, S.shape, V.shape

Out[13]:
((3, 2), (2,), (2, 2))

SVDの定義に従って、行列DDをUU、SS、VVで復元することができる.
In [15]:
np.diag(S)

Out[15]:
array([[ 5.64015854,  0.        ],
       [ 0.        ,  0.43429448]])

In [16]:
np.dot(U.dot(np.diag(S)), V)

Out[16]:
array([[ 1.,  2.],
       [ 1.,  3.],
       [ 1.,  4.]])
TruncatedSVDが返す行列はUUとSSの点積である.TSVDをシミュレートしたい場合は、最新の奇異値とUUに対するカラムベクトルを削除します.例えば、主成分がほしいです.
In [17]:
new_S = S[0]
new_U = U[:, 0]
new_U.dot(new_S)

Out[17]:
array([-2.20719466, -3.16170819, -4.11622173])

一般に,次元ttを遮断したい場合は,N−tN−t個の奇異値を除去する.
There's more... TruncatedSVDには、いくつかの詳細に注意する必要があります.
シンボル反転(Sign flipping)TruncatedSVDに「落とし穴」があります.乱数生成器の状態が変化するにつれて、TruncatedSVDが連続的にフィットすると、出力の適合が変化する.この問題を回避するためには、TruncatedSVDで1回だけフィットし、その後、他の変換を使用することをお勧めします.これはパイプラインコマンドのもう一つの用途です.
このような状況を避けるには、次のようにします.
In [23]:
tsvd = TruncatedSVD(2)
tsvd.fit(iris_data)
tsvd.transform(iris_data)[:5]

Out[23]:
array([[ 5.91220352, -2.30344211],
       [ 5.57207573, -1.97383104],
       [ 5.4464847 , -2.09653267],
       [ 5.43601924, -1.87168085],
       [ 5.87506555, -2.32934799]])

疎行列TruncatedSVDのPDAに対する利点の1つは、TruncatedSVDがPDAで処理できない行列を操作できることである.これはPCAが共分散行列を計算しなければならないためであり,行列全体で動作する必要があり,行列が大きすぎると計算リソースが不十分になる可能性があるからである.