데이터로그😎
SVD (Singular Value Decomposition) 본문
- 특잇값분해!!!
- 고유값 분해와 달리 모든 행렬에 적용 가능: 이미지 처리, 자연어 처리, 추천 시스템 등에 사용
- A = UΣV^T
- A: m x n 크기의 행렬
- 특이벡터:
- U: m x m 크기의 직교행렬(orthogonal matrix) (A행렬의 행)
- V: n x n 크기의 직교행렬 (A행렬의 열)
- Σ: m x n 크기의 직사각 대각행렬(rectangular diagonal matrix)이며, 대각원소인 특이값(singular value)들은 0 이상의 실수 (A행렬 행x열)
SVD(Singular Value Decomposition)
- Σ의 비대각 부분과 특이값 중 0인 부분을 제거
- 제거된 Σ에 대응하는 U와 V원소도 함께 제거하여 차원 줄이는 것
- 불러올 때from scipy.linalg import svd 둘다 사용 가능
- from numpy.linalg import svd
import numpy as np
#임의 행렬
np.random.seed(121)
a= np.random.rand(4,4)
>>>array([[-0.21203317, -0.28492917, -0.57389821, -0.44031017],
[-0.33011056, 1.18369457, 1.61537293, 0.36706247],
[-0.01411931, 0.6296418 , 1.70964074, -1.32698736],
[ 0.40187312, -0.19142667, 1.40382596, -1.96876855]])
- SVD 행렬 분해
from numpy.linalg import svd
#from scipy.linalg import svd
U, Sigma, VT = svd(a)
print("U:\n{}".format(U))
print()
print("Sigma:\n{}".format(Sigma))
print()
print("VT:\n{}".format(VT))
>>
U:
[[-0.07913928 -0.31822729 0.86653217 0.37628494]
[ 0.38294523 0.78655287 0.12002097 0.46934262]
[ 0.65640669 0.02243181 0.35668848 -0.66437971]
[ 0.64515128 -0.52873697 -0.32785711 0.44353889]]
Sigma:
[3.4229581 2.02287339 0.46263157 0.07935069]
VT:
[[ 0.04100747 0.22367823 0.78643002 -0.57429458]
[-0.20019867 0.56209596 0.37041464 0.71187191]
[-0.77847455 0.3945136 -0.33259252 -0.3573774 ]
[-0.5934781 -0.69164673 0.36565426 0.18895901]]
- Sigma(특이값)을 대각행렬로 변환
Sigma_mat = np.diag(Sigma)
>>>
array([[3.4229581 , 0. , 0. , 0. ],
[0. , 2.02287339, 0. , 0. ],
[0. , 0. , 0.46263157, 0. ],
[0. , 0. , 0. , 0.07935069]])
- 원본행렬 = 다시 조합된 행렬
# 원본
원본행렬 a:
[[-0.21203317 -0.28492917 -0.57389821 -0.44031017]
[-0.33011056 1.18369457 1.61537293 0.36706247]
[-0.01411931 0.6296418 1.70964074 -1.32698736]
[ 0.40187312 -0.19142667 1.40382596 -1.96876855]]
# 다시 조합
a_ U @ Sigma_mat @ VT
>>>
조합된 행렬 a_:
[[-0.21203317 -0.28492917 -0.57389821 -0.44031017]
[-0.33011056 1.18369457 1.61537293 0.36706247]
[-0.01411931 0.6296418 1.70964074 -1.32698736]
[ 0.40187312 -0.19142667 1.40382596 -1.96876855]]
Truncated SVD
- Σ의 원소 중 상위 몇개만 추출
- 불러올 때
- from scipy.sparse.linalg import svds
import numpy as np
from scipy.sparse.linalg import svds
from scipy.linalg import svd # np.lianalg.svd와 같음
np.random.seed(121)
matrix = np.random.random((6,6))
>>>
[[0.11133083 0.21076757 0.23296249 0.15194456 0.83017814 0.40791941]
[0.5557906 0.74552394 0.24849976 0.9686594 0.95268418 0.48984885]
[0.01829731 0.85760612 0.40493829 0.62247394 0.29537149 0.92958852]
[0.4056155 0.56730065 0.24575605 0.22573721 0.03827786 0.58098021]
[0.82925331 0.77326256 0.94693849 0.73632338 0.67328275 0.74517176]
[0.51161442 0.46920965 0.6439515 0.82081228 0.14548493 0.01806415]]
num_components = 4
U, Sigma, VT = svds(matrix, k=num_components)
사이킷런에서 Truncated SVD
from sklearn.decomposition import TruncatedSVD
iris = load_iris()
tsvd = TruncatedSVD(n_components = 2)
tsvd.fit(iris.data)
iris_tsvd = tvsd.transform(iris.data)
iris_tsvd.shape
>>> (150,2) --> 4차원에서 2차원으로 축소
import pandas as pd
iris_tsvd_df = pd.DataFrame(data = iris_tsvd,columns = ['component_1','component_2']
iris_tsvd_df['target'] = iris.target
sns.scatterplot(
x='component_1',
y='component_2',
hue='target',
palette='muted',
data = iris_tsvd_df)
plt.show()
'머신러닝 > 차원축소' 카테고리의 다른 글
LDA (Linear Descriminant Analysis) (0) | 2023.09.05 |
---|---|
PCA (Principal Component Analysis) (0) | 2023.09.05 |