본문 바로가기

AI/머신러닝(코세라)

[ML] #12 차원 축소 - PCA(Dimensionality Reduction - PCA)

본 글은 학교 '머신러닝' 수업을 들으며 공부한 내용을, 저의 말로 바꿔서 남에게 설명해주듯이 쓰는 글입니다.
다시 한번 복습하는 과정에서 Coursera Andrew Ng 교수님의 강의를 일부 수강하였고, 인터넷 검색 등을 통해 내용을 보충하였습니다.
너무 쉬운 개념들은 따로 정리하지 않았습니다. 따라서 해당 글에는 적히지 않은 개념들이 일부 있을 수 있습니다.


본 글은 Andrew Ng 교수님의 'machine learning' 수업 강의 노트를 일부 사용하였습니다.
본 글에 사용된 강의노트 사진들 대부분의 저작권은 'DeepLearning.AI'에 귀속되어 있음을 밝히며,
본 글은 'DeepLearning.AI'의 'Copyright rights'에 따라 수익 창출을 하지 않고,
또한 해당 정책에 따라 '개인 공부 및 정보 전달'이라는 교육적 목적으로 글을 작성함을 밝힙니다.


Motivation 1: Data Compression

 

PCA 얘는 압축임. 앞에 클러스트링은 묶음, 얘는 압축. 더 정확히는, 액기스만 뽑아내는거.

얘도 unsupervised learning의 대표적 예시 중 하나임.

피쳐 x1은 cm, 피쳐 x2는 인치임. 두 피쳐가 표현하는 게 비슷함. 즉, 두 피쳐의 상관계수가 1에 가까움. (높은 상관관계를 가짐)

이럴 때, 두 피쳐가 중복되었다고도 표현함.

2차원 데이터 셋인데 지금, 이걸 1차로 줄일 수 있는 가장 좋은 방법?? 2D → 1D를 하는 방법??

직설적인 방법은 그냥 피쳐 하나 날리는 거. 예시의 경우 x2를 날리고 x1만 씀. → 에러가 커질거임.

만약 그렇게 x축에 내리찍으면, 저기서 x2의 값 만큼씩을 반영하지 못하니까, 에러가 커질 수 있음. (저 x2 값 자체가 에러라는 말은 아님. 표현력이 떨어지게 되니까, 에러가 커지겠지.)

 

좋은 방법 : 위와 같이 마치 y=x느낌의 새로운 축을 만들면 됨. 그러면 에러가 좀 적을 거 아님. 표현력을 크게 떨어뜨리지 않음. 저 직선 하나만으로 두 피쳐를 동시에 반영할 수 있음.

이렇게 하면 x1, x2 이 2개 피쳐를 쓰지 않고, z라는 피쳐 하나만 쓰게되는거임.

** 90도로 투영해야함!! 저 y=x느낌의 축에 90도 투영!! 예를 들어 첫 번째 점이 (1,1)라 하면, 저거를 그냥 루트2로 축소시킬 수 있다.

 

우리가 압축하는 이유 : 통신 보낼 때 데이터 조금 보내려고. 하드디스크에 저장할 때, 큰 데이터를 적은 용량으로 저장하려고. 음성도 그렇고 영상도 그렇고, 이런 건 1분만 돼도 용량이 큼.

무손실 압축 : 압축했다가 압축해제하면 100% 나옴.

손실 압축 : 압축했다가 압축해제하면 손실이 생김.

PCA는 기본적으로 압축 손실임. 위 예시에서 y=x느낌의 축을 만들고 투영시킨다 해도, 저 거리만큼 표현력이 떨어질 거잖음. 따라서 에러가 생기겠지.  저 점에서 직선까지의 거리씩 만큼은 표현력이 떨어지게됨.

cf) PCA를 압축이라 부르는 이유 - 챗지피티

 

