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