列出大关联矩阵中的最高关联对?


96

您如何在与熊猫相关的矩阵中找到最相关的?关于如何使用R进行操作有很多答案(将相关性显示为有序列表,而不是大型矩阵从Python或R中从大型数据集中获取高度相关对的有效方法),但我想知道如何做到这一点大熊猫?在我的情况下,矩阵为4460x4460,因此无法从视觉上做到。

Answers:


92

您可以DataFrame.values用来获取数据的numpy数组,然后使用NumPy函数argsort()来获取最相关的对。

但是,如果要在熊猫中执行此操作,则可以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

10
对于Pandas v 0.17.0及更高版本,您应该使用sort_values而不是order。如果尝试使用order方法,则会出现错误。
Friendm1

46

@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]”
莎拉

2
我得到埃罗线路au_corr = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False)# -- partial selection or non-unique index
stallingOne

40

很少有没有冗余变量对的行解决方案:

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
os用作变量名可能不是一个好主意,因为如果代码中可用,它会掩盖osfromimport os
shadi 18'Aug

感谢您的建议,我更改了此不正确的var名称。
MiFi

1
截至2018年,使用sort_values(ascending = False)代替顺序
Serafins

1
如何循环“溶胶”?
sirjay,

2
@sirjay我在上面回答了您的问题
MiFi

13

结合@HYRY和@arun的某些功能,可以df使用以下命令在一行中打印数据帧的最高相关性:

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

注意:一个缺点是,如果您具有1.0的相关性,该相关性本身并不是一个变量,则drop_duplicates()添加会删除它们


1
不会drop_duplicates删除所有相等的相关性吗?
shadi

@shadi是的,您是正确的。但是,我们假设唯一相等的相关性是1.0的相关性(即变量本身)。可能是两个唯一变量对(即v1tov2v3to v4)的相关性可能不完全相同
Addison Klinke

绝对是我的最爱,简单性本身。在我的用法中,我首先过滤了高错误
James Igoe

9

使用下面的代码按降序查看相关性。

# 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()。unstack()
Jack Fleeting

或第一行corr = df.corr()
vizyourdata

4

您可以通过替换数据来根据此简单代码以图形方式进行操作。

corr = df.corr()

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

在此处输入图片说明


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为在顶部显示最低的相关性

corrank使用DataFrame作为参数,因为它需要.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的改进代码。该顺序为绝对值,但不排除负值。

   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


0

我最喜欢Addison Klinke的帖子,因为它是最简单的,但它最喜欢使用Wojciech Moszczyzysk的建议进行过滤和制图,但是扩展了该过滤器以避免绝对值,因此给定一个大的相关矩阵,对其进行过滤,制图然后对其进行展平:

创建,过滤和绘制图表

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是相同的变量,对吗?
吕克

可以在函数中使用.dropna()。我只是在VS Code中进行了尝试,并且它起作用了,在这里我使用第一个方程式创建和过滤相关矩阵,然后使用另一个方程式将其展平。如果使用它,则可能要尝试删除.dropduplicates()来查看是否同时需要.dropna()和dropduplicates()。
James Igoe

包含此代码和其他一些改进功能的笔记本在这里:github.com/JamesIgoe/GoogleFitAnalysis
James Igoe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.