피쳐가 많으면 좋긴 한데… 그만큼 학습 데이터가 많아야 함. 만약 피쳐가 1000만개인데, 데이터 셋이 100만개면 학습이 제대로 되겠어? low rank 문제잖음. 학습 제대로 안됨. 따라서 피쳐 줄이면 좋음. curse of dimension. 학습 셋이 늘어나야 하는데 그게 싫으면 피쳐 줄여야지 뭐.

커널같은 경우는 우리가 임의로 디멘션을 늘려주긴 하지만, 분류를 잘 할 수 있는 방향으로 늘리는 거임. 근데 이건 다르자너.

 

cf) 딥러닝이랑은 좀 철학이 다른데요? 딥러닝에서 차원이란건 좀 추상적인데요? → 근데 딥러닝을 쓴단 건 일단 어려운 문제고, 학습 셋이 엄청 많으니까 피쳐(파라미터)가 많아도 상관이 없다. 

=> 차원이 높아서 curse of dimension이 일어났을 때, 학습셋을 왕창 늘려버리면 이게 어느정도 완화가 됨. 딥러닝은 피쳐(파라미터)도 엄청 많고 학습 셋도 엄청 많음.

 

 

근데 챗지피티 답변 보면 쓰일 순 있는듯? 입력 데이터의 차원을 줄이면 되니까

 

위에 예시 그래프와 같은 피쳐 분포를 봐야하는 이유 : 안중요한 피쳐를 줄여야 하는데, 뭐가 안중요한지 모르니까. 저 그림을 보고 우린 y=x 느낌의 직선을 그려서 거길 기준으로 1차원 디멘션만 써도 되겠다!! 하고 알 수 있음.

 

실제 예시) 32x32 얼굴 사진이 1024개의 디멘션을 가지잖음. 근데 이거 PCA 해서 100개의 디멘션으로 압축해도, 나중에 100개만 보고 얼굴 윤곽을 좀 알 수 있음. 근데 얼굴의 아이덴티티가, 디멘션 압축하면 다 사라짐. 맨들맨들함. 그래서 좀 통계적인 방법임. 통계적으로 봤을 때 에러가 가장 적을 수 있는 방식으로 가는 것. 근데 1024개 디멘션 100개로 줄이면 용량 줄어들고 좋긴 하잖음. 그만큼 표현력이 떨어지는 건 어쩔 수 없지. 장단점이 있음.

 

 

3차원 데이터를 2차원으로 투영시킨 예시.

PCA는 새로운 축이 생기고, 그 축에 각 데이터 점을 투영시키는 것임.

얘는 투영시켰을 때 에러가 가장 작아질 수 있는 방향으로 축을 만듦.

피쳐의 분포가 가장 많은 쪽으로 첫 번째 축이 만들어지고, 두 번째 축은 그거에 수직으로 만들어짐.

위 예시에선(3차원 -> 2차원) 2차원 평면 위아래에 있는 점들을 평면으로 투영시킨단 느낌으로 생각하셈.

 


 

Motivation 2: Data Visualization

 

왼쪽은 피쳐가 최소 6개 이상인 데이터인데, 이걸 우측과 같이 피쳐 2개만으로 압축할 수 있다 해보자.

이걸 저렇게 2개 축으로 뽑아낼 수 있다는 건, 대부분 피쳐들이 높은 상관관계를 가졌기에 가능한 거임. 뭐 위 예시에선 GDP가 높으면 1인당 GDP도 높고 기대수명도 높고 그렇겠지 당연히 ㅇㅇ.

 

위 z1, z2로 data를 plot해보면 위와 같음.

굳이 대응하자면 z1은 국가 규모 또는 GDP에 대응될 수 있고, z2는 1인당 GDP, 복지 등에 대응될 수 있음.

 

