Pandas의 큰 상관 행렬에서 가장 높은 상관 쌍을 나열 하시겠습니까?


104

Pandas와의 상관 관계 행렬에서 상위 상관 관계를 어떻게 찾습니까? R이 작업을 수행하는 방법에 대한 많은 답변 (있다 정렬 된 목록으로, 아니 큰 행렬로 표시 상관 관계 또는 효율적인 방법으로 높은 상관 관계를 얻을 수 파이썬 또는 R에서 대규모 데이터 세트에서 쌍 ,하지만 내가 그것을 수행하는 방법 궁금는) 판다 랑? 제 경우에는 행렬이 4460x4460이므로 시각적으로 할 수 없습니다.

답변:


100

을 사용 DataFrame.values하여 데이터의 numpy 배열 argsort()을 얻은 다음 가장 상관 관계가있는 쌍을 가져 오는 것과 같은 NumPy 함수를 사용할 수 있습니다.

하지만 pandas에서이 작업을 수행 unstack하려면 DataFrame을 정렬 할 수 있습니다 .

import pandas as pd
import numpy as np

shape = (50, 4460)

data = np.random.normal(size=shape)

data[:, 1000] += data[:, 2000]

df = pd.DataFrame(data)

c = df.corr().abs()

s = c.unstack()
so = s.sort_values(kind="quicksort")

print so[-4470:-4460]

출력은 다음과 같습니다.

2192  1522    0.636198
1522  2192    0.636198
3677  2027    0.641817
2027  3677    0.641817
242   130     0.646760
130   242     0.646760
1171  2733    0.670048
2733  1171    0.670048
1000  2000    0.742340
2000  1000    0.742340
dtype: float64

11
Pandas v 0.17.0 이상에서는 order 대신 sort_values를 사용해야합니다. 주문 방법을 사용하려고하면 오류가 발생합니다.
Friendm1

또한 상관 관계가 높은 쌍을 얻으려면 sort_values(ascending=False).
sotmot

49

@HYRY의 대답은 완벽합니다. 중복 및 자체 상관 관계와 적절한 정렬을 피하기 위해 논리를 조금 더 추가하여 그 대답을 구축하십시오.

import pandas as pd
d = {'x1': [1, 4, 4, 5, 6], 
     'x2': [0, 0, 8, 2, 4], 
     'x3': [2, 8, 8, 10, 12], 
     'x4': [-1, -4, -4, -4, -5]}
df = pd.DataFrame(data = d)
print("Data Frame")
print(df)
print()

print("Correlation Matrix")
print(df.corr())
print()

def get_redundant_pairs(df):
    '''Get diagonal and lower triangular pairs of correlation matrix'''
    pairs_to_drop = set()
    cols = df.columns
    for i in range(0, df.shape[1]):
        for j in range(0, i+1):
            pairs_to_drop.add((cols[i], cols[j]))
    return pairs_to_drop

def get_top_abs_correlations(df, n=5):
    au_corr = df.corr().abs().unstack()
    labels_to_drop = get_redundant_pairs(df)
    au_corr = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False)
    return au_corr[0:n]

print("Top Absolute Correlations")
print(get_top_abs_correlations(df, 3))

그러면 다음과 같은 출력이 제공됩니다.

Data Frame
   x1  x2  x3  x4
0   1   0   2  -1
1   4   0   8  -4
2   4   8   8  -4
3   5   2  10  -4
4   6   4  12  -5

Correlation Matrix
          x1        x2        x3        x4
x1  1.000000  0.399298  1.000000 -0.969248
x2  0.399298  1.000000  0.399298 -0.472866
x3  1.000000  0.399298  1.000000 -0.969248
x4 -0.969248 -0.472866 -0.969248  1.000000

Top Absolute Correlations
x1  x3    1.000000
x3  x4    0.969248
x1  x4    0.969248
dtype: float64

3
get_redundant_pairs (df) 대신 "cor.loc [:, :] = np.tril (cor.values, k = -1)"을 사용한 다음 "cor = cor [cor> 0]"을 사용할 수 있습니다.
Sarah

2
나는 라인에 대한 오류를 받고 있어요 au_corr = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False):# -- partial selection or non-unique index
stallingOne

43

중복 변수 쌍이없는 몇 줄 솔루션 :

corr_matrix = df.corr().abs()

#the matrix is symmetric so we need to extract upper triangle matrix without diagonal (k = 1)

sol = (corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))
                  .stack()
                  .sort_values(ascending=False))

#first element of sol series is the pair with the biggest correlation

그런 다음 변수 쌍 (pandas.Series 다중 인덱스)의 이름과 해당 값을 다음과 같이 반복 할 수 있습니다.

for index, value in sol.items():
  # do some staff

3
코드에서 사용할 수있는 경우 from을 os마스킹하기 때문에 변수 이름 으로 사용하는 것은 좋지 않을 수 있습니다osimport os
shadi

제안 해 주셔서 감사합니다.이 부적절한 변수 이름을 변경했습니다.
MiFi

1
2018 년 부터 순서
Serafins

