차원축소는 모델링에 쓰이는 많은 변수들 중 설명력이 낮은 변수를 제거하거나 여러 변수를 결합하여 더욱 의미 있는 변수로 만들어 변수의 수를 줄이는 작업을 말한다. 크게 특성 선정(Feature Selection)과 특성 추출(Feature Extraction)로 나뉜다.
특성 선정에 대해 먼저 알아보자.
특성 선정은 말 그대로 여러 개의 Feature(변수) 중에 설명력 높은 Feature를 선정하는 것이다. 방법은 Forward Search와 Backward Search두 가지가 있다. 말그대로 Forward Search는 변수를 하나씩 모델에 넣어보는 것이다. 10개의 변수(10차원)가 있다면 1개씩 돌아가며 모델링에 사용해 가장 설명력이 높은 변수를 선택하고 그 다음엔 이미 선정한 변수를 제외한 9개의 변수를 기존에 선정한 변수들과 같이 모델링에 사용하여 모델의 성능을 관찰한다. 이러한 작업을 모델의 성능이 유의미하게 증가하지 않을 때까지, 혹은 원하는 변수의 수에 도달할 때까지 반복하면 된다.
Backward Search는 말 그대로 위 작업을 반대로 하면 된다. 10개의 변수를 다 넣은 Full 모델에서 출발하여 하나씩 변수를 제거하면서 모델의 성능을 테스트하면 된다.
그리고 특성 추출에 대해 알아보자.
특성 추출은 Factor Analysis, Multi-Dimensional Scaling, Principal Component Analysis 등이 있다. 차원(변수, Feature)을 축소한다는 점에서 유사하나 그 목적과 의미는 상이하다.
Factor Analysis(요인분석)라는 것은 수 많은 변수들 중에서 잠재된 몇 개의 요인을 찾아내는 것이다. 학생들의 시험 성적을 생각해보자, 국어, 수학, 영어, 중국어, 과학 등의 과목이 있다고 하자. 이는 다음의 요인으로 분석될 수 있다.
수리능력 – 수학, 과학
언어능력 – 국어, 영어, 중국어
즉, 원래 5개의 변수로 구성되어 있지만 내부적으로는 2개의 잠재변수로 구성된다는 것을 파악할 수 있다. 이렇게 변수들간의 상관관계를 고려하여 서로 유사한 변수들끼리 묶어 주는 것을 요인분석이라고 한다.
import pandas as pd
from sklearn.decomposition import FactorAnalysis
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
if __name__ == '__main__':
data = [{'이름': '영수', '분야': '언어', '국어': 100, '영어': 90, '수학': 50, '과학': 45, '중국어': 92},
{'이름': '철수', '분야': '언어', '국어': 98, '영어': 99, '수학': 30, '과학': 46, '중국어': 82},
{'이름': '미혜', '분야': '수리', '국어': 20, '영어': 30, '수학': 99, '과학': 99, '중국어': 42},
{'이름': '영이', '분야': '수리', '국어': 40, '영어': 50, '수학': 80, '과학': 85, '중국어': 62},
{'이름': '영구', '분야': '언어', '국어': 70, '영어': 90, '수학': 40, '과학': 65, '중국어': 99},
{'이름': '구희', '분야': '융합', '국어': 90, '영어': 96, '수학': 60, '과학': 85, '중국어': 100},
{'이름': '지혜', '분야': '융합', '국어': 99, '영어': 92, '수학': 80, '과학': 75, '중국어': 82},
{'이름': '미영', '분야': '융합', '국어': 98, '영어': 90, '수학': 99, '과학': 100, '중국어': 82},
{'이름': '영미', '분야': '수리', '국어': 42, '영어': 40, '수학': 98, '과학': 88, '중국어': 17},
{'이름': '수환', '분야': '수리', '국어': 33, '영어': 10, '수학': 99, '과학': 89, '중국어': 22}]
data = pd.DataFrame(data)
transformer = FactorAnalysis(n_components=2, random_state=0)
X_transformed = transformer.fit_transform(data[['국어', '영어', '수학', '과학','중국어']])
X_transformed = pd.DataFrame(X_transformed, columns=['X', 'Y'])
X_transformed = pd.concat([X_transformed, data['분야']], axis=1)
sns.scatterplot(data=X_transformed, x="X", y="Y", hue='분야')
plt.show()
뛰어난 분야끼리 잘 뭉쳐있는 것을 볼 수 있다.
Multi-Dimensional Scaling(다차원척도법)이라는 것은 변수들의 '비유사성' 거리를 바탕으로, 다중의 변수들을 2차원 혹은 3차원으로 축소하여 나타내는 기법이다. 낮은 차원에서의 변수들이 거리가 멀리 떨어져 위치한다는 것은 비유사성이 높다는 뜻이고 변수가 가까울수록 유사성이 높다는 뜻이다.
import pandas as pd
from sklearn.manifold import MDS
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
if __name__ == '__main__':
data = [{'이름': '영수', '분야': '언어', '국어': 100, '영어': 90, '수학': 50, '과학': 45, '중국어': 92},
{'이름': '철수', '분야': '언어', '국어': 98, '영어': 99, '수학': 30, '과학': 46, '중국어': 82},
{'이름': '미혜', '분야': '수리', '국어': 20, '영어': 30, '수학': 99, '과학': 99, '중국어': 42},
{'이름': '영이', '분야': '수리', '국어': 40, '영어': 50, '수학': 80, '과학': 85, '중국어': 62},
{'이름': '영구', '분야': '언어', '국어': 70, '영어': 90, '수학': 40, '과학': 65, '중국어': 99},
{'이름': '구희', '분야': '융합', '국어': 90, '영어': 96, '수학': 60, '과학': 85, '중국어': 100},
{'이름': '지혜', '분야': '융합', '국어': 99, '영어': 92, '수학': 80, '과학': 75, '중국어': 82},
{'이름': '미영', '분야': '융합', '국어': 98, '영어': 90, '수학': 99, '과학': 100, '중국어': 82},
{'이름': '영미', '분야': '수리', '국어': 42, '영어': 40, '수학': 98, '과학': 88, '중국어': 17},
{'이름': '수환', '분야': '수리', '국어': 33, '영어': 10, '수학': 99, '과학': 89, '중국어': 22}]
data = pd.DataFrame(data)
embedding = MDS(n_components=2)
X_transformed = embedding.fit_transform(data[['국어', '영어', '수학', '과학', '중국어']])
X_transformed = pd.DataFrame(X_transformed, columns=['X', 'Y'])
X_transformed = pd.concat([X_transformed, data['분야']], axis=1)
sns.scatterplot(data=X_transformed, x="X", y="Y", hue='분야')
plt.show()
Principal Component Analysis(주성분분석)라는 것은 상관관계가 있는 변수들을 결합하여 분산을 극대화 하는 성분을 만드는 방법이다.
import pandas as pd
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
if __name__ == '__main__':
data = [{'이름': '영수', '분야': '언어', '국어': 100, '영어': 90, '수학': 50, '과학': 45, '중국어': 92},
{'이름': '철수', '분야': '언어', '국어': 98, '영어': 99, '수학': 30, '과학': 46, '중국어': 82},
{'이름': '미혜', '분야': '수리', '국어': 20, '영어': 30, '수학': 99, '과학': 99, '중국어': 42},
{'이름': '영이', '분야': '수리', '국어': 40, '영어': 50, '수학': 80, '과학': 85, '중국어': 62},
{'이름': '영구', '분야': '언어', '국어': 70, '영어': 90, '수학': 40, '과학': 65, '중국어': 99},
{'이름': '구희', '분야': '융합', '국어': 90, '영어': 96, '수학': 60, '과학': 85, '중국어': 100},
{'이름': '지혜', '분야': '융합', '국어': 99, '영어': 92, '수학': 80, '과학': 75, '중국어': 82},
{'이름': '미영', '분야': '융합', '국어': 98, '영어': 90, '수학': 99, '과학': 100, '중국어': 82},
{'이름': '영미', '분야': '수리', '국어': 42, '영어': 40, '수학': 98, '과학': 88, '중국어': 17},
{'이름': '수환', '분야': '수리', '국어': 33, '영어': 10, '수학': 99, '과학': 89, '중국어': 22}]
data = pd.DataFrame(data)
pca = PCA(n_components=2)
X_transformed = pca.fit_transform(data[['국어', '영어', '수학', '과학', '중국어']])
X_transformed = pd.DataFrame(X_transformed, columns=['PC1', 'PC2'])
X_transformed = pd.concat([X_transformed, data['분야']], axis=1)
sns.scatterplot(data=X_transformed, x="PC1", y="PC2", hue='분야')
plt.show()
요인분석과 비슷하나 차이점이 있다. 요인분석은 기본적으로 대등한 관계를 가진다. 즉 어떤 변수가 더 중요하다라는 개념이 없다. 하지만 주성분분석은 제1주성분, 제2주성분, 제 3주성분 순으로 중요하다. 그리고 요인분석은 목표변수를 고려하지 않고 비슷한 변수들로 묶어 새로운 잠재변수들을 만든다. 하지만 주성분분석은 목표변수를 고려하여 목표변수를 잘 예측 및 분류하기 위하여, 즉 모델의 성능을 높이기 위하여 주성분들을 찾아낸다.
'Data Science > Data Preprocessing' 카테고리의 다른 글
[04. Feature Sampling] 002. Stratified Random Sampling (0) | 2021.07.20 |
---|---|
[04. Feature Sampling] 001. Simple Random Sampling (0) | 2021.07.20 |
[03. Feature Engineering] 005. Dummy (0) | 2021.07.06 |
[03. Feature Engineering] 004. Transform (0) | 2021.06.29 |
[03. Feature Engineering] 003. Binning (0) | 2021.06.29 |