딥러닝에선, t-SNE를 쓰면, 딥러닝에서 나온 피쳐를 visualization이 가능함. 딥러닝에서 특정 피쳐를 관찰할 때는 t-SNE를 주로 씀. 누가 누가 좀 연관성이 큰가. 근처에 있다는 건 얘네 둘이 좀 헷갈린다는 거임. 피쳐 간 특성이 비슷하단거.

이런 거 보여주는 이유 : 딥러닝시대에 PCA를 배워야하는 이유를 알려주려고.

우측 위에 저게 t-SNE로 뭐 증명을 했다. 저게 자기 주장 뒷받침하는 근거로 쓰임. (무슨말인지 잘 이해안감 ㅠ..)

 

cf) t-SNE에 대해

https://gaussian37.github.io/ml-concept-t_sne/#

=> 위 블로그 글에서 t-SNE에 대해 3D -> 2D 예시와 함께 친절히 설명해주고 있음. 시간 나면 정독하자

 

GPT 답변)

 

핵심 : 유사한(=비슷한 피쳐 값들을 가진) 데이터 포인트는 가까운 곳에 배치되고, 다른 데이터 포인트는 멀리 배치됨.

formal하게 말하면, 피쳐들의 값에 따라 데이터 포인트 간의 유사도를 계산하고, 유사한 데이터 포인트들은 서로 가까운 위치에 배치되도록 함.

 


 

Principal Component Analysis (PCA) problem formulation

여기서, 축을 왼쪽처럼 잡는 게 적절함. 오른쪽처럼 축을 잡으면 error가 커질 수 있음. (이 때, 저 error = 점부터 직선까지의 투영 거리 = 파란색 선분의 길이 -> 요걸 "projection error(투영 에러)" 라고 부름.)

 

왼쪽처럼 축을 잡으면 projection error의 sum이 최소화될 거임. 근데 오른쪽처럼 축을 잡으면 그게 최대화될 거임. 

근데 그냥 sum을 쓰면 심심하기도 하고, 거리는 절대값이 반영되도록 하고 싶으니까, 회귀 때 cost fuction 정의할 때 MSE 썼던 것처럼, 여기도 MSE를 쓰자.

즉, PCA란 : projection error(의 MSE)가 최소화되도록 투영할 더 낮은 차원의 표면 또는 직선을 찾는 것임.

(이 때, 거리 계산하는거니까 당연히 normalization을 해줘야 함. 위 예시의 경우는 원점을 지나는 축을 잡을 거잖음? 그니까 mean normalization을 써서, x1이랑 x2가 0을 중심으로 비슷한 범위를 가지게끔 만들고 거리계산하자!!)

 

왼쪽은 2D to 1D, 오른쪽은 3D to 2D plot한 예시

수학적으로는,

2D to 1D 문제는 : projection error(의 MSE)를 최소화하는 벡터 u를 찾는다. 

3D to 2D 문제는 : projection error(의 MSE)를 최소화하는 벡터 u^(1), u^(2)를 찾는다. 

 

벡터 하나가 직선(축) 하나를 나타내고,

(수직하는) 벡터 두 개가 평면을 나타낸다고 이해하면 쉬움.

이 때, u는 관습적으로 방향 벡터(크기가 1인 방향만을 나타내는 벡터)를 사용함.

 

PCA는 n-D to k-D 문제임. 이에 따라 일반화하면,

n-D to k-D 문제는 : projection error(의 MSE)를 최소화하는 벡터 u^(1), u^(2), u^(3), ..., u^(k)를 찾는다. 

이 때, n은 압축의 input으로 들어오는 초기 차원이며, k는 내가 압축하려고 하는 output 차원임.

 

이 때, projection error의 MSE를 계산에 쓰다 보니까, 선형 회귀와 헷갈릴 수 있는데, 둘은 명백히 다름.

왼쪽의 선형 회귀 예시는 각 data point의 x에 대해, 그 x값을 고정시켜 놓고 그 때 y값 차이가 최소화되는 직선을 구하려는 거고,

