๐งฉ ๋ฐ์ดํฐ๋ง์ด๋(18) ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ_11 : Reduction / ์ฃผ์ฑ๋ถ ๋ถ์2
๐งฉ ์ ๋ฒ ํฌ์คํ ์์๋ PCA์ ๊ฐ๋ ์ ๋ํด์, ๊ทธ๋ฆฌ๊ณ ํนํ ๊ทธ ํน์ง์ ๋ํด์ ์์ธํ ์์๋ณด์๋ค. ์ต๋ํ ๋ด๊ฐ ๊ณต๋ถํ๋ฉด์ ๊ถ๊ธํ๋ ์ , ๊ทธ๋ฆฌ๊ณ ๊ฒ์์ ํด๋ ์ ๋ชจ๋ฅด๋ ๋ด์ฉ์ ์ค์ฌ์ผ๋ก ๋ค๋ฃจ์ด ๋ดค๋๋ฐ ์ด๋ ์ ์ง ๋ชจ๋ฅด๊ฒ ๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ ์ ๋ฒ ํ๊ธฐ์ ์งํํ ๋ฐ์ดํฐ๋ง์ด๋ ํ๋ก์ ํธ๋ฅผ ํตํด PCA ๋ถ์์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ด์ง ์์๋ณด๋๋ก ํ์.
1. PCA ์ฝ๋ ๊ตฌํ
๐งฉ ํ๋ก์ ํธ๋ฅผ ์ํด ์ฌ์ฉํ ๋ฐ์ดํฐ๋ ์บ๊ธ์์ ๊ตฌํ Cardiovascular Disease dataset ์ด๋ค. ๊ถ๊ธํ ๋ถ์ ๋งํฌ๋ฅผ ๊ฑธ์ด๋์์ผ๋ ํ๋ฒ ํ์ธํด ๋ณด๋ฉด์ ํฌ์คํ ์ ๋ด๋ ์ข์ ๊ฒ ๊ฐ๋ค. ์ฌํ๊ด ์งํ์ ์ ๋ฌด๋ฅผ ํตํด ์ง๋ณ์ ๋ฐ๋ณ์ ์ํฅ์ ๋ฏธ์น๋ ์ฌ๋ฌ๊ฐ์ง ์์ธ๋ค์ ์ดํด ์ต์ข ์ง๋ณ ์ ๋ฌด๋ฅผ ํ์ธํ๋ ๊ฒ์ด ํ๋ก์ ํธ์ ๋ชฉ์ ์ด์๋ค. ๋ฐ๋ผ์ ์ง๋ณ์ ์ ๋ฌด๋ฅผ ๊ฐ์ฅ ์ ๋ํ๋ด๋ ํน์ง์ ์ ํํ๊ธฐ ์ํด ์ฌ๋ฌ ์ฐ๊ด๊ด๊ณ ๋ถ์ ๋ฐฉ๋ฒ์ ์คํํด๋ดค์ผ๋ฉฐ, ๊ทธ ์ค ํ๋๊ฐ ์ค๋ ์ดํด๋ณผ PCA ์ด๋ค.
๐งฉ PCA๋ถ์์ ์ํด sklearn.decomposition ๋ชจ๋์ PCA ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ผ๋ฉฐ, ์๊ฐํ๋ฅผ ์ํด์๋ plotly ๊ณต์ ํํ์ด์ง๋ฅผ ์ฐธ๊ณ ํ๋ค.
๐ฉ ๋ฐ์ดํฐ ํ์ธ
- 70000๋ช
์ ์กฐ์ฌ๊ตฐ์ ๋์์ผ๋ก 12๊ฐ์ attribute์ ์ฌํ๊ด ์งํ์ ์ ๋ฌด๋ฅผ ๋ํ๋ด๋ cardio๋ผ๋ attribute๋ก ๋ฐ์ดํฐ๊ฐ ๊ตฌ์ฑ๋๋ฉฐ, cardio๋ 0์ธ ๊ฒฝ์ฐ ์ง๋ณ์ด ์์์, 1์ธ ๊ฒฝ์ฐ ์ง๋ณ์ด ์์์ ์๋ฏธํ๋ค.
๐ฉ PCA ๊ตฌํ ๋ฐ ์๊ฐํ_Dimension 3
๐งฉ ๋จผ์ ์ฝ๋๋ถํฐ ํ์ธํด๋ณด๋๋ก ํ์๐.
# target๊ณผ feature data ์ค์
# cardio๊ฐ 0์ธ object๋ 'N' ์ผ๋ก ๋ณํ
# cardio๊ฐ 1์ธ object๋ 'Y' ๋ก ๋ณํ
cardio_target = cardio['cardio'].copy()
cardio_target[cardio_target==0] = 'N'
cardio_target[cardio_target==1] = 'Y'
cardio_feat = cardio.drop('cardio',axis = 1)
# sklearn.decomposition ๋ชจ๋์ PCA library ์ํฌํธ
# pca.fit_transform() : cardio[features]๋ฅผ scaling ํ ๋ค์ principal component๋ก ๋ณํ
# pca.explained_variance_ratio_ : dimension์ ๋ฐ๋ฅธ variance ์ค๋ช
์ ๋
pca = PCA()
components = pca.fit_transform(cardio_feat)
# PCA ๊ฒฐ๊ณผ ์๊ฐํ
labels = {
str(i): f"PC {i+1} ({var:.1f}%)"
for i, var in enumerate(pca.explained_variance_ratio_ * 100)
}
fig = px.scatter_matrix(
components,
labels=labels,
dimensions=range(3),
color=cardio_target, opacity = 0.5
)
fig.update_traces(diagonal_visible=False)
fig.show()
- ์์ ํฌ์คํ
์์๋ ์ธ๊ธํ๋ฏ์ด, PCA๊ณผ์ ์์ ๋ง๋ค์ด์ง๋ Principal Component์ ์์ ๋ฐ๋ผ์ ์๋ณธ ๋ฐ์ดํฐ์ variance ์ค๋ช
์ ๋๊ฐ ๊ฒฐ์ ๋๊ธฐ ๋๋ฌธ์ ์ด dimension์ ๊ฒฐ์ ํ๋ ๋ณ์๊ฐ ์กด์ฌํ๋ค. ์ ์ฝ๋์์ dimensions = range(3)๊ฐ ๊ทธ ๋ณ์์ด๋ฉฐ, ์ด๋ฅผ ํตํด PCA ๊ฒฐ๊ณผ๋ฅผ ์๊ฐํํ๋ฉด ์๋์ ๊ฐ๋ค.
-
๊ทธ ๊ฒฐ๊ณผ target์ผ๋ก ์ค์ ํ cardio attribut๊ฐ ๊ฐ๊ฐ 3๊ฐ์ ์ฐจ์์์ ์ค๋ช ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ผ๋ฉฐ, PC1๊ณผ PC2์์ ๋๋ถ๋ถ์ variance๊ฐ ์ค๋ช ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค๐. PCA๋ฅผ ๊ณต๋ถํ ๋ถ์ด๋ผ๋ฉด ์์๊ฒ ์ง๋ง ์์ ๊ฒฐ๊ณผ๋ target label์ ๋ฐ๋ผ ์ ๋ช ํ๊ฒ ๋ถ๋ฅ๋ ๊ฒฝ์ฐ๋ ์๋๋ค. ๊ฐ attribute์ ๋ฐ๋ผ target label์ด ๋ช ํํ๊ฒ ๊ฒฐ์ ๋๋ค๋ฉด, ์์ ๊ฒฝ์ฐ์ฒ๋ผ ์ ๋ค์ด ๊ฒน์น๊ธฐ๋ณด๋ค๋ ๋ช ํํ ๊ตฌ๋ถ๋๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค๊ฒ ๋๋ฉฐ, PC1์์ 90%๊ฐ ๋๋ ์ค๋ช ์ ๋๋ฅผ ๊ฐ์ง๋ค. ํ์ง๋ง ์ด๋ ๋ฐ์ดํฐ์ ์ฐจ์ด๋ผ๊ณ ๋ณผ์ ์๊ธฐ ๋๋ฌธ์, ๊ทธ๋ ๊ฒ ์ ๊ฒฝ์ธ ๋ถ๋ถ์ ์๋ ๊ฒ์ด๋ผ ์๊ฐํ๊ณ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ค.
-
์ด๋ฒ์๋ dimension์ด 4์ธ ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณด๋๋ก ํ์.
๐ฉ PCA ๊ตฌํ ๋ฐ ์๊ฐํ_Dimension 4
# ์ฌ์ฉํ๋ ค๋ principal componenet ๊ฐ์ ์ ์
n_components = 4
# sklearn.decomposition ๋ชจ๋์ PCA library ์ํฌํธ. principal componenet ๊ฐ์ ์ ์.
# pca.fit_transform() : cardio[features]๋ฅผ scaling ํ ๋ค์ principal component๋ก ๋ณํ
# pca.explained_variance_ratio_ : dimension์ ๋ฐ๋ฅธ variance ์ค๋ช
์ ๋
pca = PCA(n_components=n_components)
components = pca.fit_transform(cardio)
# PCA ๊ฒฐ๊ณผ ์๊ฐํ
total_var = pca.explained_variance_ratio_.sum() * 100
labels = {str(i): f"PC {i+1}" for i in range(n_components)}
fig = px.scatter_matrix(
components,
color=cardio_target,
opacity = 0.5,
dimensions=range(n_components),
labels=labels,
title=f'Total Explained Variance: {total_var:.2f}%',
)
fig.update_traces(diagonal_visible=False)
fig.show()
- ์์ ์ฝ๋๋ ์์ ์ฝ๋์ ๋ฌ๋ฆฌ n_components ๋ณ์๋ฅผ ํตํด princiapl component์ ๊ฐ์๋ฅผ ๋ฏธ๋ฆฌ ์ค์ ํด๋๊ณ PCA๋ฅผ ์งํํ๋ค. ๊ทธ ๊ฒฐ๊ณผ๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ๋ค.
- PC4 ๊น์ง ์ฌ์ฉํ ๊ฒฝ์ฐ์ ์๋ณธ ๋ฐ์ดํฐ์ variance๋ฅผ 99.58% ๊น์ง ์ค๋ช ํ๋ ๊ฒ์ ํ์ธํ๊ณ , ์ด์ PCA ๋ถ์์ ์ํด dimension์ 4๋ก ์ค์ ํ๊ธฐ๋ก ํ๋ค. ๋น์ฐํ PC์ ์๊ฐ ๋์ด๋ ์๋ก ์ค๋ช ์ ๋๋ ์ฆ๊ฐํ ๊ฒ์ด๊ธฐ์, ์ด๋ฅผ ํ์ธํด๋ณด๊ธฐ ์ํด์ ์๊ฐํ๋ฅผ ์งํํ์๋ค.
# dimension์ ๋ฐ๋ฅธ variance ์ค๋ช
์ ๋์ ๋์ ํฉ ์๊ฐํ
pca = PCA()
pca.fit(cardio)
exp_var_cumul = np.cumsum(pca.explained_variance_ratio_)
px.area(
x=range(1, exp_var_cumul.shape[0] + 1),
y=exp_var_cumul,
labels={"x": "# Components", "y": "Explained Variance"}
)
- ์ด ๊ฒฐ๊ณผ๋ฅผ ํ ๋๋ก dimension์ 4๋ก ์ค์ ํด์ ๊ฐ attribute ๊ฐ์ ์ฐ๊ด๊ด๊ณ๋ฅผ ์์๋ณผ ๊ฒ์ด๋ค.
๐ฉ attribute ์ฐ๊ด๊ด๊ณ ํ์
๐งฉ ์์ ์ค๋ช ํ PCA์ ๋ํ ๊ฐ๋ ๋ง ๊ฐ์ง๊ณ ์ ์ค์ ๋ก ์ฐ๊ด๊ด๊ณ๋ฅผ ์ด๋ป๊ฒ ๋ถ์ํ๋์ง ์๊ธฐ๋ ์ด๋ ต๋ค. ์ด๋ฅผ ์ํด ์ฌ์ดํท๋ฐ๊ณผ plotly ์์๋ ๊ฐ attribute์ ๋ฐฉํฅ์ฑ์ ํ์ ํ๊ธฐ ์ํ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ, ์๋ ์ฝ๋๋ฅผ ๋ณด๊ณ ์์๋ณด๋๋ก ํ์.
# vardiance๋ฅผ ์ค๋ช
ํ๋ ๋ฐ ์ฌ์ฉ๋ original attribute vector์ ๋ฐฉํฅ์ฑ ํ์
X = cardio[cardio_feat.columns]
pca = PCA(n_components=4)
components = pca.fit_transform(X)
loadings = pca.components_.T * np.sqrt(pca.explained_variance_)
fig = px.scatter(components, x=0, y=1, color=cardio_target, opacity = 0.5)
for i, feature in enumerate(X):
fig.add_shape(
type='line',
x0=0, y0=0,
x1=loadings[i, 0],
y1=loadings[i, 1],
line=dict(color="springgreen",width=3.5)
)
fig.add_annotation(
x=loadings[i, 0],
y=loadings[i, 1],
ax=0, ay=0,
xanchor="center",
yanchor="bottom",
text=feature,
font = {'color':'white'},
bgcolor = 'grey'
)
fig.show()
- loadings ๋ณ์๋ฅผ ํตํด ๊ฐ attribute vector์ ๋ฐฉํฅ์ ๋ํ๋ผ์ ์๋๋ก ํ๊ณ , for ๋ฌธ์ ์ฌ์ฉํด์ ๋ชจ๋ point์ vector๋ฅผ ์๊ฐํํ๋ค. ๊ทธ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
- ์ด ๊ฒฐ๊ณผ๋ง ๊ฐ์ง๊ณ ์ ํํ attribute์ ๋ฐฉํฅ์ฑ์ ํ์
ํ๊ธฐ์๋ ๊ฐ vector๊ฐ ๋๋ฌด ๊ฒน์ณ์๊ธฐ ๋๋ฌธ์, plotly์์๋ ์ด๋ฅผ ํ๋ํด์ ๋ณผ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ํ๋ํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๐งฉ PCA ๋ถ์์ ๊ฒฐ๊ณผ ์๋ก ๊ฐ์ฅ ์ฐ๊ด๊ด๊ณ๊ฐ ๊ฐ์ฅ ๋์ attribute๋ ๋ค์๊ณผ ๊ฐ์ด ๊ฒฐ์ ๋๋ค.
๐ฉ PCA DataFrame
๐งฉ ๋ง์ง๋ง์ผ๋ก ์์ ๊ฒฐ๊ณผ ์ ํ๋ [ap_hi, ap_lo, BMI, gluc, cholestero] attribute๋ฅผ ๊ฐ์ง๊ณ PCA DataFrame์ ๋ง๋ค์ด๋ณด์๐.
# PCA Dataframe ์ถ๋ ฅ
pca = PCA(n_components=n_components)
components = pca.fit_transform(cardio)
PCA_df = pd.DataFrame({'PC1' : components[:,0],
'PC2' : components[:,1],
'PC3' : components[:,2],
'PC4' : components[:,3],
'cardio' : cardio['cardio']})
PCA_df
- ์์ ๋ฐ์ดํฐํ๋ ์์ ๋ณด๋ฉด ์ฒ์์ 70000 object๊ฐ 64500 object๋ก ๋ณํ ๊ฒ์ ํ์ธํ ์ ์๋๋ฐ, ์ด๋ outlier๋ค์ ์ ๊ฑฐํ๋ ๊ณผ์ ์์ ์๊ฐ ์ค์ด๋ ๊ฒ์ด๋ค.
PCA ์ ๋ฆฌ
๐งฉ ์์ ํฌ์คํ ๊ณผ ์ด๋ฒ ํฌ์คํ ์ ๊ฒฐ๊ณผ PCA์ ๋ํ ์์ฝ์ ์๋์ ๊ฐ์ด ์ ๋ฆฌํ ์ ์๋ค.
- ๊ทธ๋ฆฌ๊ณ ๊ทธ ์๋ก์ด attributes๊ฐ ์๋ก์ด ์ถ์ธ principal component๋ก ์ ์๋จ.
-
๊ธฐ์กด์ ๋ฐ์ดํฐ๋ค์ ์๋ก์ด ์ถ PC1, PC2โฆ์์ ์๋ก์ด ์ขํ๋ฅผ ๊ฐ์ง๊ฒ ๋จ.
- ์๋ก์ด ์ถ๋ค์ ๋ง๋ ๋ค์ ๊ทธ ์ถ๋ค์ ๊ธฐ์ค์ผ๋ก ์๋ ๋ฐ์ดํฐ์ variance๋ฅผ ์ ์ค๋ช ํ๋ ์์๋๋ก ๋ฒํธ๋ฅผ ๋งค๊น.
- ๋๋ถ๋ถ์ variance๊ฐ PC1๊ณผ PC2๋ง ๊ฐ์ง๊ณ ์ ์ค๋ช ์ด ๊ฐ๋ฅํจ.
-
์ํ๋ ์ ๋๊น์ง๋ง variance๋ฅผ ์ค๋ช ํ๋ฉด ๋๊ณ , ์ด๋ฅผ ๋ง์กฑํ๋ Principal Component๊น์ง๋ง ์ ํํ ๊ฒ์ด๋ฏ๋ก, ์ ํ๊ณผ์ ์์ Dimensionality Reduction.
- attribute vector์ ๋ฐฉํฅ์ฑ์ ๊ธฐ์ค์ผ๋ก ์๋ก ์ฐ๊ด๊ด๊ณ๊ฐ ์๋ attribute๋ฅผ ์์๋ผ ์ ์์.
๐งฉ ์ด๋ ๊ฒ ํด์ Preprocessing์์ ๊ฐ์ฅ ์ค์ํ ๊ฐ๋ ์ด๋ผ๊ณ ํ ์ ์๋ PCA ๋ถ์์ ๋ชจ๋ ์์๋ณด์๋ค. ๊ฐ๋ ์์ฒด๊ฐ ๊ทธ๋ ๊ฒ ์ฝ์ง๋ ์์ง๋ง ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์์ ์ด ๋ถ์ ๋ฐฉ๋ฒ์ ์ง์ํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ๊ฒ๋จน์ง ์์๋ ๋ ๊ฒ ๊ฐ๋ค๐.
๐งฉ ํ๋ก์ ํธ ์งํ ๊ณผ์ ์์ ๋์์ ๋ฐ์ ์ฌ์ดํธ์ ๋ด ๋ธ๋ก๊ทธ์ plotly ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํฌ์คํ ์ ๊ณต์ ํ ํ ๋ ๊ถ๊ธํ์ ๋ถ๋ค์ ๋ ์ฐธ๊ณ ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค๐๐.
๐ PCA Visualization in Python
๐งฉ ๋ค์ ํฌ์คํ ์์๋ Preprocessing์ ๋ง์ง๋ง ๊ฐ๋ ์ธ Data Transformation์ ๋ํด ์์๋ณด์๐โโ๏ธ๐โโ๏ธ๐โโ๏ธ.
Leave a comment