일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- LG Aimers 4th
- gpt
- 오블완
- Machine Learning
- 회귀
- LG
- 티스토리챌린지
- supervised learning
- 지도학습
- 해커톤
- 딥러닝
- 분류
- deep learning
- LG Aimers
- OpenAI
- Classification
- ChatGPT
- GPT-4
- AI
- regression
- 머신러닝
- PCA
- LLM
Archives
- Today
- Total
SYDev
Chapter 06-3: 주성분 분석 본문
차원 축소에 대해 이해하고
대표적인 차원 축소 알고리즘 중 하나인 PCA 모델을 만들어보자.
차원 축소
- 차원 축소(Dimensionality Reduction): 저차원 표현이 고차원 원본 데이터의 의미 있는 특성을 이상적으로 원래의 차원에 가깝게 유지할 수 있도록 고차원 공간에서 저차원 공간으로 데이터를 변환하는 것을 의미한다.
- 다시 말해서, 차원 축소를 하면 고차원에서 저차원으로 변환되는 과정에서 정보 손실(information loss)이 발생하는데, 이런 정보 손실을 최소화하면서 저차원으로 변환해야 한다.
차원 축소의 필요성
1. 차원의 저주
- 머신러닝에서 차원이 증가할수록 데이터 공간의 부피가 기하급수적으로 증가하기 때문 데이터의 밀도가 낮아지고, 데이터 간의 거리가 증가한다. 이러한 데이터를 이용해 학습을 진행하게 되면 모델이 복잡해져 과대적합이 발생하기 쉽고, 모델의 예측 신뢰도가 떨어진다.
- 차원이 일정 크기를 넘으면 성능은 점점 떨어져 0에 수렴한다.
2. 시각화를 통한 데이터 분석
- 탐색형 데이터 분석을 할 때에, 변수 간 관계를 파악하기 위해서 데이터의 산점도를 시각화해서 보면 좋은데, feature의 개수가 여러 개일 때는 데이터의 시각화가 어려워진다.
- 차원축소를 통해서 고차원의 데이터를 쉽게 시각화하여 데이터를 분석할 수 있다.
3. 데이터 처리, 분석 시에 연산 속도 향상
4. 데이터를 압축하여 데이터의 저장, 전송 효율 향상
차원 축소의 종류
- 특성 선택(Feature Selection): 가지고 있는 특성 중에서 훈련에 가장 유용한 특성을 선택하는 것으로, 원본 데이터에서 가장 좋은 성능을 보여줄 수 있는 데이터의 부분집합(subset)을 찾아내는 방법이다.
- 특성 추출(Feature Extraction): 기존 feature를 저차원 feature로 압축시키는 방법으로, 이렇게 압축된 feature는 기존과는 다른 새로운 값이 된다.
예를 들어 야외 활동이 좋은지 알아내기 위해 다음과 같이 101개의 야외활동과 관련된 feature가 있다고 치자.
온도 | 습도 | 강수량 | 미세먼지 | 풍속 | 태풍여부 | ... | 교통량 | 유동인구 | |
0801 | 32 | 15 | 66 | 3 | 111 | 0 | 15 | 40326127 | |
0802 | |||||||||
... | |||||||||
0831 |
위 특성들 중 습도와 강수량, 풍속과 태풍여부는 밀접한 연관성이 있다. 이처럼 밀접한 연관성이 있는 특성들을 묶어주는 것이 특성 추출의 과정이다.
온도 | 습도 | 강수량 | 미세먼지 | 풍속 | 태풍여부 | ... | 교통량 | 유동인구 | |
0801 | 32 | 15 | 66 | 3 | 111 | 0 | 15 | 40326127 | |
0802 | 0 | ||||||||
... | |||||||||
0831 |
그러나, 위와 같이 직관적으로 연관성을 확인할 수 없는 데이터의 경우에는 임의로 특성을 묶기 힘들어지는데, 이때 활용할 수 있는 방법 중 하나가 주성분 분석(Principle Component Analysis)이다.
주성분 분석
- 주성분 분석(Principle Component Analysis): 데이터를 축에 사영했을 때, 가장 높은 분산을 가지는 데이터의 축을 찾아 그 축으로 차원을 축소하는 방식이다.
- 높은 분산을 가지는 축을 찾는 이유는, 분산이 커져야 데이터들 간 차이가 명확해지고, 이로 인해서 모델을 더 좋은 방향으로 학습시킬 수 있기 때문이다.
다음 이미지를 봤을 때, 직관적으로 봐도 좌측 축이 원래 데이터를 더 잘 표현한다고 할 수 있다.
PCA의 차원 축소 절차는 다음과 같다.
- 데이터를 사영시켰을 때, 가장 분산이 큰 축(주성분)을 찾는다.
- 1번에서 찾은 축에 직교하며, 다음으로 분산이 큰 축(다음 주성분)을 찾는다.
- 위 과정을 반복하여 k개의 축을 찾아냈을 때, 원래의 고차원 데이터를 k차원 데이터로 다시 나타낼 수 있다.
주성분 분석의 수식적 이해
- 대칭 행렬의 고유 벡터는 직교한다!
설명된 분산
- 설명된 분산(explained variance): 주성분이 원본 데이터의 분산을 얼마나 잘 나타내는지 기록한 값을 의미한다.
- 설명된 분산의 비율을 모두 더하면 총 분산 비율을 얻을 수 있다.
PCA를 이용한 데이터의 차원 축소
#데이터 준비
!wget https://bit.ly/fruits_300_data -O fruits_300.npy
import numpy as np
fruits = np.load('fruits_300.npy')
fruits_2d = fruits.reshape(-1, 100*100)
#PCA를 이용한 차원 축소
from sklearn.decomposition import PCA
pca = PCA(n_components=50) #주성분 50개
pca.fit(fruits_2d)
print(pca.components_.shape)
(50, 10000)
- 각 50개의 주성분에 투영된 10000개의 픽셀을 의미!
import matplotlib.pyplot as plt
def draw_fruits(arr, ratio=1):
n = len(arr)
rows = int(np.ceil(n/10))
cols = n if rows<2 else 10
fig, axs = plt.subplots(rows, cols,
figsize=(cols*ratio, rows*ratio), squeeze=False)
for i in range(rows):
for j in range(cols):
if i*10 + j < n:
axs[i, j].imshow(arr[i*10 + j], cmap='gray_r')
axs[i, j].axis('off')
plt.show()
draw_fruits(pca.components_.reshape(-1, 100, 100))
#원본 데이터셋과 차원 축소된 데이터셋의 비교
print(fruits_2d.shape)
fruits_pca = pca.transform(fruits_2d)
print(fruits_pca.shape)
(300, 10000)
(300, 50)
#분산이 큰 방향으로 데이터를 투영했기 때문에 원본 데이터를 상당 부분 재구성할 수 있음
fruits_inverse = pca.inverse_transform(fruits_pca)
print(fruits_inverse.shape)
fruits_reconstruct = fruits.reshape(-1, 100, 100)
for start in [0, 100, 200]:
draw_fruits(fruits_reconstruct[start:start+100])
print("\n")
(300, 10000)
#설명된 분산 비율의 합
print(np.sum(pca.explained_variance_ratio_))
0.9215768225179868
#설명된 분산을 이용해 적절한 주성분의 개수를 탐색
plt.plot(pca.explained_variance_ratio_)
plt.show()
>> 처음 10개의 주성분이 대부분의 분산을 표현
다른 알고리즘과 함께 사용
로지스틱 회귀
#지도 학습 알고리즘인 로지스틱 회귀 모델 사용
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
target = np.array([0]*100 + [1]*100 + [2]*100)
#교차 검증 수행
from sklearn.model_selection import cross_validate
scores = cross_validate(lr, fruits_2d, target)
print(np.mean(scores['test_score']))
print(np.mean(scores['fit_time']))
0.9966666666666667
2.0395181655883787
- 특성(픽셀)이 10000개나 되기 때문에 300개의 샘플에서는 과대적합된 모델을 만들기 쉬움
- 교차 검증 폴드의 훈련 시간 대략 2.04초
#PCA로 차원 축소한 데이터로 훈련
scores = cross_validate(lr, fruits_pca, target)
print(np.mean(scores['test_score']))
print(np.mean(scores['fit_time']))
1.0
0.03729820251464844
- 50개의 특성만 사용했는데도 정확도가 100%
- 훈련 시간은 0.04초로 대략 50배 이상 빨라짐
pca = PCA(n_components=0.5) #설명된 분산의 50%에 달하는 주성분을 탐색
pca.fit(fruits_2d)
print(pca.n_components_)
2
>> 2개의 특성만으로 원본 데이터에 있는 분산의 50% 표현 가능
#주성분 2개로 원본 데이터 변환
fruits_pca = pca.transform(fruits_2d)
print(fruits_pca.shape)
scores = cross_validate(lr, fruits_pca, target)
print(np.mean(scores['test_score']))
print(np.mean(scores['fit_time']))
(300, 2)
0.9933333333333334
0.04042010307312012
k-평균 알고리즘
#PCA로 축소된 데이터로 KMeans 알고리즘 학습
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, random_state=42)
km.fit(fruits_pca)
print(np.unique(km.labels_, return_counts=True))
for label in range(0, 3):
draw_fruits(fruits[km.labels_ == label])
print("\n")
(array([0, 1, 2], dtype=int32), array([110, 99, 91]))
#차원 축소로 인한 시각화의 장점!!
for label in range(0, 3):
data = fruits_pca[km.labels_ == label]
plt.scatter(data[:,0], data[:,1])
plt.legend(['apple', 'banana', 'pineapple'])
plt.show()
참고자료
- 박해선, <혼자 공부하는 머신러닝+딥러닝>, 한빛미디어(주), 2022.2.4
- https://ko.wikipedia.org/wiki/%EC%B0%A8%EC%9B%90_%EC%B6%95%EC%86%8C_(%ED%86%B5%EA%B3%84%ED%95%99)
- https://casa-de-feel.tistory.com/19
- https://huidea.tistory.com/44?category=879541
- https://m.blog.naver.com/PostView.naver?blogId=euleekwon&logNo=221464171572&referrerCode=0&searchKeyword=feature%20extraction
- https://velog.io/@swan9405/PCA
- https://www.youtube.com/watch?v=5TLPtscN3Tg&list=PLSB4-69yY3od7cw1naXNgUsbdph6A3Aw7&index=19
'KHUDA 4th > 머신러닝 기초 세션' 카테고리의 다른 글
[KHUDA 4th] 머신러닝 5주차 기초 세션 (08.16) (0) | 2023.08.31 |
---|---|
Chapter 06-1,2: 군집 알고리즘 (0) | 2023.08.28 |
[KHUDA 4th] 머신러닝 4주차 기초 세션 (08.16) (0) | 2023.08.25 |
Chapter 05-3: 트리의 앙상블 (0) | 2023.08.22 |
Chapter 05-2: 교차 검증과 그리드 서치 (1) | 2023.08.22 |