Grupowanie macierzy korelacji


20

Mam macierz korelacji, która określa, w jaki sposób każdy element jest skorelowany z drugim elementem. Dlatego dla N elementów mam już macierz korelacji N * N. Korzystając z tej macierzy korelacji, w jaki sposób grupuję N elementów w pojemnikach M, aby móc powiedzieć, że elementy Nk w k-tym bin zachowują się tak samo. Prosimy mi pomóc. Wszystkie wartości pozycji są jakościowe.

Dzięki. Daj mi znać, jeśli potrzebujesz więcej informacji. Potrzebuję rozwiązania w Pythonie, ale wszelka pomoc w popchnięciu mnie do wymagań będzie dużą pomocą.


jak duży jest zwykle N?
Rodin

1
Nie potrzebuję hierarchicznego grupowania dla mojego problemu. Wystarczy powiedzieć, które elementy zachowują się podobnie.
Abhishek093

N wynosi zwykle 250 - 300.
Abhishek093

3
Do Twojej wiadomości, ten problem nazywa się bi-klastrowaniem. Demo tego można znaleźć na scikit-learn.org/stable/auto_examples/bicluster/…
chanp

Odpowiedzi:


15

Wygląda jak zadanie do modelowania bloków. Google do „modelowania bloków” i kilka pierwszych trafień są pomocne.

Załóżmy, że mamy macierz kowariancji, w której N = 100, a faktycznie jest 5 klastrów: Początkowa macierz kowariancji

Modelowanie bloków próbuje znaleźć kolejność wierszy, aby klastry stały się widoczne jako „bloki”: Zoptymalizowana kolejność macierzy kowariancji

Poniżej znajduje się przykład kodu, który wykonuje podstawowe chciwe wyszukiwanie, aby to osiągnąć. Prawdopodobnie jest zbyt wolny dla twoich zmiennych 250-300, ale to początek. Sprawdź, czy możesz śledzić wraz z komentarzami:

import numpy as np
from matplotlib import pyplot as plt

# This generates 100 variables that could possibly be assigned to 5 clusters
n_variables = 100
n_clusters = 5
n_samples = 1000

# To keep this example simple, each cluster will have a fixed size
cluster_size = n_variables // n_clusters

# Assign each variable to a cluster
belongs_to_cluster = np.repeat(range(n_clusters), cluster_size)
np.random.shuffle(belongs_to_cluster)

# This latent data is used to make variables that belong
# to the same cluster correlated.
latent = np.random.randn(n_clusters, n_samples)

variables = []
for i in range(n_variables):
    variables.append(
        np.random.randn(n_samples) + latent[belongs_to_cluster[i], :]
    )

variables = np.array(variables)

C = np.cov(variables)

def score(C):
    '''
    Function to assign a score to an ordered covariance matrix.
    High correlations within a cluster improve the score.
    High correlations between clusters decease the score.
    '''
    score = 0
    for cluster in range(n_clusters):
        inside_cluster = np.arange(cluster_size) + cluster * cluster_size
        outside_cluster = np.setdiff1d(range(n_variables), inside_cluster)

        # Belonging to the same cluster
        score += np.sum(C[inside_cluster, :][:, inside_cluster])

        # Belonging to different clusters
        score -= np.sum(C[inside_cluster, :][:, outside_cluster])
        score -= np.sum(C[outside_cluster, :][:, inside_cluster])

    return score


initial_C = C
initial_score = score(C)
initial_ordering = np.arange(n_variables)

plt.figure()
plt.imshow(C, interpolation='nearest')
plt.title('Initial C')
print 'Initial ordering:', initial_ordering
print 'Initial covariance matrix score:', initial_score

# Pretty dumb greedy optimization algorithm that continuously
# swaps rows to improve the score
def swap_rows(C, var1, var2):
    '''
    Function to swap two rows in a covariance matrix,
    updating the appropriate columns as well.
    '''
    D = C.copy()
    D[var2, :] = C[var1, :]
    D[var1, :] = C[var2, :]

    E = D.copy()
    E[:, var2] = D[:, var1]
    E[:, var1] = D[:, var2]

    return E

current_C = C
current_ordering = initial_ordering
current_score = initial_score

max_iter = 1000
for i in range(max_iter):
    # Find the best row swap to make
    best_C = current_C
    best_ordering = current_ordering
    best_score = current_score
    for row1 in range(n_variables):
        for row2 in range(n_variables):
            if row1 == row2:
                continue
            option_ordering = best_ordering.copy()
            option_ordering[row1] = best_ordering[row2]
            option_ordering[row2] = best_ordering[row1]
            option_C = swap_rows(best_C, row1, row2)
            option_score = score(option_C)

            if option_score > best_score:
                best_C = option_C
                best_ordering = option_ordering
                best_score = option_score

    if best_score > current_score:
        # Perform the best row swap
        current_C = best_C
        current_ordering = best_ordering
        current_score = best_score
    else:
        # No row swap found that improves the solution, we're done
        break

