パンダとの相関行列で上位の相関をどのように見つけますか?Rでこれを行う方法については多くの答えがあります(大きな行列としてではなく、順序付けられたリストとして相関を表示するか、PythonまたはRの大きなデータセットから相関の高いペアを取得する効率的な方法)が、どのように行うのか疑問に思っていますパンダと?私の場合、マトリックスは4460x4460なので、視覚的に行うことはできません。
パンダとの相関行列で上位の相関をどのように見つけますか?Rでこれを行う方法については多くの答えがあります(大きな行列としてではなく、順序付けられたリストとして相関を表示するか、PythonまたはRの大きなデータセットから相関の高いペアを取得する効率的な方法)が、どのように行うのか疑問に思っていますパンダと?私の場合、マトリックスは4460x4460なので、視覚的に行うことはできません。
回答:
を使用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
@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
au_corr = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False)
:# -- partial selection or non-unique index
変数の冗長なペアがない数行のソリューション:
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
os
はos
fromをマスクするため、変数名として使用するのはおそらく悪い考えimport os
です
@HYRYと@arunの回答のいくつかの機能を組み合わせて、次df
を使用してデータフレームの上位の相関を1行で出力できます。
df.corr().unstack().sort_values().drop_duplicates()
注:1つの欠点は、1.0の相関関係がない場合です。それ自体に対して1つの変数、drop_duplicates()
追加によってそれらが削除されることです。
drop_duplicates
等しいすべての相関関係を削除しませんか?
v1
tov2
とv3
to v4
)の相関が
以下のコードを使用して、相関関係を降順で表示します。
# See the correlations in descending order
corr = df.corr() # df is the pandas dataframe
c1 = corr.abs().unstack()
c1.sort_values(ascending = False)
corr = df.corr()
を使用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)
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
配列をマップして、奇数インデックス(または偶数インデックス)の配列を削除できます。
corr_cols = corr.max().sort_values(ascending=False)
へ corr_cols = corr.unstack()
私はここでいくつかの解決策を試していましたが、実際に自分の解決策を思いつきました。これが次のものに役立つことを願っていますので、ここで共有します:
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)
これは@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)
次の関数でうまくいくはずです。この実装
また、自己相関と重複の両方を保持できるように構成することもできます。必要な数の機能ペアをレポートすることもできます。
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
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)