[ML] dimensionality reduction (차원 축소)

Woong·2023년 8월 23일
0

Python / Machine Learning

목록 보기
12/22

dimensionality reduction (차원 축소)

  • 모델 복잡도를 줄이고 overfitting 을 방지하는 방법 중 하나
    • feature selection : original feature 에서 일부를 선택
    • feature extraction: original feature 에서 새로운 feature 생성

The curse of dimensionality (차원의 저주)

  • feature (=dimension) 이 너무 많으면 알고리즘이 복잡 & 성능 저하
  • dimension (차원) 이 증가할수록 데이터간 거리가 멀어짐 (데이터 희소성)
    • overfitting 발생 가능성 증가

sequential feature selection

  • 초기 dd 차원 feature 를 k<dk<dkk 차원의 feature subspace (부분 공간) 으로 축소
    • greedy search 알고리즘.
    • 주어진 문제에 가장 관련이 높은 feature subspace 를 자동으로 선택
    • 관계없는 feature 와 noise 를 제거, 일반화 오차를 줄인다.
    • regularization (규제) 를 제공하지 않는 알고리즘에 유용
    • Sequential Backward Selection (SBS) 알고리즘 등이 있음

Sequential Backward Selection

  • 새로운 feature subspace 가 목표 feature 개수가 될 때까지, 전체 feature에서 순차적으로 제거
  • 각 단계별 어떤 feature 를 제거할지 판단 기준 : feature 제거 전/후 모델 성능 차이
    • 성능 손실이 최소가 되는 feature 제거
  • scikit-learn 에서는 SequentialFeatureSelector 로 구현
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.neighbors import KNeighborsClassifier


def test_sequential_feature_selector():
    # wine dataset
    df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None)
    df_wine.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash',
                       'Alkalinity of ash', 'Magnesium', 'Total phenols', 'Flavanoids',
                       'Nonflavanoid phenols', 'Proanthocyanidins', 'Color intensity', 'Hue',
                       'OD280/OD315 of diluted wines', 'Proline']

    # split dataset
    x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=0, stratify=y)

    # feature 표준화
    sc = StandardScaler()
    # traing data set 의 feature dimension 마다 평균과 표준 편차 계산
    sc.fit(x_train)

    # transform: 평균과 표준 편차로 data set 을 표준화
    x_train_std = sc.transform(x_train)
    x_test_std = sc.transform(x_test)
    

	# k-NN
    knn = KNeighborsClassifier(n_neighbors=5)

    scores = [] # feature selesction 갯수별로 score 담을 배열
    for n_features in range(1, 13): # 1~12개의 feature selection 테스트
        # n_features_to_select : 선택할 feature 갯수
        # n_jobs: CPU 수에 따라 코어 지정
        # direction: feature selection 방향 지정. forward, backward
        sfs = SequentialFeatureSelector(knn, n_features_to_select=n_features, n_jobs=-1)
        sfs.fit(x_train_std, y_train)
        
        f_mask = sfs.support_
        knn.fit(x_train_std[:, f_mask], y_train)
        scores.append(knn.score(x_train_std[:, f_mask], y_train))

    plt.plot(range(1, 13), scores, marker='o')
    plt.ylim([0.7, 1.02])
    plt.ylabel('Accuracy')
    plt.xlabel('Number of features')
    plt.grid()
    plt.tight_layout()
    plt.show()

    sfs = SequentialFeatureSelector(knn, n_features_to_select=7, n_jobs=-1)
    sfs.fit(x_train_std, y_train)
    print(sfs.n_features_to_select_)
    f_mask = sfs.support_
    df_wine.columns[1:][f_mask]

    knn.fit(x_train_std[:, f_mask], y_train)
    print('훈련 정확도:', knn.score(x_train_std[:, f_mask], y_train))
    print('테스트 정확도:', knn.score(x_test_std[:, f_mask], y_test))


if __name__ == '__main__':
    test_sequential_feature_selector()

reference

  • 서적 '머신러닝 교과서 with 파이썬, 사이킷런, 텐서플로 개정 3판'

0개의 댓글