5 minute read

데이터의 차원이 크다고해서(변수가 많은 것) 무조건 분석에 효과적인 것은 아니다. 오히려 계산량을 증가시키고, 분석에 방해가 되는 변수들이 존재할 수도 있다는 것이다. 데이터의 차원이 크면 발생하는 문제점들이 무엇이 있을까?

  • Overfitting의 이슈가 발생한다.
  • 계산량이 많고, 불필요한 변수 때문에 오히려 성능이 저하될 수도 있다.
  • 모델링 후 결과를 해석하기 위한 시각화가 복잡해진다.

이것 외에도 여러가지 이유들이 존재하고, 이번 posting에서는 차원축소에 관련된 여러가지 개념들을 복습해보자.

Vector transformation(벡터 변환)

벡터 변환(선형 변환이라고도 함)은 주어진 벡터에 다른 행렬이나 스칼라 값을 더하거나 곱해서 새로운 벡터를 만드는 것을 말한다.

Eigenvector(고유벡터)와 Eigenvalue(고윳값)

Eigenvector: 벡터 변환을 할 때 기존 벡터의 크기만 변하고 방향은 그대로인 벡터.

Eigenvalue: 고유벡터가 변한 정도(스칼라값). 고유벡터와 고윳값은 항상 쌍을 이루고 있음.

image

image

image

v라는 벡터에 T라는 벡터를 곱해 선형결합을 시켰는데도 v는 기존벡터에 스칼라값을 곱한(크기만 변하고 방향은 그대로인) 벡터인 것을 확인할 수 있다.

이와 같은 상황에서 v를 Eigenvector, lambda를 Eigenvalue라고 한다.

예시에서는 2가 고윳값, [3,-3]이 고유벡터

mat = np.array([[4, 2], [2, 4]])
value, vector = np.linalg.eig(mat)

그렇다면 이 고유벡터와 고윳값이 왜 중요할까?

벡터를 변환하는 방법은 여러가지가 있을 것이다. 크기만 바꿀 수 있고, 방향과 크기를 모두 바꿀 수도 있다. 목적에 따라 다르겠지만, 고윳값은 벡터를 변환할 때 하나의 선택지가 된다.

차원축소에서 가장 많이 활용되는 PCA 기법의 예를 들면, 고유값과 고유벡터는 어떤 행렬의 중요한 정보를 담고 있다.

임의의 벡터를 어느 방향으로 변화시켰는지, 변환 과정에서 변화가 일어나지 않은 부분은 어디인지 알 수 있게 한다. 데이터가 어떤식으로 변화되고 중심축이 어디인지 등을 알 수 있기 때문에 PCA에서 분산이 가장 큰(데이터의 특징이 명확한) 축을 찾는데도 매우 중요하다.

Dimension Reduction

차원축소의 이유: 데이터에서 필요한 변수만 사용함으로써 충분한 의미를 유지하면서도 cost를 줄일 수 있다.

Feature selection:: 상대적으로 덜 중요한 변수를 제거하는 것 = 필요한 변수만 선택하는 것. 변수를 새로 조합하거나 하진 않는다. 기존 변수만 사용. ex) LASSO, RIDGE

장점: 선택된 변수의 해석이 쉽다.

단점: 변수들간의 연관성을 고려해야한다. 상관관계 파악이 어렵다.(변수를 조합한 것이 아니기 때문에)

Feature Extraction: 기존에 있는 변수나 변수들을 조합하여(선형결합) 새로운 변수를 만들어 사용하는 것. ex) PCA, Auto-encoder

장점: 변수간의 연관성이 고려되어 상관관계를 파악하기 용이하다, 차원을 크게 축소할 수 있다.

단점: 변수 해석이 어렵다.

PCA

데이터의 분산을 최대한 보존하면서 서로 직교하는 새 축을 찾아, 고차원 공간의 표본들을 선형 연관성이 없는 저차원 공간으로 변환하는 기법

-> 원래 데이터의 분산(정보)을 최대한 보존하는 축을 찾고, 그 축에 기존 데이터를 사영(Linear Projection)

여기서 새로운 축은 주성분 즉, Eigenvector를 의미한다. 주성분은 원래 변수들의 선형결합으로 생성된 새로 요약된 변수이다.

PCA Proces

1) 각 변수에 대해 평균을 빼고 표준편차로 나누어서 Normalize를 한다.

-> 나중에 공분산 행렬을 구해야하는데 공분산은 scale에 영향을 많이 받으므로, 변수마다 scale이 다를 것이기 때문에 표준화를 거쳐야한다.

2) 표준화된 Z data의 분산-공분산 행렬을 계산한다.

-> 분산이 가장 큰 축을 골라야하기 때문에. 분산이 가장 크다는 것은 데이터가 명확하다는 것이고, 분산이 클수록(데이터끼리 겹치는게 적을수록) 더 많은 기존 정보를 유지할 수 있음.

3) 분산-공분산 매트릭스의 고유벡터와 고유값을 계산한다.

-> 분산을 가장 크게 하는 축인 고유벡터와 고윳값을 찾는다.

-> 예를 들어 데이터를 축으로 투영시킬 때 축이 데이터의 방향과 맞지 않고 이상한 방향으로 설정되었으면 데이터가 축에 투영하러 떨어질 때 겹쳐지게 될 것이다. 공분산은 데이터의 형태를 수치적으로 나타내는 값이기 때문에 우리는 공분산 행렬을 통해 0을 중심으로 데이터가 어느 방향성을 띄고 얼마나 펴져 있는지 알 수 있다. 따라서 이 공분산 행렬의 고유 벡터는 공분산 행렬의 방향을 유지하고 크기만 바뀌는 벡터이기 때문에 데이터를 가장 잘 보존할 수 있는 축이 되는 것이다.