오른쪽의 PCA는 각 data point로부터 직선(또는 3D->2D에선 평면)까지의 투영 거리(projection error)가 최소화되는 직선을 구하려는 거임. 헷갈리지 말자.


 

Principal Component Analysis(PCA) algorithm

 

통계적으로 에러가 최소가 되게 하려면, 아이겐 밸류 어네시스(고유값 분석)와 특이성 분해, covariance matrix 등을 써야 함. 근데 이 강의에선 엄밀하게 이를 다 증명하진 않을거임.

 

우선, PCA 하기 전 데이터 전처리는 필수임. 즉 mean normalization이나 표준화와 같은 feature scaling이 필요.

 

뮤j = j 피쳐에 대한 데이터들의 평균(x들의 평균)이고, 

이제 저 xj - 뮤j를 range(max - min) 또는 표준편차로 나눠주면 feature scaling 완성.

std_j 자리엔 range 또는 표준편차가 들어갈 수 있음. (전자 : mean normalization, 후자 : 표준화)

 

 

이제, 위에서 다뤘던 벡터 z나 벡터 u^(1), u^(2)와 같은 것들을 실제로 어떻게 구해야 할까??

엄밀하게 증명하긴 복잡하므로 우린  구하는 과정만 이해해보자.

 

1. 공분산 행렬을 계산한다.

왼쪽과 같은 행렬 시그마(작은 그리스대문자 기호 시그마임. sum이 아님.)을 공분산 행렬이라고 부름.

데이터 셋 x가 n차원이라 하면, 공분산 행렬은 n x n 행렬이 됨.

데이터 셋 x는 주어지는 거니까 당연히 공분산 행렬도 직접 구할 수 있음.

 

2. 공분산 행렬의 고유값을 계산한다.

 

 

위에서 구한 공분산 행렬 시그마를, 3개의 행렬로 분해하는 특이값 분해를 사용해 쪼갤거임. (matlab에서는 svd 함수를 사용)

우리가 svd() 함수에서 필요로 하는 것은 U행렬임.

고유값 분해를 하는 eig를 사용할 수도 있지만, svd가 좀 더 안정적(매트랩).

둘 다 서로 다른 함수지만, 공분산 행렬에 사용할 때는 같은 결과 U를 반환함.

 

만약 특정 행렬이 양의 값을 가지고 정방행렬일 경우, 고유값 분해와 특이값 분해는 같아짐. (이거 틀린말같기도. GPT는 여기에 추가로 행렬이 대칭이고 양의 정부호여야 한다고 함.)

https://velog.io/@pengu/2%EC%A3%BC%EC%B0%A8-Day3-08%EA%B0%95-SVD-PCA

즉, 공분산 행렬 시그마를 특이값 분해로 U, S, V로 분해함.

이 때 우리 시그마는 n x n 행렬임. 

그러면 U행렬 또한 따라서 n x n 행렬임. 

이 U 안에 열벡터들 u^(i)가 '고유벡터' 이고, 이 U는 고유벡터들을 모은 행렬임.

이 고유벡터들이 우리가 아까 말했던 축 또는 축을 이루는 벡터들.

근데, 이 n x n 행렬 U에 있는 건 n개의, 즉 원본에 대한 고유 벡터들임. 

우리 목표는 차원을 k로 줄이고 싶잖음? 즉 고유 벡터를 k개만 남기고 싶음.

그러니 우측처럼 열을 k개만 선택해서 행렬을 줄이고, 그 줄인 행렬 U_reduce에 대해,

z^(i) = U_reduce^T * x^(i) 로 k차원의 feature z를 구할 수 있음. (i = 1, 2, ..., m 은 training set)


선형대수에서 아직 특이값 고유값 분해  안배웠는데... ㅅㅂ...ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

https://velog.io/@pengu/2%EC%A3%BC%EC%B0%A8-Day3-08%EA%B0%95-SVD-PCA

https://roytravel.tistory.com/341

