Python 데이터 분석
Python 데이터분석 기초 67 - 특성공학 기법 중 차원축소(PCA - 주성분 분석)-iris dataset
코딩탕탕
2022. 11. 24. 11:17
특성공학 기법 중 차원축소(PCA - 주성분 분석)
n개의 관측치와 p개의 변수로 구성된 데이터를 상관관계가 최소화된 k개의 변수로 축소된 데이터를 만든다.
데이터의 분산을 최대한 보존하는 새로운 축을 찾고 그 축에 데이터를 사영시키는 기법. 직교.
목적 : 독립변수(x, feature)의 갯수를 줄임. 이미지 차원 축소로 용량을 최소화
# 특성공학 기법 중 차원축소(PCA - 주성분 분석)
# n개의 관측치와 p개의 변수로 구성된 데이터를 상관관계가 최소화된 k개의 변수로 축소된 데이터를 만든다.
# 데이터의 분산을 최대한 보존하는 새로운 축을 찾고 그 축에 데이터를 사영시키는 기법. 직교.
# 목적 : 독립변수(x, feature)의 갯수를 줄임. 이미지 차원 축소로 용량을 최소화
# iris dataset으로 PCA를 진행
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
plt.rc('font', family='malgun gothic')
import seaborn as sns
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
n = 10
x = iris.data[:n, :2]
print(x, x.shape, type(x))
print(x.T) # T는 행렬을 바꿔준다.
# plt.plot(x.T, 'o:')
# plt.xticks(range(2))
# plt.grid()
# plt.legend(['표본{}'.format(i) for i in range(n)])
# plt.show()
"""
# 산점도
df = pd.DataFrame(x)
# print(df)
ax = sns.scatterplot(0, 1, data = pd.DataFrame(x), marker = 's', s = 100, color = '.2') # marker : 모양 스퀘어(사각형), s : 크기
for i in range(n):
ax.text(x[i, 0] - 0.05, x[i, 1] - 0.07, '표본{}'.format(i + 1))
plt.xlabel('꽃받침길이')
plt.ylabel('꽃받침넓이')
plt.axis('equal')
plt.show()
"""
# PCA
pca1 = PCA(n_components=1) # n_components : 변환할 차원 수
x_low = pca1.fit_transform(x) # 비지도학습. 차원 축소된 근사 데이터
print('x_low :', x_low, ' ', x_low.shape)
x2 = pca1.inverse_transform(x_low) # 차원 축소된 근사 데이터를 원복
print('원복된 결과 :', x2, ' ', x2.shape)
print(x)
print(x_low[0])
print(x2[0, :])
print(x[0])
"""
# 시각화
ax = sns.scatterplot(0, 1, data = pd.DataFrame(x), marker = 's', s = 100, color = '.2') # marker : 모양 스퀘어(사각형), s : 크기
for i in range(n):
d = 0.03 if x[i, 1] > x2[i, 1] else -0.04
ax.text(x[i, 0] - 0.07, x[i, 1] - d, '표본{}'.format(i + 1))
plt.plot([x[i, 0], x2[i, 0]], [x[i, 1], x2[i, 1]], 'k--')
plt.plot(x2[:, 0], x2[:, 1], 'o-', color = 'b', markersize = 10)
plt.xlabel('꽃받침길이')
plt.ylabel('꽃받침넓이')
plt.axis('equal')
plt.show()
"""
# iris 4개의 열을 모두 참여(스케일링하고 PCA하는 것이 좋음
x = iris.data
pca2 = PCA(n_components = 2) # n_components : 변환할 차원 수
x_low2 = pca2.fit_transform(x)
print('x_low2 :', x_low2[:3], ' ', x_low2.shape)
print(pca2.explained_variance_ratio_) # 전체 변동성에서 개별 PCA 결과(개별 component) 별로 차지하는 변동성 비율을 제공
# [0.92461872 0.05306648] # 0.9776852
x4 = pca2.inverse_transform(x_low2)
print('최초 자료 :', x[0])
print('차원 축소 :', x_low2[0])
print('차원 복귀 :', x4[0]) # PCA를 통해 근사행렬로 변환됨
print()
iris2 = pd.DataFrame(x_low2, columns = ['f1','f2'])
print(iris2.head(3))
<console>
[[5.1 3.5]
[4.9 3. ]
[4.7 3.2]
[4.6 3.1]
[5. 3.6]
[5.4 3.9]
[4.6 3.4]
[5. 3.4]
[4.4 2.9]
[4.9 3.1]] (10, 2) <class 'numpy.ndarray'>
[[5.1 4.9 4.7 4.6 5. 5.4 4.6 5. 4.4 4.9]
[3.5 3. 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1]]
x_low : [[ 0.30270263]
[-0.1990931 ]
[-0.18962889]
[-0.33097106]
[ 0.30743473]
[ 0.79976625]
[-0.11185966]
[ 0.16136046]
[-0.61365539]
[-0.12605597]] (10, 1)
원복된 결과 : [[5.06676112 3.53108532]
[4.7240094 3.1645881 ]
[4.73047393 3.17150049]
[4.63393012 3.06826822]
[5.06999338 3.53454152]
[5.40628057 3.89412635]
[4.78359423 3.22830091]
[4.97021731 3.42785306]
[4.44084251 2.86180369]
[4.77389743 3.21793233]] (10, 2)
[[5.1 3.5]
[4.9 3. ]
[4.7 3.2]
[4.6 3.1]
[5. 3.6]
[5.4 3.9]
[4.6 3.4]
[5. 3.4]
[4.4 2.9]
[4.9 3.1]]
[0.30270263]
[5.06676112 3.53108532]
[5.1 3.5]
x_low2 : [[-2.68412563 0.31939725]
[-2.71414169 -0.17700123]
[-2.88899057 -0.14494943]] (150, 2)
[0.92461872 0.05306648]
최초 자료 : [5.1 3.5 1.4 0.2]
차원 축소 : [-2.68412563 0.31939725]
차원 복귀 : [5.08303897 3.51741393 1.40321372 0.21353169]
f1 f2
0 -2.684126 0.319397
1 -2.714142 -0.177001
2 -2.888991 -0.144949


