머신러닝 / 공분산 행렬 PCA - 1
출처 : https://post.naver.com/viewer/postView.nhn?volumeNo=28714805&memberNo=21815
다음 3차원 행렬의 고유값과 고유벡터를 구해보자.
import numpy as np
A = np.array([[-2, -5, -2], [-5, 1, -5], [-2, -5, 2]])
print("Matrix A: ")
print(A)
print()
eigenvalue, eigenvector = np.linalg.eig(A)
eigenvalue = np.round(eigenvalue, 5) # 소수점 5자리로 반올림
eigenvector = np.round(eigenvector, 5) # 소수점 5자리로 반올림
print("Eigen Value: ")
print(eigenvalue)
print()
print("Eigen Value Diagonal Matrix \u039B(lambda): ")
eigenvalue = np.array([[eigenvalue[0], 0, 0], [0, eigenvalue[1], 0], [0, 0, eigenvalue[2]]])
print(eigenvalue)
print()
print("Eigen Vector Matix P: ")
print(eigenvector)
print()
print("AP = ")
print(np.round(A@eigenvector, 0))
print()
print("P\u039B =")
print(np.round(eigenvector@eigenvalue))
Matrix A:
[[-2 -5 -2]
[-5 1 -5]
[-2 -5 2]]
Eigen Value:
[-7.97321 1.92062 7.05259]
Eigen Value Diagonal Matrix Λ(lambda):
[[-7.97321 0. 0. ]
[ 0. 1.92062 0. ]
[ 0. 0. 7.05259]]
Eigen Vector Matix P:
[[ 0.65864 0.70272 0.26903]
[ 0.6114 -0.29139 -0.73572]
[ 0.43861 -0.64906 0.62156]]
AP =
[[-5. 1. 2.]
[-5. -1. -5.]
[-3. -1. 4.]]
PΛ =
[[-5. 1. 2.]
[-5. -1. -5.]
[-3. -1. 4.]]
이 고유값(eigen value)의 대각 행렬Λ과 고유벡터(eigen vector)의 행렬 P은 원래 행렬 A와 다음의 관계가 있다.
어떤 정방행렬의 고유값을 구한다는 것은 고유벡터로 이루어진 행렬과 고유값들로 이루어진 대각행렬, 고유벡터들로 이루어진 행렬의 역행렬의 순차적인 행렬곱으로 분해한다는 의미이다.
공분산 행렬
위 표는 각 스포츠 종목에 대한 선수들의 기록을 나타낸 것이다. 이 표에서 각 종목에 대해 선수들끼리의 우수성을 발견할 수 있지만 종목 간의 연관성, 즉 한 종목에서 뛰어난 선수가 다른 종목에서도 우수한가를 확인하긴 어렵다.
종목간의 비교를 위해 다음과 같은 표를 채워본다.
각 셀에 들어갈 값은 분산이다.
분산은 편차(각 데이터와 평균 사이의 차이)의 제곱을 평균낸 것이다.
일단 허들과 200m의 평균과 분산을 계산해보자.
joyner_kersee 선수의 허들 편차는 +0.58이고, 200m의 편차는 +1.03이다. 이 두 편차를 곱하면 +0.59정도이다.
편차를 곱하므로서 두 종목에서 평균보다 잘했는 가를 알 수 있다.
곱이 양수이면 두 종목 모두 평균 이상이라는 의미이고, 음수면 둘 중 한 종목은 평균 이하라는 의미이다.
이제 모든 선수들에게 두 편차를 곱한 후 이의 평균을 계산하는 것이 공분산이다.
공분산을 계산해 종목간의 연관성을 확인할 수 있다. 즉, 한 종목에서 뛰어난 선수가 다른 종목에서도 뛰어난가를 확인할 수 있게 된다.
import numpy as np
A = np.array([
[3.73, 1.86, 15.8, 4.05, 7.27, 45.66, 34.92 ],
[3.57, 1.80, 16.23, 2.96, 6.71, 42.56, 37.31],
[3.22, 1.83, 14.20, 3.51, 6.68, 44.54, 39.23],
[2.81, 1.80, 15.23, 2.69, 6.25, 42.78, 31.19],
[2.91, 1.74, 14.76, 2.68, 6.32, 47.46, 35.53],
[2.67, 1.83, 13.50, 1.96, 6.33, 42.82, 37.64]
])
print(A)
print()
print('covariance matrix')
B=np.cov(A, rowvar = False)
print(np.array2string(B, formatter={'float_kind':lambda x: "%.4f" % x}))
[[ 3.73 1.86 15.8 4.05 7.27 45.66 34.92]
[ 3.57 1.8 16.23 2.96 6.71 42.56 37.31]
[ 3.22 1.83 14.2 3.51 6.68 44.54 39.23]
[ 2.81 1.8 15.23 2.69 6.25 42.78 31.19]
[ 2.91 1.74 14.76 2.68 6.32 47.46 35.53]
[ 2.67 1.83 13.5 1.96 6.33 42.82 37.64]]
covariance matrix
[[0.1843 0.0074 0.3249 0.2619 0.1513 0.1087 0.2222]
[0.0074 0.0017 -0.0008 0.0136 0.0103 -0.0291 0.0223]
[0.3249 -0.0008 1.0281 0.3883 0.1994 -0.0263 -1.0597]
[0.2619 0.0136 0.3883 0.5281 0.2436 0.5239 0.0785]
[0.1513 0.0103 0.1994 0.2436 0.1482 0.1572 0.2100]
[0.1087 -0.0291 -0.0263 0.5239 0.1572 3.8842 0.0853]
[0.2222 0.0223 -1.0597 0.0785 0.2100 0.0853 7.8713]]
이를 이용해 PCA 피쳐들의 관계성을 파악하는데 사용할 수 있을 것 같다.