1
'솔'을 반복하는 방법 ??
sirjay

2
@sirjay 위의 질문에 대한 답변을 배치했습니다
MiFi

14

@HYRY와 @arun의 답변의 일부 기능을 결합하면 df다음을 사용하여 데이터 프레임 에 대한 상위 상관 관계를 한 줄로 인쇄 할 수 있습니다 .

df.corr().unstack().sort_values().drop_duplicates()

참고 : 한 가지 단점은 하나의 변수 가 아닌 1.0 상관 관계가있는 경우 drop_duplicates()추가하면 제거 된다는 것입니다.


1
drop_duplicates동일한 상관 관계를 모두 삭제 하지 않겠습니까 ?
shadi

@shadi 예, 맞습니다. 그러나 동일하게 동일한 유일한 상관 관계는 1.0의 상관 관계 (즉, 자신과의 변수) 라고 가정합니다 . 두 개의 고유 한 변수 쌍 (예 : v1to v2v3to v4)에 대한 상관 관계 가 정확히 동일하지 않을 가능성이 있습니다.
Addison Klinke

확실히 내가 가장 좋아하는 단순함 그 자체. 내 사용에, 내가 먼저 높은 corrleations 필터링
제임스 Igoe

10

내림차순으로 상관 관계를 보려면 아래 코드를 사용하십시오.

# See the correlations in descending order

corr = df.corr() # df is the pandas dataframe
c1 = corr.abs().unstack()
c1.sort_values(ascending = False)

1
귀하의 둘째 행은 다음과 같습니다 (C1)가 core.abs을 () = 언 스택 ().
잭 한순간

(첫번째 줄)corr = df.corr()
vizyourdata

6

데이터를 대체하여이 간단한 코드에 따라 그래픽으로 수행 할 수 있습니다.

corr = df.corr()

kot = corr[corr>=.9]
plt.figure(figsize=(12,8))
sns.heatmap(kot, cmap="Greens")

여기에 이미지 설명 입력


3

나는 Addison Klinke의 게시물이 가장 단순하다는 점을 가장 좋아했지만 필터링 및 차트 작성에 Wojciech Moszczyńsk의 제안을 사용했지만 절대 값을 피하기 위해 필터를 확장 했으므로 큰 상관 행렬이 주어지면 필터링하고 차트 화 한 다음 평면화합니다.

생성, 필터링 및 차트 작성

dfCorr = df.corr()
filteredDf = dfCorr[((dfCorr >= .5) | (dfCorr <= -.5)) & (dfCorr !=1.000)]
plt.figure(figsize=(30,10))
sn.heatmap(filteredDf, annot=True, cmap="Reds")
plt.show()

필터링 된 히트 맵

함수

결국, 상관 행렬을 만들고 필터링 한 다음 평탄화하는 작은 함수를 만들었습니다. 아이디어로 쉽게 확장 할 수 있습니다 (예 : 비대칭 상한 및 하한 등).

def corrFilter(x: pd.DataFrame, bound: float):
    xCorr = x.corr()
    xFiltered = xCorr[((xCorr >= bound) | (xCorr <= -bound)) & (xCorr !=1.000)]
    xFlattened = xFiltered.unstack().sort_values().drop_duplicates()
    return xFlattened

corrFilter(df, .7)

여기에 이미지 설명 입력


마지막 하나를 제거하는 방법? HofstederPowerDx와 Hofsteder PowerDx는 동일한 변수입니다. 맞죠?
Luc

함수에서 .dropna ()를 사용할 수 있습니다. 방금 VS Code에서 시도했고 작동합니다. 첫 번째 방정식을 사용하여 상관 행렬을 만들고 필터링하고 다른 방정식을 사용하여 평평하게 만듭니다. 이를 사용하는 경우 .dropduplicates () 제거를 실험하여 .dropna () 및 dropduplicates ()가 모두 필요한지 확인할 수 있습니다.
James Igoe

이 코드와 기타 개선 사항이 포함 된 노트북은 다음과 같습니다. github.com/JamesIgoe/GoogleFitAnalysis
James Igoe

2

여기에 좋은 답변이 많이 있습니다. 내가 찾은 가장 쉬운 방법은 위의 답변 중 일부를 조합 한 것입니다.

corr = corr.where(np.triu(np.ones(corr.shape), k=1).astype(np.bool))
corr = corr.unstack().transpose()\
    .sort_values(by='column', ascending=False)\
    .dropna()

2

사용은 itertools.combinations팬더의 모든 고유의 상관 관계를 자신의 상관 행렬을 얻기 위해 .corr(), 목록의 목록을 생성하고 사용하기 위해서는 다시 DataFrame에 '.sort_values을'을 공급. ascending = True가장 낮은 상관 관계를 맨 위에 표시하도록 설정

corrankDataFrame은 .corr().

  def corrank(X: pandas.DataFrame):
        import itertools
        df = pd.DataFrame([[(i,j),X.corr().loc[i,j]] for i,j in list(itertools.combinations(X.corr(), 2))],columns=['pairs','corr'])    
        print(df.sort_values(by='corr',ascending=False))

  corrank(X) # prints a descending list of correlation pair (Max on top)

