Как найти верхние корреляции в корреляционной матрице с Pandas? Есть много ответов о том, как это сделать с R ( Показать корреляции в виде упорядоченного списка, а не в виде большой матрицы или Эффективный способ получить высококоррелированные пары из большого набора данных в Python или R ), но мне интересно, как это сделать с пандами? В моем случае матрица 4460х4460, так что визуально сделать не могу.
python
pandas
correlation
Кайл Брандт
источник
источник
Ответ @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
от,import os
если оно доступно в кодеКомбинируя некоторые особенности ответов @HYRY и @arun, вы можете распечатать основные корреляции для фрейма данных
df
в одной строке, используя:Примечание: одним недостатком является то, что если у вас есть корреляции 1.0, которые не являются одной переменной для себя,
drop_duplicates()
добавление удалит ихисточник
drop_duplicates
все равные корреляции?v1
к»v2
и «v3
к»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()
Вы можете делать это графически в соответствии с этим простым кодом, подставляя свои данные.
corr = df.corr() kot = corr[corr>=.9] plt.figure(figsize=(12,8)) sns.heatmap(kot, cmap="Greens")
источник
Здесь много хороших ответов. Самый простой способ, который я нашел, - это комбинация некоторых из приведенных выше ответов.
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()
источник
Используется
itertools.combinations
для получения всех уникальных корреляций из собственной матрицы корреляции pandas.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)
источник
Я не хотел
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()
Мне больше всего понравился пост Аддисона Клинке, как самый простой, но я использовал предложение Войцеха Мощинска для фильтрации и построения диаграмм, но расширил фильтр, чтобы избежать абсолютных значений, поэтому, учитывая большую матрицу корреляции, отфильтруйте ее, нанесите на диаграмму и затем сгладьте:
Создано, отфильтровано и нанесено на диаграммы
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)
источник
Я пробовал некоторые из решений здесь, но потом я фактически придумал свое. Я надеюсь, что это может быть полезно для следующего, поэтому я поделюсь им здесь:
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. Это один порядок в абс, но не исключая отрицательные значения.
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
источник