#!/usr/bin/env python3
univariate analysis(단변량 분석)
0.살펴보기
univariate analysis단변량 통계에서는
1. 개개의 특성과 target 사이에 중요한 통계적 관계가 있는지를 계산
2. 깊게 관련되어 있다고 판단되는 특성을 선택
분산분석 : 데이터를 클래스별로 나누어 평균을 비교하는 방법
분산분석으로 계산한 어떤 특성의 F-통계량이 높으면 그 특성은 클래스별 평균이 서로 다르다는 뜻
분류에서는 ANOVA, analysis of variance분산분석
사용하는 분포는 F-distribution
0. 기본적인 형태는 group(1) / group(2), 큰 값을 분자로 사용하여 최솟값을 1이 되게함
1. H0 = 클래스들의 평균과 분산이 같다
2. H0상태에서의 F-distribution 그래프를 그림
3. F-통계량이 1(좌측)에 가까운 수가 나올수록 두 집단은 비슷한 평균과 분산을 갖음
4. F-통계량이 1에 가까울수록 p-value의 값은 커짐 ==> target에 미치는 영향이 적다고 판단
5. p-value는 pvalues_에 저장됨
6. scikit-learn의 SelectBest, SelectPercentile에서 특성을 선택하는 기준은 F-통계값
7. F-통계값은 scores_에 저장됨
이 방법의 핵심 요소는 univariate, 즉 각 특성이 독립적으로 평가됨
==> 따라서 다른 특성과 깊게 연관된 특성은 선택되지 않을 것으로 예상 가능
이 방법의 특징은
1. 계산이 매우 빠르고 평가를 위해 모델을 만들 필요가 없음
2. 특성을 선택한 후 적용하려는 모델에 상관없이 사용 가능
scikit-learn에서 univariate로 특성을 선택하려면
1. 분류에는 f_classif(default)를, 회귀에서는 f_regression을 선택하여 테스트
2. 계산한 p-value에 기초하여 특성을 제외하는 방식을 선택.
이런 방식들은 매우 높은 p-value를 가진(target값과 연관성이 적은) 특성을 제외할 수 있도록 critical value를 조정하는 parameter를 사용
critical value를 계산하는 방법중 하나인 SelectKBest는 고정된 k개의 특성을 선택하고 SelectPercentile은 지정된 비율만큼 특성을 선택
1. cancer data에서 univariate analysis(단변량 분석)하기
### library import
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import SelectPercentile
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
### matplotlib 한글출력, 축- 설정
matplotlib.rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
### dataload
cancer = load_breast_cancer()
### preprocessing
rng = np.random.RandomState(seed=0) # random seed
noise = rng.normal(size=(cancer.data.shape[0], 50)) # normal분포에서 cancer.data.shape[0]x50의 데이터추출
cancer_data_noise = np.hstack([cancer.data, noise]) # data 병합
print('cancer_data_noise.shape \n{}'.format(cancer_data_noise.shape)) # (569, 80)
### data 분할
x_train, x_test, y_train, y_test = \
train_test_split(cancer_data_noise, cancer.target,
test_size=0.5, random_state=0)
### preprocessing 메소드 호출 및 적용
select = SelectPercentile(percentile=50).fit(x_train, y_train) # percentile: 50%만 선택
x_train_select = select.transform(x_train) # 적용
x_test_selected = select.transform(x_test)
print('x_train.shape \n{}'.format(x_train.shape))
print('x_train_select.shape \n{}'.format(x_train_select.shape))
합친 데이터와 선택된 데이터의 형태
>> 특성의 갯수가 80에서 40개로 줄음
2. 어떤 특성이 선택되었는지 확인
print('idx \n{}'.format(idx))
논리값으로 만들어진 idx
plt.matshow(idx.reshape(1, -1), cmap='gray_r')
plt.yticks([]) # 축눈금없애기
plt.xlabel('feature number')
plt.show()
SelectPercentile이 선택한 특성
>> 마스킹된 그래프에서 볼 수 있듯이 선택된 특성은 대부분 원본특성이며, 노이즈 특성은 거의 제거됨을 볼 수 있음
3. 전체 특성을 이용했을 때와 선택된 특성만 사용했을 때 로지스틱 회귀 성능 비교
Logistic Regression 링크 참조
### library import
from sklearn.linear_model import LogisticRegression
### model 호출
lr = LogisticRegression()
### 전체특성을 사용했을 때 정확도
lr.fit(x_train, y_train)
print('전체 특성을 사용한 점수: \n{:.3f}'.format(lr.score(x_test, y_test))) # 0.937
### 일부특성을 사용했을 때 정확도
lr.fit(x_train_select, y_train)
print('선택된 특성을 사용한 점수 \n{:.3f}'.format(lr.score(x_test_selected, y_test))) # 0.951
>> 이 경우에는 일부 원본 특성이 없더라도 노이즈 특성을 제거한 쪽의 성능이 더 높음
이 예는 인위적으로 간단하게 만들었고 실제 데이터에서는 엇갈리는 경우도 많음
너무 많은 특성 때문에 모델을 만들기가 현실적으로 어려울 때 univariate를 사용하거나,
많은 특성들이 확실히 도움이 안된다고 생각할 때 사용
- get_support(): 선택된 특성을 논리값으로 표시 [본문으로]
'데이터 표현과 특성 > feature auto-selection' 카테고리의 다른 글
feature selection based model(모델 기반 특성 선택) (0) | 2018.04.01 |
---|---|
feature auto-selection --intro (0) | 2018.03.30 |