Pandalar'daki Büyük Korelasyon Matrisinden En Yüksek Korelasyon Çiftlerini Listeliyor musunuz?


97

Pandalar ile bir korelasyon matrisindeki en yüksek korelasyonları nasıl bulursunuz? Bunun R ile nasıl yapılacağına dair pek çok cevap var ( Korelasyonları sıralı bir liste olarak göster, büyük bir matris olarak göster veya Python veya R'deki büyük veri kümesinden yüksek düzeyde ilişkili çiftler elde etmenin verimli yolu ), ancak bunu nasıl yapacağımı merak ediyorum. pandalarla? Benim durumumda matris 4460x4460, bu yüzden görsel olarak yapamıyorum.

Yanıtlar:


93

DataFrame.valuesVerilerin uyuşmuş bir dizisini elde etmek için kullanabilir ve ardından argsort()en ilişkili çiftleri elde etmek gibi NumPy işlevlerini kullanabilirsiniz .

Ancak bunu pandalarda yapmak istiyorsanız unstack, DataFrame'i sıralayabilir ve sıralayabilirsiniz:

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]

İşte çıktı:

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 ve üzeri sürümlerde, sıralama yerine sort_values ​​kullanmalısınız. Sipariş yöntemini kullanmayı denerseniz bir hata alırsınız.
Friendm 1

46

@ HYRY'nin cevabı mükemmel. Yinelenen ve kendi kendine korelasyonlardan ve uygun sıralamadan kaçınmak için biraz daha mantık ekleyerek bu yanıta dayanarak:

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

Bu, aşağıdaki çıktıyı verir:

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) yerine "cor.loc [:,:] = np.tril (cor.values, k = -1)" ve ardından "cor = cor [cor> 0]" kullanabilirsiniz
Sarah

2
Şu satır için hata alıyorum au_corr = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False):# -- partial selection or non-unique index
stallingOne

41

Yedekli değişken çiftleri olmadan birkaç satır çözümü:

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

Ardından değişken çiftlerinin adlarını (pandalar, çoklu dizinler) ve aşağıdaki gibi değerlerini yineleyebilirsiniz:

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

3
Muhtemelen kötü bir fikir kullanmak osdeğişken adı olarak çünkü maskeleri osgelen import oseğer kodunda
vasiliy

Öneriniz için teşekkürler, bu uygunsuz değişken adını değiştirdim.
MiFi

1
2018 Kullanım itibariyle sort_values (artan = False) yerine sırayla
Serafins

1
'sol' nasıl döngü yapılır?
sirjay

2
@sirjay Yukarıdaki sorunuza bir cevap verdim
MiFi

13

@HYRY ve @ arun yanıtlarının bazı özelliklerini birleştirerek, dataframe için en iyi korelasyonları dftek bir satırda yazdırabilirsiniz :

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

Not: Tek dezavantajı, kendi başına bir değişken olmayan 1.0 korelasyonunuz varsa , drop_duplicates()ekleme onları kaldıracaktır


1
Olmaz drop_duplicateseşit tüm korelasyonlar damla?
shadi

@shadi evet, haklısın. Ancak, özdeş olarak eşit olacak tek bağıntının 1.0 bağıntıları (yani kendisiyle bir değişken) olduğunu varsayıyoruz . Şansı (yani değişken iki benzersiz çiftleri için korelasyon olduğunu vardır v1için v2ve v3için v4) tam olarak aynı olmaz
Addison Klinke

Kesinlikle benim favorim, basitliğin kendisi. kullanımımda, önce yüksek korelasyonlar için filtre uyguladım
James Igoe

9

Korelasyonları azalan sırada görüntülemek için aşağıdaki kodu kullanın.

# 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. satırınız şöyle olmalıdır: c1 = core.abs (). Unstack ()
Jack Fleeting

or first linecorr = df.corr()
vizyourdata

4

Verilerinizi değiştirerek bu basit koda göre grafiksel olarak yapabilirsiniz.

corr = df.corr()

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

görüntü açıklamasını buraya girin


2

Burada çok iyi cevaplar var. Bulduğum en kolay yol, yukarıdaki cevaplardan bazılarının bir kombinasyonuydu.

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