-> 공분산 = 결국, 데이터의 형태를 수치로 표현한 것 -> 공분산 행렬 = 데이터가 어느 방향으로 얼만큼 분포해 있는지 파악할 수 있음 -> 이 공분산 행렬의 고유벡터는 공분산 행렬의 방향은 유지하고 크기만 바뀌는 벡터 -> 데이터를 이 축에 투영시킬 때 기존 데이터의 분포인 공분산 행렬과 방향이 같기 때문에 데이터를 가장 잘 포함함 -> 데이터를 가장 잘 포함함 = 데이터가 겹치지 않고 원래 데이터가 잘 유지됨 -> 데이터가 겹치지 않음 = 데이터가 잘 떨어져있음 = 분산이 큼

4) 데이터를 고유 벡터에 projection 시킨다.

-> 표준화된 데이터와 고유벡터를 선형결합(행렬곱)시키면 투영된 데이터(우리가 얻고자 하는 주성분 = PC)를 얻을 수 있다.

-> 주성분은 고윳값이 가장 큰 순서대로 PC1, PC2, …. 고윳값이 크다 = 분산이 크다.

5) 원하는 갯수의 주성분을 선택한다.

하지만 파이썬으로 이 복잡한 것을 쉽게 구현할 수 있음.

from sklearn.preprocessing import StandardScaler, Normalizer
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

scaler = StandardScaler()
Z = scaler.fit_transform(df.loc[:, df.columns != "species"])
pca = PCA(4)
pca.fit(Z)

ratio = pca.explained_variance_ratio_
print("\n Eigenvectors: \n", pca.components_)
print("\n Eigenvalues: \n",pca.explained_variance_)
print("\n explained variance ratio :", ratio)

pd.DataFrame(pca.transform(Z)) # pca된 데이터를 데이터 프레임으로 얻고싶으면

def scree_plot(pca):
    num_components = len(pca.explained_variance_ratio_)
    ind = np.arange(num_components)
    vals = pca.explained_variance_ratio_ 
    
    ax = plt.subplot()
    cumvals = np.cumsum(vals)
    ax.bar(ind, vals, color = ['#00da75', '#f1c40f',  '#ff6f15', '#3498db']) # Bar plot
    ax.plot(ind, cumvals, color = '#c0392b') # 누적분포 Line plot 
    
    for i in range(num_components): #막대 위에 annotation 추가
        ax.annotate(r"%s" % ((str(vals[i]*100)[:3]+'%')), (ind[i], vals[i]), va = "bottom", ha = "center", fontsize = 13)
     
    ax.set_xlabel("PC")
    ax.set_ylabel("Variance")
    plt.title('Scree plot')
    
scree_plot(pca)
# PC를 2개 고르면 약 87%, 3개 고르면 약 96% 까지 데이터를 설명할 수 있다. 
# 많이 고를수록 설명력은 높아지지만, 차원 축소한 메리트가 사라지게 됨.
# q보통 누적 기여율이 85% 이상이면 해당 지점까지 주성분의 수로 결정하게 됨.
# 90% 설명을 하기 위해서는 PC를 3개 선택해야 하지만, 85% 기준을 충족시킨 2개를 선택하는 것이 더 나을 것 같다.

결론:

Vector Transformation은 벡터에 행렬이나 특정 값을 더하거나 곱하는 것을 말한다. -> 이렇게 어떤 값을 더하고 곱하느냐의 기준을 Eigenvector와 Eigenvalue를 통해 transformation을 정해서 할 수 있다. -> 차원이 늘어나면 중요하지 않은 피처 때문에 계산량이 많아지고 오히려 모델의 성능이 떨어질 수도 있는 문제 발생 -> 이를 보완하기 위해 PCA를 사용하여 차원을 축소(PCA에서 고유벡터와 고윳값을 찾음)

Discussion

Dimension을 축소하는 방법은, 변수 선택(feature selection)과 변수 추출(feature extraction)로 나눌 수 있는데요. 그럼 PCA는 어디에 해당할까요? 또한 나머지 하나(변수 추출과 변수 선택 중 나머지 하나)에는 어떤 예시가 있을까요?

답변:

feature extraction은 기존의 변수들을 변환시켜 새로운 변수를 만들어 좋은 변수를 추출하는 것을 말하고, feature selection은 주어진 변수에서 불필요한 변수를 제거하여 필요한 변수만을 선택하는 것을 말한다.

PCA는 기존 변수의 분산을 최대한 보존하고, 선형 변환을 통해 새로운 변수를 만들고 추출하기 때문에 feature extraction에 해당한다.

변수 선택의 예시로는 Embedded method가 있다. Embedded method는 모델 학습 과정에서 feature에 패널티를 적용시켜 성능에 영향을 끼치지 못하는 feature들은 버리고, 남은 feature로만 다시 학습을 진행시키는 것을 반복하며 최적의 변수를 찾는 것이다. 패널티를 적용하는 알고리즘으로는 LASSO(L1 norm) 와 RIDGE(L2 norm)가 있다고 한다.

변수 선택과 변수 추출 모두 차원을 축소시키기 위해 사용한다. feature selection은 사용자가 해석하기 쉽게 모델을 단순화 한다는 것에 장점이 있다. 하지만 , 변수를 조합하여 선택한 것이 아니기 때문에 변수 간 상관관계를 고려하기 어렵다.

feature extraction은 변수간의 상관관계를 고려하고, 변수의 개수를 크게 줄일 수 있다는 장점이 있지만, 추출된 변수를 해석하기 어렵다는 단점이 있다.

Categories:

Updated: