[변수 선택] sklearn에 있는 mutual_info_classif , mutual_info_regression를 활용하여 변수 선택하기 (feature selection)

2020. 3. 9. 22:15분석 Python/Data Preprocessing

728x90

sklearn.feature_selection.mutual_info_classif

Mutual Information은 두 random variable들이 얼마나 mutual dependence 한 지를 measure 하는 방법을 의미한다.

 

Mutual information - Wikipedia

In probability theory and information theory, the mutual information (MI) of two random variables is a measure of the mutual dependence between the two variables. More specifically, it quantifies the "amount of information" (in units such as shannons, comm

en.wikipedia.org

즉 간단하게 $x , y$가 독립이면 $p(x,y) = p(x)p(y)$로 주어지고, 아니면 먼가 값이 나올 것이다. 
그래서 만약 independent 하면 0의 값을 얻게 되고, 상호 의존성이 크다면, 값이 나오게 될 것이다.
개인적으로 이 방법이 correlation을 측정하는 방법론보다 더 일반화된 방법이라서 더 선호한다.


Correlation은 $X,y$의 선형 관계(Pearson's correlation) 또는 monotonic relationship(Spearman's correlation)을 측정한다.
Mutual Information 같은 경우, 일반적이며 X를 관찰한 후 Y의 불확실성 감소를 측정한다. 이것은 결합 밀도 함수와 개별 밀도 함수의 곱 같이 KL dIvergence를 의미한다. 따라서 MI는 비 단조 관계나 더 복잡한 관계까지도 측정이 가능하다는 것이다.


$I(x,y) = KL(p(x,y)||(p(x)p(y))$

$I(x,y) = H(x)-H(x|y) = H(y)-H(y|x)$

 

sklearn.feature_selection.mutual_info_classif(X, y,
discrete_features='auto', n_neighbors=3, copy=True, random_state=None)
## return
mi : ndarray, shape (n_features,)
Estimated mutual information between each feature and the target.

이산형 타겟 변수에 대한 상호 정보를 추정하는 방법

discrete_features 가 auto 기능이 있지만, 정확하기 하기 위해서는 X값의 Columns 인덱스를 넣어주면 됨.

from sklearn.feature_selection import mutual_info_classif
discrete = [1,2,3] ## discrete column index
mu = mutual_info_classif(train[in_var] , 
                    train[target_name],
                    discrete_features= discrete)

Mutual information (MI) [1] between two random variables is a non-negative value, which measures the dependency between the variables. It is equal to zero if and only if two random variables are independent, and higher values mean higher dependency.
즉 변수들 사이에 의존성을 측정하게 된다. 만약 이 값이 0 이면 2개의 변수는 독립적이라고 할 수 있고 즉 도움이 안 된다는 의미, 만약 숫자가 크면 어떤 의존성을 뜬다는 것이다.
여기서 2개의 변수는 X값과 y값을 의미한다.

이 라이브러리를 사용하려면, 데이터의 결측이 존재해서는 안 되는 것도 잊지 말자.

그래서 특정 값이 나오는데 여기서 threshold를 지정하여, 변수 선택을 할 수 있다.

import matplotlib.pyplot as plt
fig, axes = plt.subplots( 1,1, figsize=(10,10))
pos = np.arange(len(mu))
plt.barh(pos , mu)
plt.yticks(pos , in_var)
threshold = 0.01
for idx , tick in enumerate( axes.yaxis.get_major_ticks()) :
    tick.label.set_fontsize(15)
    tick.label.set_rotation(15)
    if np.squeeze(mu)[idx] > threshold :
        tick.label.set_color("red")
        
plt.vlines(x=threshold , ymin =-1 , ymax= len(mu))
plt.show()

특정 threshold 0.01을 기준으로 넘고 있는
PAY_AMT1 , PAY_AMT2 , PAY_AMT3 , PAY_AMT4, PAY_AMT5, PAY_AMT6
PAY_0, PAY_2, PAY_3, PAY_4, PAY_5, PAY_6, LIMIT_BAL가 나오게 된다.

이렇게 target이 이산형 변수인 경우는 위와 같이 하면 되고, 만약 연속형 변수 같은 경우 아래 패키지를 사용하면 된다.

sklearn.feature_selection.mutual_info_regression(X, y,
discrete_features='auto', n_neighbors=3, copy=True, random_state=None)

https://scikit-learn.org/stable/modules/classes.html#module-sklearn.feature_selection

 

API Reference — scikit-learn 0.22.2 documentation

 

scikit-learn.org

 

 

728x90