https://gguguk.github.io/posts/SVD/

https://my-mindpalace.tistory.com/10

일단 이런 블로그 글들 참고해서 이해해보고 썼다.....ㅠㅠㅠㅠㅠㅠ


 

Reconstruction from compressed representation

 

1차원으로 줄인 걸 2차원으로 복원하면 오른쪽처럼 됨. 그냥 인버스 구하는 건데, 왼쪽 z = ~~ 식에서, U를 왼쪽으로 넘기면 x가 복원이 되잖음.

 

저차원으로 압축한 식이 위에 z = ~~~ 식. 반대로 고차원으로 재구성한 식이 우측의 x_approx = ~~~ 식.

 

복원을 하면 보다시피 손실이 좀 있음. 그래서 손실 압축임

여기서 x가 아니라 x_approx 라고 표기한 것도, 재구성 과정에선 실제 x는 우리가 구할 수 없기 때문. 손실이 반영된 x_approx만 구할 수 있음.

 

이렇게 ' 압축된 데이터 z에서 원래 x의 값을 구하는 과정' 재구성(Reconstruction)이라고 함.

 

참고로, UU^T = I인 이유는 위와 같음.

 


 

Choosing the number of principal components

PCA는 n차원의 피쳐를 k차원의 피쳐로 축소하는거였잖음?? 여기서 k를 어떻게 선택해야 할 까 배워보자.

 

일단, 위와 같이 두 가지 값을 정의할거임.

평균 투영 오차의 제곱의 평균, 그리고 데이터의 총 변화량의 평균.

 

여기서, 위와 같이 '평균 투영 오차의 제곱의 평균' / '데이터의 총 변화량의 평균' 을 계산하면, 이는 error / 원본 이잖음. 

우린 여기서 원본 대비 error 비율이 '일정 비율' 이하가 되는 가장 작은 k값을 고르면 됨. (k가 늘어나면 error가 감소할 테니)

여기서 '일정 비율'은 내가 선택하는 거임. 예를 들어, 99%의 분산이 보존되기를 원하면, '일정 비율'은 0.01이 되어야 함.

일반적으로 위와 같이 '일정 비율'을 0.01로 선택함. 

 

이 때, '분산' 이란 용어를 쓴 것은, 분산은 '데이터가 평균으로부터 얼마나 떨어져 있는 지를 나타내는 값들의 제곱의 평균' 이잖음? 일단 데이터들은 정규화가 되어있으니 평균은 0임. 즉 저 자체가 '투영된 분산' / '원본 분산' 인 거임. 즉 원본 분산 대비 k개의 주성분만으로 압축했을 때 얼마나 분산이 유지되었느냐? 는 관점에서 '분산'이라는 용어를 쓴 것.

즉, 데이터가 고차원 공간에서 가지고 있는 분산을 개의 저차원 축에서도 거의 잃지 않고 나타낼 수 있다는 것을 의미함.

 

특히, https://gguguk.github.io/posts/PCA/

이 글을 보면, PCA 자체가 오차를 적게 하는 것 -> 이 말이 분산이 최대가 되게 하는 벡터를 찾는다는 말과 같음.


 

위와 같이, 일단 k 값을 1로 정한 후, U_reduce를 구하고, z1, z2, ..., zm을 계산함. 그러면 xapprox(1), ..., xapprox(m)을 다 구할 수 있잖음?

이제 모든 값이 구해졌으니, 저 오차 비율을 구해서 99%의 분산이 유지되는지를 확인함. 0.01 안에 들어왔다면? k = 1을 사용.

 

이걸 k = 2, k = 3, 4, 5, ... 99%의 분산을 유지할 때까지 계속 반복함.

 


 

근데, 이렇게 k = 1, 2,... 다 구하는 건 비효율적이긴 하잖음. 그래서 아까 svd 함수에서 구한 S 행렬을 이용하면, 좀 더 효율적으로 구할 수 있음. 

