パンダの大きな相関行列から最も高い相関ペアをリストしますか?


96

パンダとの相関行列で上位の相関をどのように見つけますか?Rでこれを行う方法については多くの答えがあります(大きな行列としてではなく、順序付けられたリストとして相関を表示する、PythonまたはRの大きなデータセットから相関の高いペアを取得する効率的な方法)が、どのように行うのか疑問に思っていますパンダと?私の場合、マトリックスは4460x4460なので、視覚的に行うことはできません。

回答:


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以降では、orderの代わりにsort_valuesを使用する必要があります。orderメソッドを使用しようとすると、エラーが発生します。
friendm1 2017

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]」を使用できます
Sarah

2
私はラインのためERRO取得しています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
コードで使用可能な場合ososfromをマスクするため、変数名として使用するのはおそらく悪い考えimport osです
shadi 2018

あなたの提案をありがとう、私はこの不適切な変数名を変更しました。
miFi 2018年

1
2018年現在順序の
セラフィン

1
'sol'をループする方法??
サージェイ

2
@sirjay上記の質問に答えました
MiFi

13

@HYRYと@arunの回答のいくつかの機能を組み合わせて、次dfを使用してデータフレームの上位の相関を1行で出力できます。

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

注:1つの欠点は、1.0の相関関係がない場合です。それ自体に対して1つの変数、drop_duplicates()追加によってそれらが削除されることです。


1
drop_duplicates等しいすべての相関関係を削除しませんか?
shadi 2018

@shadiはい、あなたは正しいです。ただし、同じように等しくなる唯一の相関は、1.0の相関(つまり、それ自体との変数)であると想定しています。変数の2つの一意のペア(つまり、v1tov2v3to v4)の相関が
完全に

間違いなく私のお気に入り、シンプルさ自体。私の使用法では、最初に高い相関関係をフィルタリングしました
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
2行目は次のようになります。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()、リストのリストを生成して、「。sort_values」を使用するためにDataFrameにフィードバックします。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 2017

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のようなものではなく、1つのインデックス(機能)を提供するだけです。変更ライン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からの改善コードです。これは腹筋で1つの順序ですが、負の値を除外するものではありません。

   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の投稿が最も単純であることが最も好きでしたが、フィルタリングとグラフ化にWojciechMoszczyń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とHofstederPowerDxは同じ変数ですよね?
Luc

関数で.dropna()を使用できます。VS Codeで試してみたところ、最初の方程式を使用して相関行列を作成およびフィルタリングし、別の方程式を使用してそれを平坦化して機能しました。これを使用する場合は、.dropduplicates()を削除して、.dropna()とdropduplicates()の両方が必要かどうかを確認することをお勧めします。
James Igoe

このコードとその他のいくつかの改善点を含むノートブックはこちらです:github.com/JamesIgoe/GoogleFitAnalysis
James Igoe
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.