3
이 코드 스 니펫이 해결책이 될 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 도움이됩니다. 미래에 독자를 위해 질문에 답하고 있으며 해당 사용자는 코드 제안 이유를 모를 수 있습니다.
haindl

1

unstack기능 선택 단계의 일부로 상관 관계가 높은 일부 기능을 삭제하고 싶었 기 때문에이 문제를 지나치게 복잡하게 만들고 싶지 않았습니다 .

그래서 다음과 같은 단순화 된 솔루션으로 끝났습니다.

# map features to their absolute correlation values
corr = features.corr().abs()

# set equality (self correlation) as zero
corr[corr == 1] = 0

# of each feature, find the max correlation
# and sort the resulting array in ascending order
corr_cols = corr.max().sort_values(ascending=False)

# display the highly correlated features
display(corr_cols[corr_cols > 0.8])

이 경우 상관 된 기능을 삭제하려면 필터링 된 corr_cols배열을 통해 매핑 하고 홀수 인덱스 (또는 짝수 인덱스) 항목을 제거 할 수 있습니다.


이것은 단지 하나의 인덱스 (기능)를 제공하며 feature1 feature2 0.98과 같은 것은 아닙니다. 변경 라인 corr_cols = corr.max().sort_values(ascending=False)에이 corr_cols = corr.unstack()
aunsid

OP는 상관 관계 모양을 지정하지 않았습니다. 앞서 언급했듯이 스택을 풀고 싶지 않았기 때문에 다른 접근 방식을 사용했습니다. 각 상관 관계 쌍은 내가 제안한 코드에서 2 개의 행으로 표시됩니다. 그러나 유용한 의견에 감사드립니다!
falsarella

0

여기에서 몇 가지 솔루션을 시도했지만 실제로 내 자신의 솔루션을 생각해 냈습니다. 이것이 다음 번에 유용 할 수 있기를 바랍니다. 그래서 여기에서 공유합니다.

def sort_correlation_matrix(correlation_matrix):
    cor = correlation_matrix.abs()
    top_col = cor[cor.columns[0]][1:]
    top_col = top_col.sort_values(ascending=False)
    ordered_columns = [cor.columns[0]] + top_col.index.tolist()
    return correlation_matrix[ordered_columns].reindex(ordered_columns)

0

@MiFi의 개선 된 코드입니다. 이것은 abs의 순서이지만 음수 값을 제외하지 않습니다.

   def top_correlation (df,n):
    corr_matrix = df.corr()
    correlation = (corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))
                 .stack()
                 .sort_values(ascending=False))
    correlation = pd.DataFrame(correlation).reset_index()
    correlation.columns=["Variable_1","Variable_2","Correlacion"]
    correlation = correlation.reindex(correlation.Correlacion.abs().sort_values(ascending=False).index).reset_index().drop(["index"],axis=1)
    return correlation.head(n)

top_correlation(ANYDATA,10)

0

다음 함수가 트릭을 수행해야합니다. 이 구현

  • 자기 상관 제거
  • 중복 제거
  • 상관 관계가 가장 높은 상위 N 개 기능을 선택할 수 있습니다.

또한 자체 상관 관계와 중복 관계를 모두 유지할 수 있도록 구성 할 수도 있습니다. 원하는만큼 많은 기능 쌍을보고 할 수도 있습니다.


def get_feature_correlation(df, top_n=None, corr_method='spearman',
                            remove_duplicates=True, remove_self_correlations=True):
    """
    Compute the feature correlation and sort feature pairs based on their correlation

    :param df: The dataframe with the predictor variables
    :type df: pandas.core.frame.DataFrame
    :param top_n: Top N feature pairs to be reported (if None, all of the pairs will be returned)
    :param corr_method: Correlation compuation method
    :type corr_method: str
    :param remove_duplicates: Indicates whether duplicate features must be removed
    :type remove_duplicates: bool
    :param remove_self_correlations: Indicates whether self correlations will be removed
    :type remove_self_correlations: bool

    :return: pandas.core.frame.DataFrame
    """
    corr_matrix_abs = df.corr(method=corr_method).abs()
    corr_matrix_abs_us = corr_matrix_abs.unstack()
    sorted_correlated_features = corr_matrix_abs_us \
        .sort_values(kind="quicksort", ascending=False) \
        .reset_index()

    # Remove comparisons of the same feature
    if remove_self_correlations:
        sorted_correlated_features = sorted_correlated_features[
            (sorted_correlated_features.level_0 != sorted_correlated_features.level_1)
        ]

    # Remove duplicates
    if remove_duplicates:
        sorted_correlated_features = sorted_correlated_features.iloc[:-2:2]

    # Create meaningful names for the columns
    sorted_correlated_features.columns = ['Feature 1', 'Feature 2', 'Correlation (abs)']

    if top_n:
        return sorted_correlated_features[:top_n]

    return sorted_correlated_features

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.