아까 식을

로 나타낼 수 있고, 이항 시

로 나타내짐.

따라서 해당 값이 0.99 이상이 되게 하는 k값을 선택하면 됨. 

여기서 S는 각각의 고유값이 대각선에 위치한 대각 행렬이고,

Sii는 i번째 고유값임.

GPT의 예시

 


 

Advice for applying PCA

PCA를 쓰면 학습할 때 피쳐 개수가 줄어드니까, 학습 속도가 빨라질 수 있다고 했잖음. 이제 실제로 어떻게 그게 가능한지, 그리고 우리가 실전에서 PCA를 적용하는 방법에 대해 알아보자.

 

이런 100 x 100의, image를 사용한다고 해보자. 이러면 피쳐의 차원이 10000으로 엄청 많다... 학습 속도 ㅈㅈ...

이럴 때 PCA를 사용하면 아래와 같이 1000차원의 새로운 피쳐 z를 인풋으로 사용할 수 있다.

즉, PCA로 디멘션을 1/10배로 줄인 거임. Good!!

이렇게 차원을 줄인 인풋 z를 x 대신 로지스틱 회귀에 쓰든 어디에 쓰든 다 할 수 있음.

** 이 때, 교차 검증 셋이나 테스트 셋 말고, '오직 학습 셋 에서만 PCA를 실행해야 함'

즉, PCA에 대한 k나, 그 축 같은 걸 정할 때, 학습 셋에서만 해야한단 말. 

결론) "새로운 데이터셋에서 다시 PCA를 계산하면 안 된다" 를 말해주고 싶었던 거임.

 

이제 학습 셋에서 구한 PCA 매핑을 교차 검증 셋이나 트레이닝 셋에 그대로 적용하면 됨.

 

 

 

잘만 하면, 이렇게 10000차원에서 1000차원으로 피쳐를 줄이고도 분산 대부분을 유지하고, 따라서 분류 정확도 측면에서 성능에 거의 영향을 미치지 않을거임. 그러면서 학습 속도는 훨씬 더 빨라짐.

 

PCA의 장점 2가지

1. Compression(압축)

: 메모리와 하드 디스크 사용 공간을 줄이고, 학습 알고리즘 속도를 높일 수 있음.

: 보통 99% 분산 유지하도록 압축.

2. Visualization(시각화)

: 우리는 2차원이나 3차원 데이터 분포만 눈으로 볼 수 있잖음. 따라서 k = 2 or k = 3을 선택해 도식화할 수 있음.

 

 

PCA의 오용 사례1

: overfitting을 방지하기 위해, 피쳐 줄여보겠다고 PCA 사용하려는 사람들이 있는데... 권장하지 않음. 

PCA를 사용하는 게 과적합 방지에 나쁘다는 건 아님. 다만, 과적합을 해결하기 위해 PCA를 쓰는 건 좋은 방법이 아니라는 것.

그냥 위처럼 정규화를 하는 게 젤 나음.

근데, 우리가 쓰는 라이브러리들엔 이미 리규화 들어가있음.

그래서 우리가 추가로 한다면 차라리, data set을 늘리는 게 나음.

 

 

PCA의 오용 사례2

위에 ML 시스템 디자인할 때 4가지가 있는데,

처음부터 PCA를 무조건적으로 사용하지는 마셈.

 

PCA를 사용하기 전에, PCA단계를 버리고 그냥 원래 데이터 x^(i)를 사용해서 이것저것 해보고 나서,

학습이 너무 느려!! 아님 메모리나 디스크 공간이 부족해!!

-> 이럴 때에 "PCA 써야겠따" 하고 PCA 쓰라는 거임.

즉, 원래 학습 셋을 사용했을 때 제대로 작동하지 않는다는 강력한 이유가 있을 때 비로소 PCA를 고려하셈.

 

많은 경우 PCA를 안 써도 잘 작동할거임

 


 

