파이썬에서 공선 변수를 체계적으로 제거하는 방법은 무엇입니까? [닫은]


18

지금까지 상관 테이블을보고 특정 임계 값을 초과하는 변수를 제거하여 데이터 준비 프로세스의 일부로 공선 변수를 제거했습니다. 이 작업을 수행하는 데 더 허용되는 방법이 있습니까? 또한 한 번에 두 변수 사이의 상관 관계 만 보는 것이 이상적이지 않다는 것을 알고 있습니다. VIF와 같은 측정은 여러 변수의 잠재적 상관 관계를 고려합니다. 다중 공선 성을 나타내지 않는 변수 조합을 체계적으로 선택하는 방법은 무엇입니까?

팬더 데이터 프레임 내에 데이터가 있으며 sklearn의 모델을 사용하고 있습니다.


3
부분 최소 제곱 법 회귀 또는 주성분 회귀 분석을 고려할 수 있습니다. 이 중 하나가 지원 될 수 있습니다.
spdrnl

내가 참조. 따라서 올바르게 이해하면 PCA를 실행하면 독립적 인 주 구성 요소 집합을 얻을 수 있는데, 주 ​​구성 요소 각각이 다른 구성 요소와 동일 선상에 있지 않기 때문에 모델의 공변량으로 사용할 수 있습니까?
orange1

2
바로 그거죠. 일부 구성 요소는 관련이 없을 수 있습니다. 변수를 삭제하는 것보다 쉽습니다.
spdrnl 2016 년

흠, 내 의도는 주로 예측 목적보다는 설명을 위해 모델을 실행하는 것입니다. 주성분을 공변량으로 사용한 모델을 해석하는 방법은 무엇입니까?
orange1

1
이 경우 구성 요소를 해석하는 것이 다소 어두운 기술이므로 도움이되지 않습니다.
spdrnl

답변:


13

감사합니다 SpanishBoy-좋은 코드입니다. @ilanman : VIF 값을 확인한 다음 VIF가 5보다 큰 변수를 삭제합니다. "성능"이란 런타임을 의미한다고 생각합니다. 위의 코드는 약 300 개의 변수, 5000 개의 행에서 실행하는 데 약 3 시간이 걸렸습니다.

그건 그렇고, 여분의 루프를 제거하기 위해 수정했습니다. 또한, 나는 그것을 좀 더 깨끗하게 만들고 감소 된 변수로 데이터 프레임을 반환합니다. 이 버전은 내 실행 시간을 절반으로 줄였습니다! 내 코드는 아래에 있습니다-도움이되기를 바랍니다.

from statsmodels.stats.outliers_influence import variance_inflation_factor    

def calculate_vif_(X, thresh=5.0):
    variables = list(range(X.shape[1]))
    dropped = True
    while dropped:
        dropped = False
        vif = [variance_inflation_factor(X.iloc[:, variables].values, ix)
               for ix in range(X.iloc[:, variables].shape[1])]

        maxloc = vif.index(max(vif))
        if max(vif) > thresh:
            print('dropping \'' + X.iloc[:, variables].columns[maxloc] +
                  '\' at index: ' + str(maxloc))
            del variables[maxloc]
            dropped = True

    print('Remaining variables:')
    print(X.columns[variables])
    return X.iloc[:, variables]

감사합니다. 두 기능의 출력을 비교 했습니까? VIF에 대한 R 함수 (패키지 usdm방법 vifstep)를 보았고 런타임이 정말 멋졌습니다. 앞에서 말했듯이 위의 변형과 절반 (최적화)은 R과 비교할 때 너무 느립니다. 다른 아이디어는 아직 최적화하는 방법은 무엇입니까?
SpanishBoy

1
이 접근법에 대한 질문이 있습니다. A, B 및 C 기능이 있다고 가정 해 봅시다. A는 C와 상관 관계가 있습니다. 피처를 반복하면 A와 C의 VIF> 5가 적용되므로 삭제됩니다. 실제로 피처를 삭제할 때마다 VIF를 다시 계산해서는 안됩니다. 이 예에서는 A와 C를 모두 드롭하지만 A를 삭제 한 후 VIF (C)를 계산하면> 5가되지 않습니다.
Titus Pullo

3

아래 코드를 사용해보십시오.

from statsmodels.stats.outliers_influence import variance_inflation_factor

def calculate_vif_(X):

    '''X - pandas dataframe'''
    thresh = 5.0
    variables = range(X.shape[1])

    for i in np.arange(0, len(variables)):
        vif = [variance_inflation_factor(X[variables].values, ix) for ix in range(X[variables].shape[1])]
        print(vif)
        maxloc = vif.index(max(vif))
        if max(vif) > thresh:
            print('dropping \'' + X[variables].columns[maxloc] + '\' at index: ' + str(maxloc))
            del variables[maxloc]

    print('Remaining variables:')
    print(X.columns[variables])
    return X

작동하지만 그 접근 방식의 성능이 마음에 들지 않습니다.


이 접근 방식의 기능에 대해 조금 더 언급하고 싶습니까? 그리고 왜 성능이 마음에 들지 않습니까?
ilanman

2

SpanishBoy의 답변을 시도하고 데이터 프레임에 대해 실행할 때 서비스 오류가 발견되었습니다. 다음은 디버깅 된 솔루션입니다.

from statsmodels.stats.outliers_influence import variance_inflation_factor    

def calculate_vif_(X, thresh=100):
cols = X.columns
variables = np.arange(X.shape[1])
dropped=True
while dropped:
    dropped=False
    c = X[cols[variables]].values
    vif = [variance_inflation_factor(c, ix) for ix in np.arange(c.shape[1])]

    maxloc = vif.index(max(vif))
    if max(vif) > thresh:
        print('dropping \'' + X[cols[variables]].columns[maxloc] + '\' at index: ' + str(maxloc))
        variables = np.delete(variables, maxloc)
        dropped=True

print('Remaining variables:')
print(X.columns[variables])
return X[cols[variables]]

또한 성능에는 문제가 없었지만 광범위하게 테스트하지는 않았습니다.


이것은 좋고 나에게 효과적입니다. 예외적으로 불길한 경고를 반환합니다.RuntimeWarning: divide by zero encountered in double_scalars
user2205916
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.