์ด๋ฒ ์ธ์ ์ ๋ค์ด๊ฐ๊ธฐ ์ ์, ์ ๋ ๋ํต ์ด ์ฑ ์ผ๋ก ์ดํด๊ฐ ์๋์ ๋ฐ๋ก ๊ฐ์๋ฅผ ๋ค์ด์ PCA์ ๋ํ ๊ฐ๋ ์ ์ก์์์ผ๋ ๊ฐ๋จํ๊ฒ ๋จผ์ ์ค๋ช ์ ๋๋ฆฌ๊ณ ๋ค์ด๊ฐ๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ถ๋ ์ด ์งง์ ์ค๋ช ์ด ์ฌ๋ฌ๋ถ์ด ์ดํดํ์๋๋ฐ ๋์์ด ๋๊ธธ ๋ฐ๋๋๋ค:)
PCA๋ ์ ๋ ฅ ๋ฐ์ดํฐ์ ๊ตฌ์กฐ๋ ์ต๋ํ ๋ณด์กดํ๋ฉด์ ์ฐจ์์ ๊ฐ์์ํค๋ ๊ธฐ๋ฒ์ ๋๋ค. ์ด๋, ๋ฐ์ดํฐ์ ๋ถ์ฐ์ด ๋ฐ์ดํฐ์ ๊ตฌ์กฐ๋ผ๊ณ ํ ์ ์์ต๋๋ค. ์ด ๋ฐ์ดํฐ์ ๋ถ์ฐ์ ์ต๋ํ์ผ๋ก ์ ์งํ๋ ์ ์ฐจ์ ๋ฒกํฐ์ ์ฌ์์ ์ํค๋ ๋ฐฉ์์ด์ฃ .
์๋ฅผ ๋ค์ด, 2์ฐจ์์์ 1์ฐจ์์ผ๋ก ์ฐจ์์ ์ถ์์ํจ๋ค๊ณ ์๊ฐํด๋ด ์๋ค. ์ฐ๋ฆฌ๋ ์ผ๋จ ํ๊ท ์ 0์ผ๋ก ๋ง์ถ ๋ฐ์ดํฐ๊ฐ ํ์ํ๊ณ , ์ด ๋ฐ์ดํฐ๋ฅผ ๊ณต๋ถ์ฐ ํ๋ ฌ๋ก ๋ง๋ค์ด์ค๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๊ณต๋ถ์ฐ ํ๋ ฌ์ ๊ณ ์ ๋ฒกํฐ๋ฅผ ๊ธฐ์ค์ผ๋ก PCA๋ฅผ ์คํํ์ฃ .
์ด๋ ๊ฒ ๋๋ฉด ์ฐ๋ฆฌ๋ ๋ ๊ณต๋ถ์ฐ ํ๋ ฌ์ ๋ญ๊ฐ, ํ๊ณ ์๋ฌธ์ด ์๊น๋๋ค. ๊ณต๋ถ์ฐ์ ๊ฐ ํน์ฑ์ ๋ณ๋์ด ์ผ๋ง๋ ๋ฎ์๋๊ฐ? ์ ๋๋ค. ๊ทธ๋ฌ๋๊น ๊ฐ ํน์ฑ์์ ์ ์ฒด ํน์ฑ์ ํ๊ท ์ ๋บ ๊ฐ์ ๋ฎ์ ์ ๋๋ฅผ ์ด์ผ๊ธฐํ๋ ๊ฒ์ด์ฃ . ์์์ ์ธ๊ธํ๋ฏ์ด ์ฐ๋ฆฌ๋ ๋จผ์ ํ๊ท ์ 0์ผ๋ก ๋ง๋ค์ด์ฃผ์์ผ๋, ๋ฎ์ ์ ๋๋ง ์๋ฉด ๋๊ฒ ๋ค์.
๋ฎ์ ์ ๋๋ ํ๋ ฌ ๊ฐ์ ๋ด์ ์ผ๋ก ์ ์ ์์ต๋๋ค. ์ ๋ ฅ ๋ฐ์ดํฐ ํ๋ ฌ X์ X์ ์ ์นํ๋ ฌ์ ์ ๊ณฑํ๋ฉด ๋ด์ ํ๋ ฌ์ด ์๊น๋๋ค. ์ด ๋ด์ ํ๋ ฌ์ ๋์นญํ๋ ฌ์ด๊ณ , ํ๋ ฌ ์์ ๋ ๋ฐ์ดํฐ๋ค์ ๊ฑฐ์ ๊ณต๋ถ์ฐ๊ณผ ์ ์ฌํฉ๋๋ค. ์ ์ ์ฌํ๋ค๊ณ ํํํ๋๋ฉด, ๊ณต๋ถ์ฐ์ ์ฌ๊ธฐ์ ์ ์ฒด ์ํ์ ๊ฐ์๋ก ๋๋ ์ฃผ์ด์ผํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ง์ฝ์ ์ํ์ ๊ฐ์๊ฐ ๋๋ฌด ๋ง์์ง๋ง ๊ฐ๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ด ์ปค์ง๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ํ ์๋ก ๋๋ ์ฃผ๋ ๊ฒ์ ๋๋ค.
์, ์ด ๋จ๊ณ์์ PCA๋ฅผ ์ํํด์ค๋ค๊ณ ํ ๋, ๊ฐ์ฅ ๋ฐ์ดํฐ๋ค์ด ๋๊ฒ ํผ์ ธ ์์ด์ผ ๋ฐ์ดํฐ์ ์๋ณธ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ฅ ์ ๊ฐ๊ณ ์๋ค๊ณ ํ๋จํ ์ ์๊ฒ ์ฃ ? ์ด ๋๊ฒ ํผ์ ธ์๋ ์ ๋๋ฅผ ๋ถ์ฐ์ด๋ผ๊ณ ํฉ๋๋ค. ์๋ ์ฌ์ง์ ์ฐธ์กฐํ๋ฉด, ๋ถํ์ ์ ์ผ๋ก ํํ๋ ๋ถ๋ถ์ด ๊ฐ์ฅ ๋ถ์ฐ์ด ํฐ ์ฃผ์ถ ๋ฒกํฐ์ ๋๋ค. ์ด ์ฃผ์ถ์ ์ฌ์์ ํด์ค์ผ๋ก์จ PCA๊ฐ ์๋ฃ๋๋ ๊ฒ์ด์ฃ .
๊ทธ๋ ๋ค๋ฉด ๋ถ์ฐ์ด ํฐ ์ ๋๋ ์ด๋ป๊ฒ ์ ์ ์์๊น์? ์ด๊ฒ์ ๊ณ ์ ๊ฐ๊ณผ ๊ณ ์ ๋ฒกํฐ๋ฅผ ํตํด์ ๊ตฌํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ์ ๊ณ ์ ๊ฐ์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ฉด ์ฒ์ ๋ ๋ฒกํฐ๊ฐ ๊ฐ์ฅ ํฐ ๋ถ์ฐ์ ๊ฐ์ง์ ์ ์ ์์ต๋๋ค(2์ฐจ์ ๊ธฐ์ค). ๊ฐ์ฅ ํฐ ๊ณ ์ณ๊ฐ์ ๊ฐ์ง ๊ณ ์ ๋ฒกํฐ๊ฐ ์ฃผ์ถ์ด ๋๋ ๊ฒ์ด์ฃ . ์ด ์ฃผ์ถ์ ์ ์ฌ์ ํด์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก PCA์ ๋๋ค.
์๋ ๋ด์ฉ์ ์ฑ ๋ด์ฉ์ ์ ๋ฆฌํ ๋ด์ฉ์ด๋ฏ๋ก, ์ด ์์ ๋ถ๋ถ์ ๊ฐ๋จํ๊ฒ ๋จธ๋ฆฌ์ ์๊ฒจ๋๊ณ ์ฝ์ด์ฃผ์๊ธธ ๋ฐ๋๋๋ค.
1. ์ฃผ์ฑ๋ถ ๋ถ์์ ์ฃผ์ ๋จ๊ณ
๋น์ง๋ ์ ํ ๋ณํ ๊ธฐ๋ฒ์ธ PCA(Principal Component Analysis)๋ ๊ณ ์ฐจ์ ๋ฐ์ดํฐ์์ ๋ถ์ฐ์ด ํฐ ๋ฐฉํฅ์ ์ฐพ์์ ๋ ์๊ฑฐ๋ ๊ฐ์ ์์ ์ฐจ์์ ๊ฐ๋ ๋ถ๋ถ๊ณต๊ฐ์ผ๋ก ํฌ์ํ๋ ๊ฒ์ ๋๋ค. ํน์ฑ ์ฌ์ด์ ์๊ด๊ด๊ณ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ์ ํน์ฑ์ ์ก์๋ผ ์ ์์ฃ . ์ด๋ ํฌ์ํ ์๋ก์ด ๋ถ๋ถ๊ณต๊ฐ์ ์ฃผ์ฑ๋ถ, ์ง๊ต์ขํ๋ ์กฐ๊ฑด ํ์์ ๋ถ์ฐ์ด ์ต๋์ธ ๋ฐฉํฅ์ ๋๋ค. ์๋ ๊ทธ๋ฆผ์ ๋ณผ๊น์?
x1๊ณผ x2๊ฐ ์๋ณธ ํน์ฑ ์ถ์ด๊ณ , PC1๊ณผ PC2๋ ์ฃผ์ฑ๋ถ์ ๋๋ค. ๋ ์ง๊ต ์ขํ๋ ์๋ก ์ง๊ฐ์ ์ด๋ฃจ์ฃ . ์ด๋ ๋ฒกํฐ์ ์ฑ์ง์ ์ํด์ ๋ ์ง๊ต์ขํ๊ฐ ์๊ด๊ด๊ณ๊ฐ ์๋ค๋ ๋ป์ ๋๋ค. PCA๋ฅผ ์ฌ์ฉํด์ ์ฐจ์์ ์ถ์ํ๊ธฐ ์ํด์๋ ์๋ณธ์ฐจ์ d * ์๋ก์ด ํน์ฑ ๋ถ๋ถ๊ณต๊ฐ k ์ฐจ์์ ๋ณํํ๋ ฌ W๋ฅผ ๋ง๋ญ๋๋ค. ์ด ๋ถ๋ถ ๊ณต๊ฐ์ ๋น์ฐํ ์๋ณธ d์ฐจ์๋ณด๋ค ์์ ์ฐจ์์ ๊ฐ์ต๋๋ค.
์๋ณธ ์ฐจ์์์ ์๋ก์ด ์ฐจ์์ ๋ถ๋ถ ๊ณต๊ฐ์ผ๋ก ๋ณํํ์ฌ ๋ง๋ค์ด์ง ์ฒซ ๋ฒ์งธ ์ฃผ์ฑ๋ถ์ ๊ฐ์ฅ ํฐ ๋ถ์ฐ์ ๊ฐ์ต๋๋ค. ๋ชจ๋ ์ฃผ์ฑ๋ถ์ ๋ค๋ฅธ ์ฃผ์ฑ๋ถ๊ณผ ์๊ด๊ด๊ณ๊ฐ ์๋ค๋ ์ ์ฝ ํ์ ๊ฐ์ฅ ํฐ ๋ถ์ฐ์ ๊ฐ์ง๋๋ค. ์ด๋ ์ ๋ ฅํน์ฑ๊ฐ์ ์๊ด๊ด๊ณ์๋ ๊ด๋ จ์ด ์์ต๋๋ค.
PCA ๋ฐฉํฅ์ ๋ฐ์ดํฐ์ ๊ท๋ชจ์ ๋ฏผ๊ฐํฉ๋๋ค. ํน์ฑ์ ๊ท๋ชจ, ์ฆ ์ค์ผ์ผ์ด ๋ค๋ฅด๊ณ ๋ชจ๋ ํน์ฑ์ ์ค์๋๋ฅผ ๋์ผํ๊ฒ ์ทจ๊ธํ๋ ค๋ฉด ํน์ฑ ํ์คํ ์ฒ๋ฆฌ๊ฐ ๊ผญ ํ์ํฉ๋๋ค. ์ด์ PCA ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๊ธฐ ์ ์ ํด์ผํ ๋ชฉ๋ก์ ์ ๋ฆฌํด๋ณผ๊น์?
-
d ์ฐจ์ ๋ฐ์ดํฐ์ ์ ํ์คํํฉ๋๋ค.
-
๊ณต๋ถ์ฐ ํ๋ ฌ(covariance matrix)์ ๋ง๋ญ๋๋ค.
-
๊ณต๋ถ์ฐ ํ๋ ฌ์ ๊ณ ์ ๋ฒกํฐ(eigenvector)์ ๊ต์ณ๊ฐ(eigenvalue)๋ก ๋ถํดํฉ๋๋ค.
-
๊ณ ์ณ๊ฐ์ ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌํ๊ณ ๊ทธ์ ํด๋นํ๋ ๋ฒกํฐ์ ์์๋ฅผ ๋งค๊น๋๋ค.
-
๊ณ ์ณ๊ฐ์ด ๊ฐ์ฅ ํฐ k๊ฐ์ ๊ณ ์ ๋ฒกํฐ๋ฅผ ์ ํํฉ๋๋ค. ์ฌ๊ธฐ์ k๋ ํน์ฑ ๋ถ๋ถ ๊ณต๊ฐ์ ์ฐจ์์ ๋๋ค.
-
์ต์์ k๊ฐ์ ๊ณ ์ ๋ฐฑํฐ๋ก ํฌ์ ํ๋ ฌ(projection matrix) W๋ฅผ ๋ง๋ญ๋๋ค.
-
ํฌ์ํ๋ ฌ W๋ฅผ ์ด์ฉํด d์ฐจ์ ์ ๋ ฅ ๋ฐ์ดํฐ์ X๋ฅผ ์๋ก์ด k ์ฐจ์์ ํน์ฑ ๋ถ๋ถ๊ณต๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค.
2. ์ฃผ์ฑ๋ถ ์ถ์ถ ๋จ๊ณ
์ด๋ฒ์๋ PCA์ ์ฒ๋ฆฌ๊ณผ์ ์ค ์ฒ์ 4๋จ๊ณ๋ฅผ ๊ตฌํํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ฌผ๋ก ํ์ด์ฌ์ผ๋ก์! ๋จผ์ , ์์ ์ธ์ ์์ ์ฌ์ฉํ wine ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํด์ฃผ๊ณ , ํ๋ จ์ธํธ์ ํ ์คํธ์ธํธ๋ก ๋๋๊ณ ํ์คํ๋ฅผ ์ ์ฉํด์ค๋๋ค. ํ๋ จ์ธํธ๊ฐ 70%, ํ ์คํธ์ธํธ๊ฐ 30% ์ ๋๋ค.
import pandas as pd
df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/''machine-learning-databases/wine/wine.data', header = None)
from sklearn.model_selection import train_test_split
X, y = df.wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
X_train, Xtest, y_train, y_test = \
train_test_split(X, y, test_size = 0.3, stratify = y, random_state = 0)
from sklearn.preprocessing import StandartScaler
sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.transform(X_test)
์ ์ฝ๋๋ก ์ ์ฒ๋ฆฌ ๋จ๊ณ๋ฅผ ์๋ฃํ๊ณ , ๊ณต๋ถ์ฐ ํ๋ ฌ์ ๋ง๋ค์ด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๊ณต๋ถ์ฐ ํ๋ ฌ์ ์ฃผ์ด์ง ๋ฒกํฐ์ ๊ฐ ์์ ์ ์ฌ์ด์ ๊ณต๋ถ์ฐ์ ์ ๊ณตํ๋ ์ ์ฌ๊ฐ ํ๋ ฌ์ ๋๋ค. ๊ณต๋ถ์ฐ์ 2๊ฐ์ ํ๋ฅ ๋ณ์์ ์๊ด์ ๋๋ฅผ ๋ํ๋ด๋ ๊ฐ์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๋ง๋ค ๊ณต๋ถ์ฐ ํ๋ ฌ์ d x d์ฐจ์์ ๋์นญ ํ๋ ฌ๋ก ํน์ฑ๊ฐ์ ๊ณต๋ถ์ฐ์ ์ ์ฅํฉ๋๋ค. ์ ์ฒด ์ํ์ ๋ํ ๋ ํน์ฑ Xj์ Xk ์ฌ์ด์ ๊ณต๋ถ์ฐ์ ์๋์ ๊ฐ์ด ๊ณ์ฐ ๊ฐ๋ฅํฉ๋๋ค.
์ฌ๊ธฐ์ ๊ฐ ํน์ฑ์์ ๋นผ์ฃผ๋ ๊ฐ์ ํน์ฑ j์ k์ ์ํ ํ๊ท ์ ๋๋ค. ์ฌ๊ธฐ์๋ ๋ฐ์ดํฐ์ ์ ํ์คํ ์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ํ๊ท ์ 0์ ๋๋ค. ์ ๊ท๋ถํฌ์ ๊ฐ์ฃ . ๊ณต๋ถ์ฐ์ ๊ฐ์ด ์์ด๋ฉด ํน์ฑ์ด ํจ๊ป ์ฆ๊ฐํ๊ฑฐ๋ ๊ฐ์ํ๋ค๋ ๋ป์ด๊ณ , ์์ด๋ฉด ๋ฐ๋ ๋ฐฉํฅ์ผ๋ก ๋ฌ๋ผ์ง๋ค๋ ๋ป์ ๋๋ค. ์ธ ๊ฐ์ ํน์ฑ์ผ๋ก ์ด๋ฃจ์ด์ง ๊ณต๋ถ์ฐ ํ๋ ฌ์ ์๋์ ๊ฐ์ต๋๋ค. (์๋ ๊ทธ๋ฆผ์์ ์๊ทธ๋ง๋ ํฉ์ ๊ธฐํธ๊ฐ ์๋๋๋ค!)
๊ณต๋ถ์ฐ ํ๋ ฌ์ ๊ณ ์ ๋ฒกํฐ๊ฐ ์ฃผ์ฑ๋ถ์ ํํํฉ๋๋ค. ์ฃผ์ฑ๋ถ์ ์ต๋ ๋ถ์ฐ์ ๋ฐฉํฅ์ ๋๋ค. ์ฌ๊ธฐ์ ๋์๋๋ ๊ณ ์ณ๊ฐ์ ์ฃผ์ฑ๋ถ์ ํฌ๊ธฐ์ ๋๋ค. Wine ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ์๋ 13 * 13์ ๊ณต๋ถ์ฐ ํ๋ ฌ์์ 13๊ฐ ๋ฒกํฐ์ ๊ณ ์ณ๊ฐ์ ์ป์ ์ ์์ต๋๋ค.
๋ค์์ผ๋ก ๊ณ ์ ๋ฒกํฐ์ ๊ณ ์ณ๊ฐ ์์ ๊ตฌํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๊ณ ์ ๋ฒกํฐ v๋ ์๋ ์์ ๋ง์กฑํฉ๋๋ค.
์ ์์ ๋๋ค๋ ์ค์ผ์ผ์ ๋ด๋นํ๋ ๊ณ ์ณ๊ฐ์ ๋๋ค. ๊ณ ์ ๋ฒกํฐ์ ๊ณ ์ณ๊ฐ์ ๊ณ์ฐํ๊ธฐ๋ ๊ท์ฐฎ๊ธฐ ๋๋ฌธ์ ๋ํ์ด linalg.eig ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
import numpy as np
cov_mat = np.cov(X_train_std.T)
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
print('\nEigenvalues \n%s' % eigen_vals)
numpy.cov ํจ์๋ฅผ ์ฌ์ฉํด์ ํ๋ จ ๋ฐ์ดํฐ์ ๊ณต๋ถ์ฐ ํ๋ ฌ์ ๊ณ์ฐํด์ฃผ๊ณ , linalg.eig ํจ์๋ก ๊ณ ์ณ๊ฐ์ ๊ณ์ฐํฉ๋๋ค. ์ด๋ฅผ ํตํด์ 13๊ฐ ๊ณ ์ณ๊ฐ์ด ๋ค์ด์๋ ๋ฒกํฐ์ธ eigen_vals์ ๋์ํ๋ ๊ณ ์ ๋ฒกํฐ๊ฐ ์ ์ฅ๋ ํ๋ ฌ์ ์ป์ ์ ์์ต๋๋ค.
3. ์ด๋ถ์ฐ๊ณผ ์ค๋ช ๋ ๋ถ์ฐ
์ฐ๋ฆฌ์ ๋ชฉํ๋ ๋ฐ์ดํฐ์ ์ฐจ์์ ์๋ก์ด ํน์ฑ ๋ถ๋ถ ๊ณต๊ฐ์ผ๋ก ์์ถํด์ผํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ฅ ๋ง์ ์ ๋ณด๋ฅผ ๊ฐ์ง ๊ณ ์ ๋ฒกํฐ์ ์ผ๋ถ๋ง ์ ํํฉ๋๋ค. ์ด๋ ์ ํํ๋ ๊ณ ์ ๋ฒกํฐ๋ ๊ณ ์ณ๊ฐ ์์์ ๋ฐ๋ผ ์ต์์ k๊ฐ ์ ๋๋ค. ์ผ๋จ, ์์ ๋ชฉ์์ ์ ์ ์๋ ์ค๋ช ๋ ๋ถ์ฐ์ด ๋ฌด์์ธ์ง๋ถํฐ ์์๋ณผ๊น์?
์ค๋ช ๋ ๋ถ์ฐ(explained variance)์ ํต๊ณ์์ ์ฃผ์ด์ง ๋ฐ์ดํฐ์ ๋ถ์ฐ์ ์ค๋ช ํ๋ ๋น์จ์ ์ธก์ ํฉ๋๋ค. ๊ทธ ์ค์์, ์ค๋ช ๋ ๋ถ์ฐ์ ๋น์จ์ ์ ์ฒด ๊ณ ์ณ๊ฐ ์ค์์ ์ํ๋ ๊ณ ์ณ๊ฐ์ ๋น์จ์ ๋๋ค.
๋๋ค j๊ฐ ์ฌ๊ธฐ์์ ์ํ๋ ๊ณ ์ณ๊ฐ์ด ๋ฉ๋๋ค. ์์ผ๋ก ๋ํ๋ด๋ฉด ์์ ๊ฐ๊ฒ ์ฃ ? ์ด์ ๋ํ์ด cumsum ํจ์๋ก ์ค๋ช ๋ ๋ถ์ฐ ๋์ ํฉ์ ๊ณ์ฐํ๊ณ , matplot lib์ stepํจ์๋ก ๊ทธ๋ํ๋ฅผ ๊ทธ๋ ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
tot = sum(eigen_vals)
var_exp = [(i / tot) for i in sorted(eigen_vals, reverse=True)]
cum_var_exp = np.cumsum(var_exp)
...
import matplotlib.pyplot as plt
plt.bar(range(1, 14), var_exp, alpha=0.5, align='center',
label='individual explained variance')
plt.step(range(1, 14), cum_var_exp, where='mid',
label='cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal component index')
plt.legend(loc='best')
plt.tight_layout()
plt.show()
์ด ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฒฐ๊ณผ ๊ทธ๋ํ์์ ์ค๋ช ๋ ๋ถ์ฐ์ ๋น์จ์ ํ์ธํ ์ ์์ต๋๋ค.
๊ทธ๋ ค์ง ๊ทธ๋ํ์์ ์ฒซ ๋ฒ์งธ ๊ณ ์ณ๊ฐ์ด ์ ์ฒด ๋ถ์ฐ์ 40%๋ฅผ ๋ด๋นํ๊ณ , ๋ ๋ฒ์งธ ๊ณ ์ณ๊ฐ๊น์ง๊ฐ 60%๋ฅผ ์ฐจ์งํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์๋ง๋ ์ฌ๋ฌ๋ถ์ ๋ญ๊ฐ ๋๋ค ํฌ๋ ์คํธ์ ํน์ฑ ์ค์๋๋ ๋น์ทํ์ง ์์๊ฐ ํ๋ ์๊ฐ์ด ๋์ค ๊ฒ๋๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ์ง๊ธ ์ด์ผ๊ธฐํ๊ณ ์๋ ์ด PCA๋ผ๋ ์น๊ตฌ๋ ๋น์ง๋ ํ์ต์ ๋๋ค! ๋ํ ๋๋ค ํฌ๋ ์คํธ์์๋ ๋ ธ๋์ ๋ถ์๋๋ฅผ ๊ณ์ฐํ์ง๋ง ๋ถ์ฐ์ ๊ฐ๋ค์ด ํผ์ง ์ ๋๋ฅผ ์ธก์ ํฉ๋๋ค.
4. ํน์ฑ ๋ณํ
์ด์ ์ฐ๋ฆฌ๊ฐ ํด์ผํ ์ผ์ ์ธ ๊ฐ์ง์ ๋๋ค.
- ๊ณ ์ณ๊ฐ์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ๊ณ ์ ๋ฒกํฐ๋ฅผ ์ ๋ ฌํ๊ธฐ.
- ์ ํ๋ ๊ณ ์ ๋ฒกํฐ๋ก ํฌ์ ํ๋ ฌ ๊ตฌ์ฑํ๊ธฐ.
- ํฌ์ํ๋ ฌ์ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ ์ฐจ์ ๋ถ๋ถ ๊ณต๊ฐ์ผ๋ก ๋ณํํ๊ธฐ.
๋จผ์ , ๊ณ ์ ๋ฒกํฐ์ ๊ณ ์ณ๊ฐ ์์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํฉ๋๋ค.
# (๊ณ ์ณ๊ฐ, ๊ณ ์ ๋ฒกํฐ) ํํ์ ๋ฆฌ์คํธ๋ฅผ ๋ง๋ญ๋๋ค
eigen_pairs = [(np.abs(eigen_vals[i]), eigen_vecs[:, i])
for i in range(len(eigen_vals))]
# ๋์ ๊ฐ์์ ๋ฎ์ ๊ฐ์ผ๋ก (๊ณ ์ณ๊ฐ, ๊ณ ์ ๋ฒกํฐ) ํํ์ ์ ๋ ฌํฉ๋๋ค
eigen_pairs.sort(key=lambda k: k[0], reverse=True)
๊ทธ๋ฆฌ๊ณ ๊ฐ์ฅ ํฐ ๋ ๊ฐ์ ๊ณ ์ณ๊ฐ๊ณผ ๊ณ ์ ๋ฒกํฐ ์ธํธ๋ฅผ ์ ํํฉ๋๋ค. ์์ ๊ทธ๋ํ์์ ํ์ธํ์ ๊ฒ๊ณผ ๊ฐ์ด ์ด ๋ ์ธํธ๋ก ์ด ๋ถ์ฐ์ 60% ๋ฅผ ์ก์๋ผ ์ ์์ต๋๋ค. ์ฌ๊ธฐ ์์ ์์๋ 2์ฐจ์ ์ฐ์ ๋๋ฅผ ์ํด 2 ๊ฐ๋ฅผ ์ ํํ์ง๋ง, ์ค์ ์์๋ ๊ณ์ฐ ํจ์จ๊ณผ ๋ชจ๋ธ ์ฑ๋ฅ ์ฌ์ด์ ์ค๊ฐ์ ์ ์ฐพ์์ ๊ฐ์๋ฅผ ์ ํํด์ฃผ๋ฉด ๋ฉ๋๋ค.
w = np.hstack((eigen_pairs[0][1][:, np.newaxis],
eigen_pairs[1][1][:, np.newaxis]))
print('ํฌ์ ํ๋ ฌ W:\n', w)
์ ์ฝ๋๋ฅผ ์คํํ๋ฉด 13 * 2์ ํฌ์ ํ๋ ฌ W๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ด ํฌ์ํ๋ ฌ์ ์ฌ์ฉํ๋ฉด ์ํ x(1 * 13์ ํ ๋ฐฑํฐ)๋ฅผ PCA ๋ถ๋ถ๊ณต๊ฐ์ผ๋ก ํฌ์ํด x'๋ฅผ ์ป์ ์ ์์ต๋๋ค. 2๊ฐ ํน์ฑ์ผ๋ก ์ด๋ฃจ์ด์ง 2์ฐจ์ ์ํ ๋ฒกํฐ๊ฐ ๋์ฃ .
์์ ์๋ ๊ฒ ๋ฉ๋๋ค. ๋น์ทํ๊ฒ ์ ์ฒด 124 * 13์ฐจ์์ ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ํ๋ ฌ ๊ณฑ์ผ๋ก ๋ ๊ฐ์ ์ฃผ์ฑ๋ถ์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค. ์ ์์ ๋๋ฌธ์๋ก ๋ฐ๊ฟ์ ํํํ ์ ์์ต๋๋ค.
X_train_std[0].dot(w)
X_train_pca = X_train_std.dot(w)
colors = ['r', 'b', 'g']
markers = ['s', 'x', 'o']
for l, c, m in zip(np.unique(y_train), colors, markers):
plt.scatter(X_train_pca[y_train == l, 0],
X_train_pca[y_train == l, 1],
c=c, label=l, marker=m)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
plt.show()
์ ์ฝ๋๋ฅผ ์ด์ฉํ๋ฉด 124 * 2์ฐจ์์ ํ๋ ฌ๋ก ๋ณํํ Wine ํ๋ จ ์ธํธ๋ฅผ 2์ฐจ์ ์ฐ์ ๋๋ก ์๊ฐํํฉ๋๋ค.
์ด ๊ทธ๋ํ์์ ๋ณผ ์ ์๋ฏ์ด ๋ฐ์ดํฐ๊ฐ y์ถ(๋ ๋ฒ์งธ ๊ณ ์ณ๊ฐ)๋ณด๋ค x์ถ(์ฒซ ๋ฒ์งธ ๊ณ ์ณ๊ฐ)์ ๋ฐ๋ผ์ ๋ ๋๊ฒ ํผ์ณ์ ธ ์์ต๋๋ค.
5. ์ฌ์ดํท๋ฐ์ ์ฃผ์ฑ๋ถ ๋ถ์
์ด์ ๋จ๊ณ๋ค์์ PCA์ ์๋ฆฌ๋ฅผ ์ดํดํด ๋ณผ ์ ์์๋ค๋ฉด ์ด์ ์ฌ์ดํท๋ฐ์ ์ด์ฉํด๋ณผ ์ฐจ๋ก์ ๋๋ค. ์ผ๋จ ๋จผ์ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ๊ทธ๋ฆฌ๋ ํจ์๋ ์ด๋ฐ ์ธ์ ์์ ๋ง๋ค์๋ plot_decision_regions๋ฅผ ์ด์ฉํ๊ฒ ์ต๋๋ค.
def plot_decision_regions(X, y, classifier, resolution=0.02):
# ๋ง์ปค์ ์ปฌ๋ฌ๋งต์ ์ค๋นํฉ๋๋ค
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
# ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ๊ทธ๋ฆฝ๋๋ค
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
# ํด๋์ค ์ํ์ ํ์ํฉ๋๋ค
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0],
y=X[y == cl, 1],
alpha=0.6,
c=cmap.colors[idx],
edgecolor='black',
marker=markers[idx],
label=cl)
๊ทธ๋ฆฌ๊ณ ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด ๋ชจ๋ธ์ ํ๋ จํ๊ณ ๊ฐ์ ๋ชจ๋ธ ํ๋ผ๋ฏธํฐ๋ก ํ๋ จ๊ณผ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ๋ณํํฉ๋๋ค. ์ฌ์ดํท๋ฐ PCA ํด๋์ค๋ฅผ Wine๋ฐ์ดํฐ์ ์ ํ๋ จ ์ธํธ์ ์ ์ฉํ๊ณ ๋ก์ง์คํฑ ํ๊ท๋ก ๋ถ๋ฅํด๋ณด๊ฒ ์ต๋๋ค.
from sklearn.linear_model import LogisticRegression
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_train_pca = pca.fit_transform(X_train_std)
X_test_pca = pca.transform(X_test_std)
lr = LogisticRegression(solver='liblinear', multi_class='auto')
lr = lr.fit(X_train_pca, y_train)
#๊ทธ๋ฆฌ๊ธฐ!
plot_decision_regions(X_train_pca, y_train, classifier=lr)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
plt.show()
์ฝ๋๋ฅผ ์คํํ๋ฉด ๋ ๊ฐ์ ์ฃผ์ฑ๋ถ ์ถ์ผ๋ก ์ค์ด๋ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
์ฌ์ดํท๋ฐ์ PCA ํฌ์๊ณผ ์ฐ๋ฆฌ๊ฐ ์์์ ์ญ ๊ตฌํํด๋ณธ PCA๋ ์๋ก ๊ฑฐ์ธ์ฒ๋ผ ๋ค์งํ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ํ๋ฆฐ ๊ฒ์ ์๋๊ณ , ๊ทธ์ ๊ณ์ฐ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ๊ณ ์ ๋ฒกํฐ๊ฐ ์์๋ ์์ ๊ฐ์ ๊ฐ์ง ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ํ์ํ๋ค๋ฉด ๋ฐ์ดํฐ์ -1์ ๊ณฑํด์ค ์ ์์ต๋๋ค.
๊ณ ์ ๋ฒกํฐ๋ ์ผ๋ฐ์ ์ผ๋ก ๋จ์ ๊ธธ์ด๊ฐ 1์ด ๋๋๋ก ์ ๊ทํ๋์ด์์ต๋๋ค. ์ด์ ํ ์คํธ ์ธํธ๋ฅผ ๋ณํํ๊ณ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ๊ทธ๋ ค๋ณผ๊น์?
plot_decision_regions(X_test_pca, y_test, classifier=lr)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
plt.show()
๋ง์ฝ ์ ์ฒด ์ฃผ์ฑ๋ถ์ ์ค๋ช ๋ ๋ถ์ฐ์ ๋น์จ์ ์๊ณ ์ถ๋ค๋ฉด PCA ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ n_components๋ฅผ None์ผ๋ก ํด๋๊ณ explained_variance_ratio_ ์์ฑ์์ ๋ชจ๋ ์ฃผ์ฑ๋ถ์ ์ค๋ช ๋ ๋ถ์ฐ ๋น์จ์ ์ ์ ์์ต๋๋ค.
pca = PCA(n_components=None)
X_train_pca = pca.fit_transform(X_train_std)
pca.explained_variance_ratio_
์, ์ฌ๊ธฐ๊น์ง๊ฐ PCA์ ๋ํ ์ค๋ช ์ด์์ต๋๋ค. ๋ค์ ์ธ์ ์์๋ LDA๋ฅผ ๋ค๊ณ ๋์์ฌํ ๋ฐ์, ์์ ์๋ง์ ์์์ ๋ํด์ ๋๋ฌด ์ ๊ฒฝ์ฐ์ค ํ์๋ ์์ต๋๋ค. PCA๊ฐ ์ด๋ค ๊ฑฐ๊ณ , ์ด๋ป๊ฒ ์ํ๋๋์ง์ ๋ํด์๋ง ์ธ์งํ๋ฉด ๋ฉ๋๋ค. ์ค์ ๋ก ์์ฃผ ์ฆ๊ฒ ์ฐ์ด๋ ๊ธฐ๋ฒ๋ ์๋๊ณ , ๊ด์ฌ์๋ ๋ถ์ผ๊ฐ ์๋๋ฉด ์๋ ์ฌ๋๋ ์ ์ ๋ถ๋ถ์ ๋๋ค. ๊ทธ๋ผ ๋ค์ ์ธ์ ์์ ๋ต๊ฒ ์ต๋๋ค!