Jak znaleźć najlepsze korelacje w macierzy korelacji z pandami? Jest wiele odpowiedzi, jak to zrobić za pomocą R ( Pokaż korelacje jako uporządkowaną listę, a nie jako dużą macierz lub Wydajny sposób na uzyskanie silnie skorelowanych par z dużego zestawu danych w Pythonie lub R ), ale zastanawiam się, jak to zrobić z pandami? W moim przypadku matryca ma wymiary 4460x4460, więc nie mogę tego zrobić wizualnie.
python
pandas
correlation
Kyle Brandt
źródło
źródło
sort_values(ascending=False)
.Odpowiedź @ HYRY'ego jest doskonała. Po prostu opierając się na tej odpowiedzi, dodając nieco więcej logiki, aby uniknąć duplikatów i korelacji własnych oraz właściwego sortowania:
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))
To daje następujący wynik:
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
źródło
au_corr = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False)
:# -- partial selection or non-unique index
Rozwiązanie kilku linii bez zbędnych par zmiennych:
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
Następnie możesz iterować po nazwach par zmiennych (czyli pandas.Series multi-indexes) i ich wartościach w następujący sposób:
for index, value in sol.items(): # do some staff
źródło
os
jako nazwy zmiennej, ponieważ maskujeos
przed,import os
jeśli jest dostępny w kodzieŁącząc niektóre cechy odpowiedzi @HYRY i @ arun, możesz wydrukować najważniejsze korelacje dla ramki danych
df
w jednej linii, używając:Uwaga: jedyną wadą jest to, że jeśli masz korelacje 1.0, które nie są dla siebie jedną zmienną,
drop_duplicates()
dodanie spowoduje ich usunięcieźródło
drop_duplicates
porzuciłby wszystkich równych korelacji?v1
Dov2
iv3
dov4
) nie byłaby dokładnie taka samaUżyj poniższego kodu, aby wyświetlić korelacje w porządku malejącym.
# See the correlations in descending order corr = df.corr() # df is the pandas dataframe c1 = corr.abs().unstack() c1.sort_values(ascending = False)
źródło
corr = df.corr()
Możesz to zrobić graficznie zgodnie z tym prostym kodem, zastępując swoje dane.
corr = df.corr() kot = corr[corr>=.9] plt.figure(figsize=(12,8)) sns.heatmap(kot, cmap="Greens")
źródło
Najbardziej podobał mi się post Addisona Klinke, jako najprostszy, ale wykorzystałem sugestię Wojciecha Moszczyńska do filtrowania i tworzenia wykresów, ale rozszerzyłem filtr, aby uniknąć wartości bezwzględnych, więc mając dużą macierz korelacji, przefiltruj, wykreśl, a następnie spłaszcz:
Utworzono, przefiltrowano i przedstawiono na wykresie
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()
Funkcjonować
Na koniec stworzyłem małą funkcję do tworzenia macierzy korelacji, przefiltrowania jej, a następnie spłaszczenia. Jako pomysł można go łatwo rozszerzyć, np. Asymetryczne górne i dolne granice itp.
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)
źródło
Tutaj jest dużo dobrych odpowiedzi. Najłatwiejszy sposób, jaki znalazłem, to połączenie niektórych z powyższych odpowiedzi.
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()
źródło
Użyj,
itertools.combinations
aby uzyskać wszystkie unikalne korelacje z własnej macierzy korelacji pandy.corr()
, wygenerować listę list i przesłać ją z powrotem do ramki DataFrame w celu użycia „.sort_values”. Ustaw,ascending = True
aby wyświetlać najniższe korelacje na górzecorrank
przyjmuje jako argument DataFrame, ponieważ wymaga.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)
źródło
Nie chciałem zbytnio
unstack
komplikować tego problemu, ponieważ chciałem po prostu usunąć niektóre wysoce skorelowane funkcje w ramach fazy wyboru funkcji.W rezultacie otrzymałem następujące uproszczone rozwiązanie:
# 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])
W takim przypadku, jeśli chcesz usunąć skorelowane funkcje, możesz zmapować filtrowaną
corr_cols
tablicę i usunąć nieparzyste (lub parzyste) elementy.źródło
corr_cols = corr.max().sort_values(ascending=False)
nacorr_cols = corr.unstack()
Próbowałem tutaj niektórych rozwiązań, ale potem wymyśliłem własne. Mam nadzieję, że przyda się to przy następnym, więc udostępniam to tutaj:
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)
źródło
To jest ulepszony kod z @MiFi. To jedno zamówienie w abs, ale nie wykluczając wartości ujemnych.
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)
źródło
Poniższa funkcja powinna załatwić sprawę. Ta realizacja
i jest również konfigurowalny, dzięki czemu można zachować zarówno własne korelacje, jak i duplikaty. Możesz również zgłosić dowolną liczbę par funkcji.
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
źródło