컴퓨터 비전 예시 적용

영상에서는 PCA를 많이 사용했었음. 근데 딥러닝을 영상에 쓰니까 안쓰게 됨. 요즘은 안쓰는데…

근데, 쉬운 어플리케이션을 만든다면 PCA를 안쓸 이유가 없어보임

 

ex. 0~9 hand writting 분류 문제

그림 예시로 했을 때, 왜 PCA 변환한 데이터는 멍들었을까??

⇒ 멍든 건, 다 평균 빼줘서 그렇게 된거임.

평균은 회색 배경에 하얀색으로 약간 8처럼 생긴 놈인데, 0~9 다 하다보면 대충 8이랑 비슷하게 생겼으니까. 저게 평균임.

그러니까, 그 8 모양으로 검정색 멍든 게 생긴거임.

 

reconstruction image가 뿌연 이유 : 압축 과정에서 손실이 발생했으니까

흑백의 경우는 channel이 하나임(gray 하나, RGB면 3개)

class는 10개임(0~9)

centraization 을 먼저 해줌 (평균을 다 빼줌)

 

아이겐 벡터의 inverse는 , 그게 Transpose임. 선형대수 때 보셈.

저거 새 결과물 보면 좀 더 선명한데, 만약, k = n 이라면 아예 원본과 같음.

y = U^T (x - 뮤)

y : 784 x 1, U^T : 784 x 784, x - 뮤 : 784 x 1

그럼, k값을 어떻게 정해야 할까??

⇒ error = sum(|x - x-hat|)일 때,

(입력 및 recon 된거.)

k가 늘어나면, error는 감소함.

적당히 elbow 지점에서 k를 정하면 됨.

(아님 우리가 배웠던 것 처럼 보존할 분산 정해놓고 k 줄이거나)

 

보통은 M > N 인데,

M < N이면, matrix의 rank가 784가 나오지 않음.

뭐 막 99 100 이런 거 나옴. 그럼 고유값 계산이 안됨. eig가 error 뜨거나 이상한 값을 내뱉음.

그래서, 원래는 x * xT 인데, 이걸 xT * x로 바꿔씀.

전자 : M x M matrix → M > N일 때임. full rank.

후자 : N x N matrix → M < N일 떄임. inverse가 없음.

피쳐가 1000개인데 데이터 셋이 10개밖에 없는거.

저거 커널 써서 해결이 힘듦.

그러니까, 1000x1000을 만드는 게 아니라, 10x10짜리 공분산 행렬을 만든 다음에, x에다가 고유값을 곱해줌. 이게 수학적으론 맞진 않는데, 대충 근사임. 

우리는, feature 개수보다 트레이닝 데이터 개수가 적으면 문제가 된다는 것만 이해하고 가자.

 

display_network(U(:, 1:20))

figure, display_network(U(:, end-20:end))

end 대신 100

결론) 아이겐 벡터는 각각이 90도. 따라서 내 생각과 다르게 나올 확률이 큰데, 최초에 가까운 아이겐 벡터는 그나마 좀 잘 나옴.

cfar의 경우는? (일반적인 이미지 분류)

데이터마다 알아볼만한 k값은 다름. 왜 m list(손글씨)는 100이어도 됐는데 왜 cfar는 알아보기 힘드나? 각각 학습 셋은 6만, 5만개. 데이터가 더 적은데, k 100 이니 더 알아보기 힘듦. class 개수도 같음 cfar니까. 10개.

(만약 분류해야 할 output class 개수가 늘어가면 표현할 수 있는게 다양해지니, k가 더 증가해야 할 가능성이 있음.) (개만 있는데 고양이, 낙타, 호랑이도 표현해야 하니까, k가 늘어나야 함.)

 

class 고정 상태에서, 피쳐 개수가 늘어나니까, 보존을 잘 하기 위해 필요한 k가 늘어나는 거임.