Как вычислить корреляцию между всеми столбцами и удалить сильно коррелированные с помощью python или pandas

У меня есть огромный набор данных, и до моделирования машинного обучения всегда предлагается, чтобы сначала вы должны удалить сильно коррелированные дескрипторы (столбцы), как я могу вычислить корреляцию между столбцами и удалить столбец с пороговым значением, например, удалить все столбцы или дескрипторы, имеющие > 0,8 корреляции. также он должен сохранить заголовки в сокращении данных.

Пример набора данных

 GA      PN       PC     MBP      GR     AP   
0.033   6.652   6.681   0.194   0.874   3.177    
0.034   9.039   6.224   0.194   1.137   3.4      
0.035   10.936  10.304  1.015   0.911   4.9      
0.022   10.11   9.603   1.374   0.848   4.566    
0.035   2.963   17.156  0.599   0.823   9.406    
0.033   10.872  10.244  1.015   0.574   4.871     
0.035   21.694  22.389  1.015   0.859   9.259     
0.035   10.936  10.304  1.015   0.911   4.5       

Пожалуйста, помогите....

Ответ 1

Вот подход, который я использовал -

def correlation(dataset, threshold):
    col_corr = set() # Set of all the names of deleted columns
    corr_matrix = dataset.corr()
    for i in range(len(corr_matrix.columns)):
        for j in range(i):
            if (corr_matrix.iloc[i, j] >= threshold) and (corr_matrix.columns[j] not in col_corr):
                colname = corr_matrix.columns[i] # getting the name of column
                col_corr.add(colname)
                if colname in dataset.columns:
                    del dataset[colname] # deleting the column from the dataset

    print(dataset)

Надеюсь, это поможет!

Ответ 2

Метод здесь работал хорошо для меня, всего несколько строк кода: https://chrisalbon.com/machine_learning/feature_selection/drop_highly_correlated_features/

import numpy as np

# Create correlation matrix
corr_matrix = df.corr().abs()

# Select upper triangle of correlation matrix
upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))

# Find features with correlation greater than 0.95
to_drop = [column for column in upper.columns if any(upper[column] > 0.95)]

# Drop features 
df.drop(df.columns[to_drop], axis=1)

Ответ 3

Для данного фрейма данных df можно использовать следующее:

corr_matrix = df.corr().abs()
high_corr_var=np.where(corr_matrix>0.8)
high_corr_var=[(corr_matrix.columns[x],corr_matrix.columns[y]) for x,y in zip(*high_corr_var) if x!=y and x<y]

Ответ 4

Я позволил себе изменить ответ TomDobbs. Сообщенная ошибка в комментариях теперь удалена. Кроме того, новая функция также отфильтровывает отрицательную корреляцию.

def corr_df(x, corr_val):
    '''
    Obj: Drops features that are strongly correlated to other features.
          This lowers model complexity, and aids in generalizing the model.
    Inputs:
          df: features df (x)
          corr_val: Columns are dropped relative to the corr_val input (e.g. 0.8)
    Output: df that only includes uncorrelated features
    '''

    # Creates Correlation Matrix and Instantiates
    corr_matrix = x.corr()
    iters = range(len(corr_matrix.columns) - 1)
    drop_cols = []

    # Iterates through Correlation Matrix Table to find correlated columns
    for i in iters:
        for j in range(i):
            item = corr_matrix.iloc[j:(j+1), (i+1):(i+2)]
            col = item.columns
            row = item.index
            val = item.values
            if abs(val) >= corr_val:
                # Prints the correlated feature set and the corr val
                print(col.values[0], "|", row.values[0], "|", round(val[0][0], 2))
                drop_cols.append(i)

    drops = sorted(set(drop_cols))[::-1]

    # Drops the correlated columns
    for i in drops:
        col = x.iloc[:, (i+1):(i+2)].columns.values
        x = x.drop(col, axis=1)
    return x

Ответ 5

