실습 · 연습문제 2개
최적 저랭크 근사 low-rank-approx
Eckart–Young 정리에 의해, 행렬 의 최적 rank- 근사는 SVD의 앞 개 항만 남긴
이고, 그 Frobenius 오차는 이다.
함수 low_rank_approx(A, k)를 완성해 (A_k, err)를 반환한다.
| 반환 | shape | 내용 |
|---|---|---|
A_k |
A와 같음 |
최적 rank- 근사 |
err |
스칼라 | 버린 특이값으로 계산한 Frobenius 오차 |
k가 0이면 영행렬과 를, k가 이상이면 A 자신과 0을 반환한다.
테스트는 다음을 확인한다.
A_k의 rank가k이고,err가 실제 오차np.linalg.norm(A - A_k)와 같다.- 같은 rank의 다른 근사(무작위 부분공간으로의 사영)보다 오차가 작다.
- 경계 경우(
k = 0,k ≥ min(m, n))
힌트: np.linalg.svd(A, full_matrices=False)가 돌려주는 Vt의 행이 이다. U[:, :k] * s[:k]처럼 브로드캐스팅을 쓰면 대각행렬을 만들지 않아도 된다.
SVD로 PCA 구현하기 pca-svd
데이터 행렬 (행 = 샘플)의 주성분을 SVD로 구한다. 열 평균 를 뺀 의 thin SVD가 이면
- 주성분 방향: 의 앞 개 열(
Vt의 앞 개 행) - 각 방향의 분산:
- 점수(score):
이다. 함수 pca(X, k)를 완성해 딕셔너리를 반환한다.
| 키 | shape | 내용 |
|---|---|---|
"mean" |
(D,) |
열 평균 |
"components" |
(k, D) |
행 = 주성분 방향(단위 벡터), 분산이 큰 순서 |
"explained_variance" |
(k,) |
각 주성분의 분산, 내림차순 |
"scores" |
(N, k) |
중심화한 데이터의 주성분 좌표 |
np.cov나 np.linalg.eig·eigh는 쓰지 않는다(테스트가 비교 기준으로 쓴다).
테스트는 다음을 확인한다.
- 분산과 방향이 공분산 행렬의 고유분해와 같다(방향은 부호를 무시하고 비교).
- 평균이 원점에서 먼 데이터에서도 올바른 방향을 찾는다(중심화).
- 점수의 표본 분산이
explained_variance와 같고, 점수끼리 상관이 없다. scores @ components + mean이 rank- 재구성이며, 이면 원래 데이터로 돌아간다.