# Output the result
plt.figure()
plt.imshow(current_C, interpolation='nearest')
plt.title('Best C')
print 'Best ordering:', current_ordering
print 'Best score:', current_score
print
print 'Cluster     [variables assigned to this cluster]'
print '------------------------------------------------'
for cluster in range(n_clusters):
    print 'Cluster %02d  %s' % (cluster + 1, current_ordering[cluster*cluster_size:(cluster+1)*cluster_size])

Czy ta technika nie jest używana do grupowania sieci społecznościowych? Czy to będzie istotne tutaj? Czy sensowne jest zastosowanie tej macierzy korelacji jako macierzy odległości?
Abhishek093

1) Tak, 2) Myślę, że tak, 3) Tak (wartości, które są wysoce skorelowane, są bliskie)
Rodin

W porządku. Przejrzałem kilka pierwszych linków. Nadal nie wiem, jak to pomoże mi rozwiązać mój problem.
Abhishek093

Zredagowałem swoją odpowiedź. Mam nadzieję, że ci się przyda.
Rodin

Sprawdzę to teraz. Dam ci znać, czy pasuje do mojego problemu. Dziękuję bardzo.
Abhishek093

6

Czy spojrzałeś na hierarchiczne grupowanie? Może pracować z podobieństwami, nie tylko odległościami. Możesz wyciąć dendrogram na wysokości, na której dzieli się on na k klastrów, ale zwykle lepiej jest wizualnie sprawdzić dendrogram i zdecydować o wysokości cięcia.

Hierarchiczne grupowanie jest również często wykorzystywane do uzyskania sprytnego uporządkowania w celu waporyzacji macierzy podobieństwa, jak widać w drugiej odpowiedzi: umieszcza więcej podobnych wpisów obok siebie. Może to również służyć jako narzędzie sprawdzania poprawności dla użytkownika!


2

Czy zastanawiałeś się nad grupowaniem korelacji ? Ten algorytm grupowania korzysta z par dodatniej / ujemnej informacji o korelacji, aby automatycznie zaproponować optymalną liczbę klastrów o dobrze zdefiniowanej funkcjonalnej i ścisłej generatywnej interpretacji probabilistycznej .


Promowanego artykułu Wikipedii: Correlation clustering provides a method for clustering a set of objects into the optimum number of clusters without specifying that number in advance. Czy to definicja metody? Jeśli tak, to dziwne, ponieważ istnieją inne metody automatycznego sugerowania liczby klastrów, a także dlaczego nazywa się to „korelacją”.
ttnphns

@ttnphns (1) nazywa się to „klastrowaniem korelacji”, ponieważ oczekuje jako danych wejściowych macierzy korelacji parami (patrz przełomowe dzieło Bansal, N .; Blum, A .; Chawla, S. (2004).) „Correlation Clustering „. Uczenie maszynowe. 56: 89).
Shai

@ttnphns na temat „optymalnej liczby klastrów”: masz rację, że „optymalna” jest niejednoznaczna, „optymalna” pod jakim względem? Jeśli chodzi o grupowanie korelacji, jeśli zaakceptujesz model generatywny zaproponowany w Bagon & Galun „Large Scale Correlation Clustering” , wówczas metoda generuje liczbę optymalną.
Shai

Shai, wygląda na to, że jesteś jednym z wynalazców tej metody. Zachęcam cię do udzielenia bardziej nieopakowanej odpowiedzi, przedstawiając ją - jeśli masz czas i pragnienie. W szczególności chce się dowiedzieć, w jaki sposób metoda jest umieszczana wśród niektórych dobrze znanych, takich jak k-średnie lub hierarhiczne. Zauważ też, że korelacja jest łatwo przeliczalna na odległość euklidesową (przy każdej późniejszej standardowej metodzie grupowania), - znając ten fakt / sztuczkę, jakie rzeczy pozwala na to twoja metoda, na którą ta „sztuczka” nie pozwala? Napisz o tym. (Z góry dziękuję!)
ttnphns

1
Mam nadzieję, że to obejmuje. Chciałem tylko powiedzieć, że zawsze dobrym pomysłem jest podanie nieco więcej szczegółów w odpowiedzi opublikowanej na tej stronie, szczególnie gdy metoda jest raczej nowa i kiedy wiadomo, co powiedzieć, będąc wynalazcą. :-) Nie, nie jest „zbyt szeroki”.
ttnphns

-1

Filtrowałbym według pewnego znaczącego progu (istotności statystycznej), a następnie użyłem dekompozycji Dulmage-Mendelsohna, aby uzyskać połączone komponenty. Być może zanim spróbujesz usunąć jakiś problem, taki jak korelacje przechodnie (silnie skorelowane z B, B do C, C do D, więc istnieje składnik zawierający je wszystkie, ale w rzeczywistości D do A jest niski). możesz użyć algorytmu opartego na międzyczasie. Nie jest to problem dwulicowy, jak ktoś sugerował, ponieważ macierz korelacji jest symetryczna i dlatego nie ma bi-czegoś.


Ta odpowiedź nie wyjaśnia, jak ustawić sugerowane progi, które IMO wydaje się arbitralne. Ponadto, ponieważ to pytanie ma dwa lata, a odpowiedź z kilkoma głosami pozytywnymi została już zaakceptowana, możesz chcieć rozwinąć już istniejące informacje.
IWS,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.