Python: TOP 10 skorelowanych kolumn

7-lip-2024

W analizie danych zależy nam na wykryciu ukrytych relacji między różnymi cechami danych. Pomocne są w tym wykresy w rodzaju „heat-map” i wszystko ładnie, póki dane, które przetwarzamy są w miarę małe. A co jeśli mamy, dajmy na to 100 kolumn? Oczywiście znajdowanie najbardziej skorelowanych danych i wybieranie tych najbardziej skorelowanych da się zautomatyzować. Zobaczymy taki przykład:

import pandas as pd
import numpy as np
# Create a sample DataFrame (replace with your actual data)
shape = (50, 100) # 50 rows, 100 columns
data = np.random.normal(size=shape)
data[:, 10] += data[:, 20]
# Introduce some correlation
df = pd.DataFrame(data)

Ten przykładowy zestaw danych ma 50 wierszy i 100 kolumn. Część kolumn została ze sobą sztucznie skorelowana. W następnym kroku możemy wyznaczyć macierz korelacji:

# Calculate the correlation matrix
correlation_matrix = df.corr().abs()

Ta macierz ma już 100 wierszy i 100 kolumn. Trudno by było jednak wyszukiwać maksymalnej wartości w tablicy 100×100. Łatwiej będziem jeśli wszystkie wartości umieścimy w jednej kolumnie

Pobawmy się tą tablicą korelacji, nim zbudujemy finalne rozwiazanie. Pozwoli to nam zrozumieć, co tutaj pod spodem się dzieje. To polecenie zamieni tablicę 100×100 na tablicę z indeksem, jedną kolumną i 10000 wierszami.

correlation_matrix.unstack()

Ten obiekt ma też ciekawy indeks, tzw. multiindeks:

correlation_matrix.unstack().index

Wygląda on mniej więcej tak:

MultiIndex([( 0,  0),
            ( 0,  1),
            ( 0,  2),
            ( 0,  3),
            ( 0,  4),
            ( 0,  5),
            ( 0,  6),
            ( 0,  7),
            ( 0,  8),
            ( 0,  9),
            ...
            (99, 90),
            (99, 91),
            (99, 92),
            (99, 93),
            (99, 94),
            (99, 95),
            (99, 96),
            (99, 97),
            (99, 98),
            (99, 99)],
           length=10000)

Każdy wiersz tej dłuuugiej listy jest adresowany dwiema wartościami, które odpowiadają numerowi wiersza i numerowi kolumny z oryginalnego data frame, od którego wystartowaliśmy.

Nas interesują najbardziej skorelowane kolumny, dlatego posortujemy dane w oparciu o wartości, pewnie wolelibyśmy też widzieć największe wartości na początku:

correlation_matrix.unstack().sort_values(kind="quicksort", ascending=False)

Wynik wygląda mniej więcej tak:

46  46    1.000000
99  99    1.000000
0   0     1.000000
45  45    1.000000
26  26    1.000000
            ...   
81  95    0.000093
21  75    0.000010
75  21    0.000010
19  70    0.000001
70  19    0.000001
Length: 10000, dtype: float64

Jak widać największa korelacja pojawia się między kolumną a nią samą… w wyjściowej matrycy korelacji te wartości znajdowały się na przekątnej. Mają one numer wiersza i kolumny taki sam. Trzeba by je wykluczyć. Na dodatek, matryca korelacji wykazuje taką samą wartość dla kolumn 3 i 13 oraz 13 i 3. Dlatego możnaby wyrzucić z danych jakie będziemy analizować te wartości, które znajdowałyby się na przekątnej lub są wartościami zdublowanymi:

m = correlation_matrix.unstack()
first = m[m.index.get_level_values(0) < m.index.get_level_values(1)]

No to teraz już będzie z górki. Wystarczy posortować dane, tak jak robiliśmy to wcześniej i wybrać tych dajmy na to 10 „naj”:

first.sort_values(kind=”quicksort”, ascending=False).head(10)

Oto wynik:

10  20    0.839781
13  36    0.485660
40  52    0.481521
11  77    0.479348
26  66    0.474195
69  93    0.471580
20  26    0.462138
53  72    0.456067
47  94    0.444600
8   74    0.443435
dtype: float64

Komentarze są wyłączone

Autor: Rafał Kraik