Во-первых, я бы предложил использовать что-то вроде PCA как метод мерцания размерности, но если вам нужно катиться самостоятельно, тогда ваш вопрос будет недостаточно ограничено. Где коррелируются два столбца, какой из них нужно удалить? Что, если столбец А соотносится со столбцом B, а столбец B сопоставляется с столбцом C, но не столбец A?

Вы можете получить парную матрицу корреляций, вызвав DataFrame.corr() (docs), что может помочь вам в разработке вашего алгоритма, но в конечном итоге вам нужно преобразовать это в список столбцов, чтобы сохранить.

Ответ 6

Вставьте эту функцию в эту функцию и установите порог корреляции. Он автоматически удалит столбцы, но также даст вам диагностику столбцов, которые он упадет, если вы хотите сделать это вручную.

def corr_df(x, corr_val):
    '''
    Obj: Drops features that are strongly correlated to other features.
          This lowers model complexity, and aids in generalizing the model.
    Inputs:
          df: features df (x)
          corr_val: Columns are dropped relative to the corr_val input (e.g. 0.8)
    Output: df that only includes uncorrelated features
    '''

    # Creates Correlation Matrix and Instantiates
    corr_matrix = x.corr()
    iters = range(len(corr_matrix.columns) - 1)
    drop_cols = []

    # Iterates through Correlation Matrix Table to find correlated columns
    for i in iters:
        for j in range(i):
            item = corr_matrix.iloc[j:(j+1), (i+1):(i+2)]
            col = item.columns
            row = item.index
            val = item.values
            if val >= corr_val:
                # Prints the correlated feature set and the corr val
                print(col.values[0], "|", row.values[0], "|", round(val[0][0], 2))
                drop_cols.append(i)

    drops = sorted(set(drop_cols))[::-1]

    # Drops the correlated columns
    for i in drops:
        col = x.iloc[:, (i+1):(i+2)].columns.values
        df = x.drop(col, axis=1)

    return df

Ответ 7

Небольшая редакция решения, опубликованного пользователем 3025698, которая решает проблему, при которой не фиксируется корреляция между первыми двумя столбцами и выполняется некоторая проверка типов данных.

def filter_df_corr(inp_data, corr_val):
    '''
    Returns an array or dataframe (based on type(inp_data) adjusted to drop \
        columns with high correlation to one another. Takes second arg corr_val
        that defines the cutoff

    ----------
    inp_data : np.array, pd.DataFrame
        Values to consider
    corr_val : float
        Value [0, 1] on which to base the correlation cutoff
    '''
    # Creates Correlation Matrix
    if isinstance(inp_data, np.ndarray):
        inp_data = pd.DataFrame(data=inp_data)
        array_flag = True
    else:
        array_flag = False
    corr_matrix = inp_data.corr()

    # Iterates through Correlation Matrix Table to find correlated columns
    drop_cols = []
    n_cols = len(corr_matrix.columns)

    for i in range(n_cols):
        for k in range(i+1, n_cols):
            val = corr_matrix.iloc[k, i]
            col = corr_matrix.columns[i]
            row = corr_matrix.index[k]
            if abs(val) >= corr_val:
                # Prints the correlated feature set and the corr val
                print(col, "|", row, "|", round(val, 2))
                drop_cols.append(col)

    # Drops the correlated columns
    drop_cols = set(drop_cols)
    inp_data = inp_data.drop(columns=drop_cols)
    # Return same type as inp
    if array_flag:
        return inp_data.values
    else:
        return inp_data

Ответ 8

Другой эффективный способ найти корреляцию - использовать профилирование панд. Когда у вас есть готовый фрейм данных, просто используйте

import pandas_profiling as pp

 your_df_report= pp.ProfileReport(your_df)
 your_df_report.to_file("your_df_report.html")

Этот отчет в формате html содержит подробный отчет о вашем фрейме данных, который является ничем иным, как EDA, который также включает в себя ваши взаимосвязи между различными функциями. Он также предложит вам отбросить столбцы с высоким соотношением.