Список наивысших корреляционных пар из большой корреляционной матрицы в Pandas?

Как вы находите верхние корреляции в корреляционной матрице с Pandas? Существует много ответов о том, как это сделать с помощью R (Показывать корреляции как упорядоченный список, а не как большую матрицу или Эффективный способ получить сильно коррелированные пары из большого набора данных в Python или R), но мне интересно, как это сделать с помощью Pandas? В моем случае матрица 4460x4460, поэтому не может визуально выглядеть.

Ответы

Ответ 1

Вы можете использовать DataFrame.values чтобы получить массив данных, а затем использовать функции NumPy, такие как argsort() чтобы получить наиболее коррелированные пары.

Но если вы хотите сделать это в unstack, вы можете unstack и order 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

Ответ 2

@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

Решение нескольких строк без лишних пар переменных:

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 bigest correlation

Ответ 4

Комбинируя некоторые особенности ответов @HYRY и @arun, вы можете вывести верхние корреляции для фрейма данных df в одну строку, используя:

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

Примечание: один недостаток - если у вас есть корреляции 1.0, которые не являются одной переменной для себя, drop_duplicates() удалит их

Ответ 5

Используйте itertools.combinations, чтобы получить все уникальные корреляции из pandas собственной корреляционной матрицы .corr(), сгенерировать список списков и вернуть его в DataFrame, чтобы использовать ".sort_values". Установите ascending = True, чтобы отображать самые низкие корреляции сверху

corrank принимает параметр DataFrame в качестве аргумента, потому что ему требуется .corr().

  def corrank(X):
        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)

Ответ 6

Используйте код ниже, чтобы просмотреть корреляции в порядке убывания.

# See the correlations in descending order

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

Ответ 7

Здесь много хороших ответов. Самым простым способом, который я нашел, была комбинация некоторых из ответов выше.

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()

Ответ 8

Я не хотел 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 и удалить нечетные (или даже индексированные).

Ответ 9

Я пробовал некоторые решения здесь, но затем я действительно нашел свое собственное. Я надеюсь, что это может быть полезно для следующего, поэтому я поделюсь этим здесь:

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)