ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 커널 주성분 분석(KPCA)로 차원 축소하기
    Programming & Machine Learning/풀어쓰는 머신러닝 2017. 8. 10. 15:58

    비선형 매핑을 위한 커널 주성분 분석의 사용

    회귀분석과 대부분의 분류 알고리즘에서는 데이터를 선형분리 가능하다는 가정이 필요했다.
    심지어 인공신경망의 기초격인 퍼셉트론에서조차 선형분리 가능을 전제로 알고리즘이 동작했다.
    이러한 문제점들을 PCA, LDA같은 차원 축소 기법으로 해결했으나
    데이터의 모양이 정말로, 완전히, 앱솔루틀리 하게 비선형인 경우는 문제가 달라진다.
    
    PCA, LDA 같은 알고리즘은 차원축소를 위한 선형 변환 기법을 이용하기 때문에,
    선형으로 분리 불가능한 데이터에 대해서는 적당하지 않다. 
    
    이런 문제를 극복하기 위해 커널 PCA를 사용할 수 있다.
    
    SVM에서의 커널 기법을 떠올려보자. 원래의 d차원 데이터를 k차원으로 (더 큰 차원으로)
    매핑하는 하나의 함수를 생각할 수 있다. 이 때, 커널을 활용하여 데이터를 고차원으로 변환하는
    비선형 매핑을 수행한 뒤, 일반적인 PCA를 통해 데이터들이 선형 분리가 가능한 저차원 공간으로
    다시 투영하는 아이디어를 생각해보자. 이 아이디어가 커널 PCA의 기본적인 생각이다.
    
    하지만 이런 방법은 굉장히 비효율적이다. 
    
    이 문제를 효율적으로 해결하기에 앞서 잠시 앞으로 돌아가 볼 필요가 있다.
    우리는 앞서 PCA에서 피처간의 관계를 공분산 행렬로 표현하였다. 
    공분산은 피처간의 내적을 통해 표현이 되기도 한다. 
    즉, 두 피처간의 벡터의 내적이란 두 데이터의 유사도를 의미하기도 한다는 것이다.
    
    그렇다면 두 벡터 사이를 내적하는 부분의 함수를, 데이터를 고차원으로 mapping하는 커널 함수로
    대체하는 것은 어떨까? 아마도 두 데이터의 상관관계를 우리가 정한 kernel function으로써 
    나타내는 것이 가능해질 것이고, 유사도라는 개념을 더욱 범용적이고 고차원적인 방법으로 사용이 가능해진다.
    
    
    벡터의 내적을 이용하여 상관관계를 구하게 되면, 그 관계의 모양은 linear한 선형적 의미를 가진다.
    하지만 커널을 사용한다면, 그 커널과 맞는 선형적 의미를 가지게 된다. 당연히 가우시안 커널을 사용한다면
    방사형의 관계를 가지게 될 것이다.
    
    다시 kernel PCA로 돌아와보자. PCA는 주어진 데이터셋을 linear 벡터 형식의 주성분 분석을 통해
    새로운 basis에 projection 시키는 과정이라고 할 수 있다. 
    하지만 만약 여기서 데이터의 주성분 분석이 kernel의 형태라면, 
    기존의 linear projection이 nonlinear한 projection으로 바뀌게 될 것이다.
    그 결과, 우리가 분류하고자 하는 데이터셋은 커널의 성질을 띤 채로 non-linear하게 구분이 된다.
    
    

    python에 구현되어있는 kernel PCA

    from sklearn.decomposition import KernelPCA
    
    X, y = make_moons(n_samples=100, random_state=123)
    scikit_kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15)
    X_skernpca = scikit_kpca.fit_transform(X)
    
    plt.scatter(X_skernpca[y==0, 0], X_skernpca[y==0, 1], 
                color='red', marker='^', alpha=0.5)
    plt.scatter(X_skernpca[y==1, 0], X_skernpca[y==1, 1], 
                color='blue', marker='o', alpha=0.5)
    
    plt.xlabel('PC1')
    plt.ylabel('PC2')
    plt.tight_layout()
    # plt.savefig('./figures/scikit_kpca.png', dpi=300)
    plt.show()


    댓글

분노의 분석실 Y.LAB