데이터 집합 내에 존재하는 각 데이터의 차이를 가장 잘 나타내 주는 요소를 찾아 내는 방법
통계 데이터 분석(주성분 찾기), 데이터 압축(차원감소), 노이즈 제거 등 다양한 분야에서 사용


그려보면
plt.scatter(X[:,0], X[:,1])
plt.axis('equal') #x, y축 간격을 같게 만드는 옵션

#fit
from sklearn.decomposition import PCA
pca = PCA(n_components=2, random_state=13)
pca.fit(X)

#벡터를 그리는 함수
def draw_vector(v0, v1, ax=None):
ax = ax or plt.gca() #ax=none이면 plt.gca(), 다른 ax 설정이 들어오면 그걸 써라
arrowprops = dict(
arrowstyle='->', #화살표 스타일
linewidth=2, #줄크기
color='black', #색상
shrinkA=0, #
shrinkB=0
)
ax.annotate('', v1, v0, arrowprops=arrowprops) #annotate함수는 글자를 찍는 함수인데, 우리는 화살표만 표현하기 위해서 ''로 두었고,
#v1에서 v0까지 그려라
pca.mean_ #그래프에서 원점역할, 데이터의 중심, 가장 큰 영향력을 미치는 벡터
#그래프
plt.scatter(X[:,0], X[:,1], alpha=0.4)
for length, vector in zip(pca.explained_variance_, pca.components_):
v = vector * 3 * np.sqrt(length) #적당한 크기로 만들기 위해 3을 곱함
draw_vector(pca.mean_, pca.mean_+v)
plt.axis('equal')
plt.show()

데이터의 주성분을 찾은 다음 주축을 변경하는 것도 가능하다
이번에는 n_components를 1로 두고

X_pca = pca.transform(X)
X_new = pca.inverse_transform(X_pca) #2차원 -> 1차원 : pca 이것을 2차원 표현으로 바꿈 (X_new)
plt.scatter(X[:,0], X[:,1], alpha=0.3)
plt.scatter(X_new[:,0], X_new[:,1], alpha=0.9)
plt.axis('equal')
plt.show()

iris 데이터로 실습해보자

#scaler 적용
from sklearn.preprocessing import StandardScaler
iris_ss = StandardScaler().fit_transform(iris.data)
iris_ss[:3]
#pca 결과를 return하는 함수
from sklearn.decomposition import PCA
def get_pca_data(ss_data, n_components=2):
pca = PCA(n_components=n_components)
pca.fit(ss_data)
return pca.transform(ss_data), pca

#pca 결과를 데이터프레임으로
def get_pd_from_pca(pca_data, cols=['PC1', 'PC2']):
return pd.DataFrame(pca_data, columns=cols)
#4개의 특성을 두개의 특성으로
iris_pd_pca = get_pd_from_pca(iris_pca)
iris_pd_pca['species'] = iris.target
#두 개의 특성 그리기
sns.pairplot(iris_pd_pca, hue='species', height=5, x_vars=['PC1'], y_vars=['PC2'])

#4개 특성을 모두 사용해서 randomforest
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
def rf_scores(X,y,cv=5):
rf = RandomForestClassifier(random_state=13, n_estimators=100)
scores_rf = cross_val_score(rf, X, y, scoring='accuracy', cv=cv)
print('Score : ', np.mean(scores_rf))

wine 데이터로 실습해보자




pca_columns = ['PC1', 'PC2']
pca_wine_pd = pd.DataFrame(pca_wine, columns=pca_columns)
pca_wine_pd['color'] = wine_y.values
sns.pairplot(pca_wine_pd, hue='color', height=5, x_vars=['PC1'], y_vars=['PC2'])



pca_wine_plot = pca_X
pca_wine_plot['color'] = wine_y.values
import plotly.express as px
fig = px.scatter_3d(pca_wine_plot, x='PC1', y='PC2', z='PC3', color='color', symbol='color', opacity=0.4)
fig.update_layout(margin=dict(l=0, r=0, b=0, t=0))
fig.show()