Kullanım itertools.combinationspandalar gelen tüm benzersiz korelasyonlar kendi korelasyon matrisi olsun .corr(), listelerin listesini oluşturmak ve kullanım amacıyla geri DataFrame içine' .sort_values' besleyin. ascending = TrueEn düşük korelasyonları en üstte görüntüleyecek şekilde ayarlayın

corrankDataFrame'i argüman olarak alır çünkü gerektirir .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
Bu kod pasajı çözüm olabilir, ancak bir açıklama da dahil olmak üzere yayınınızın kalitesini artırmaya gerçekten yardımcı olur. Gelecekte okuyucular için soruyu yanıtlayacağınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceklerini unutmayın.
haindl

1

unstackBu sorunu aşırı karmaşıklaştırmak istemedim , çünkü sadece bir özellik seçme aşamasının bir parçası olarak yüksek düzeyde ilişkili bazı özellikleri kaldırmak istedim.

Bu yüzden aşağıdaki basitleştirilmiş çözümü elde ettim:

# 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])

Bu durumda, ilişkili özellikleri kaldırmak istiyorsanız, filtrelenmiş corr_colsdiziyi eşleyebilir ve tek-indeksli (veya çift-indeksli) olanları kaldırabilirsiniz.


Bu sadece bir dizin (özellik) verir ve özellik1 özellik2 0.98 gibi bir şey değildir. Değişim hattı corr_cols = corr.max().sort_values(ascending=False)için corr_cols = corr.unstack()
aunsid

Eh, OP bir korelasyon şekli belirtmedi. Bahsettiğim gibi, yığınları ayırmak istemedim, bu yüzden sadece farklı bir yaklaşım getirdim. Her bir korelasyon çifti, önerilen kodumda 2 satırla temsil edilir. Ama faydalı yorum için teşekkürler!
falsarella

1

Addison Klinke'nin gönderisini en basit olduğu için en çok beğendim, ancak Wojciech Moszczyńsk'ın filtreleme ve çizelgeleme önerisini kullandım, ancak filtreyi mutlak değerlerden kaçınmak için genişlettim, bu nedenle büyük bir korelasyon matrisi verildiğinde, onu filtreleyin, grafiğini çizin ve ardından düzleştirin:

Oluşturuldu, Filtrelendi ve Grafik Oluşturuldu

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

filtrelenmiş ısı haritası

Fonksiyon

Sonunda, korelasyon matrisini oluşturmak, filtrelemek ve sonra düzleştirmek için küçük bir fonksiyon yarattım. Bir fikir olarak, kolaylıkla genişletilebilir, örneğin asimetrik üst ve alt sınırlar vb.

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)

görüntü açıklamasını buraya girin


sonuncusu nasıl kaldırılır? HofstederPowerDx ve Hofsteder PowerDx aynı değişkenlerdir, değil mi?
Luc

işlevlerde .dropna () kullanılabilir. Bunu VS Kodunda denedim ve işe yarıyor, korelasyon matrisini oluşturmak ve filtrelemek için ilk denklemi ve onu düzleştirmek için başka bir denklemi kullandığım yerde. Bunu kullanırsanız, hem .dropna () hem de dropduplicates () 'e ihtiyacınız olup olmadığını görmek için .dropduplicates ()' i kaldırmayı denemek isteyebilirsiniz.
James Igoe

Bu kodu ve diğer bazı iyileştirmeleri içeren bir not defteri burada: github.com/JamesIgoe/GoogleFitAnalysis
James Igoe

0

Burada bazı çözümleri deniyordum ama sonra aslında kendi çözümümü buldum. Umarım bu bir sonraki için yararlı olabilir, bu yüzden burada paylaşıyorum:

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

Bu, @MiFi'den geliştirilmiş bir koddur. Bu, mutlak bir emirdir, ancak negatif değerleri hariç tutmaz.

   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

Aşağıdaki işlev hile yapmalı. Bu uygulama

  • Kişisel korelasyonları ortadan kaldırır
  • Yinelenenleri kaldırır
  • En yüksek korelasyonlu ilk N özelliğin seçilmesini sağlar

ve aynı zamanda hem kendi korelasyonlarını hem de kopyaları koruyabilmeniz için yapılandırılabilir. Dilediğiniz kadar özellik çiftini de bildirebilirsiniz.


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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.