Кластеризация корреляционной матрицы

20

У меня есть корреляционная матрица, в которой указано, как каждый элемент соотносится с другим элементом. Следовательно, для N элементов у меня уже есть N * N корреляционная матрица. Используя эту корреляционную матрицу, как кластеризовать N элементов в M бинах, чтобы я мог сказать, что Nk элементов в k-ом бине ведут себя одинаково. Пожалуйста, помогите мне. Все значения элемента являются категориальными.

Благодарю. Дайте мне знать, если вам нужна дополнительная информация. Мне нужно решение на Python, но любая помощь в продвижении к требованиям будет большой помощью.

Abhishek093
источник
насколько велика обычно N?
Роден
1
Мне не нужна иерархическая кластеризация для моей проблемы. Просто нужно сказать, какие предметы ведут себя так же.
Abhishek093
N обычно составляет 250 - 300.
Abhishek093
3
К вашему сведению, эта проблема называется би-кластеризацией. Демонстрацию этого можно найти по адресу scikit-learn.org/stable/auto_examples/bicluster/…
chanp

Ответы:

15

Похоже, работа для блочного моделирования. Google для "блочного моделирования" и первые несколько хитов полезны.

Скажем, у нас есть ковариационная матрица, где N = 100, и на самом деле есть 5 кластеров: Начальная ковариационная матрица

Моделирование блоков пытается найти порядок строк, чтобы кластеры стали очевидными как «блоки»: Оптимизированный порядок ковариационных матриц

Ниже приведен пример кода, который выполняет простой жадный поиск для достижения этой цели. Вероятно, это слишком медленно для ваших 250-300 переменных, но это только начало. Посмотрите, можете ли вы следовать вместе с комментариями:

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])
Родин
источник
Разве этот метод не используется для кластеризации в социальных сетях? Это будет актуально здесь? Имеет ли смысл использовать эту корреляционную матрицу в качестве матрицы расстояний?
Abhishek093
1) Да, 2) Я так думаю, 3) Да (сильно коррелированные значения близки)
Родин
Ладно. Я видел первые несколько ссылок. Я до сих пор не знаю, как это поможет мне решить мою проблему.
Abhishek093
Я отредактировал свой ответ. Я надеюсь, что это полезно для вас.
Роден
Я собираюсь проверить это сейчас. Я дам вам знать, если это соответствует моей проблеме. Огромное спасибо.
Abhishek093
6

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

Иерархическая кластеризация также часто используется для создания умного переупорядочения для визуализации матрицы сходства, как видно из другого ответа: она размещает больше похожих записей рядом друг с другом. Это также может служить средством проверки для пользователя!

Аноним-Мусс-Восстановить Монику
источник
2

Вы смотрели на корреляционную кластеризацию ? Этот алгоритм кластеризации использует информацию о попарной положительной / отрицательной корреляции, чтобы автоматически предлагать оптимальное число кластеров с четко определенным функционалом и строгой генеративной вероятностной интерпретацией .

Шай
источник
Способствовали статьи Википедии: Correlation clustering provides a method for clustering a set of objects into the optimum number of clusters without specifying that number in advance. Это определение метода? Если да, это странно, потому что существуют другие методы для автоматического определения количества кластеров, а также, почему тогда это называется "корреляцией".
ttnphns
@ttnphns (1) это называется «корреляционная кластеризация», потому что она ожидает в качестве входных данных попарно-корреляционную матрицу (см. основную работу Бансала, N .; Блум, А.; Чавла, S. (2004). «Корреляционная кластеризация» ". Машинное обучение. 56: 89).
Шай
@ttnphns относительно «оптимального числа кластеров»: вы правы в том, что «оптимальный» является неоднозначным, «оптимальным» по какой мере? Что касается корреляционной кластеризации, если вы принимаете генеративную модель, предложенную в Bagon & Galun «Крупномасштабная корреляционная кластеризация» , то метод действительно выводит оптимальное число.
Шай
Шай, похоже, ты один из изобретателей метода. Я бы посоветовал вам дать более развернутый ответ, представив его - если у вас есть время и желание. В частности, нужно знать, как метод размещается среди некоторых хорошо известных, таких как k-средних или иерархических. Также обратите внимание, что корреляция легко конвертируется в евклидово расстояние (с любым стандартным методом кластеризации, применимым впоследствии), - зная этот факт / уловку, что тогда позволяет ваш метод, чего не позволяет этот «уловка»? Напиши об этом. (Заранее спасибо!)
ttnphns
1
Я надеюсь, что это покрывает. Я просто хотел сказать, что это всегда хорошая идея, чтобы дать немного больше подробностей в ответе, размещенном на этом сайте, особенно когда метод довольно новый и когда кто-то знает, что сказать, будучи изобретателем. :-) Нет, не "слишком широк".
ttnphns
-1

Я бы отфильтровал на некотором значимом (статистически значимом) пороге, а затем использовал бы разложение dulmage-mendelsohn, чтобы получить связанные компоненты. Может быть, прежде чем вы сможете попытаться устранить некоторые проблемы, такие как транзитивные корреляции (A сильно коррелирует с B, B к C, C к D, поэтому есть компонент, содержащий все из них, но на самом деле D к A является низким). Вы можете использовать некоторый алгоритм, основанный на промежуточности. Это не бикластеризованная проблема, как кто-то предложил, так как матрица корреляции симметрична, и, следовательно, нет двусмысленности.

user2843263
источник
Этот ответ не совсем объясняет, как установить предложенные пороговые значения, которые IMO кажется произвольными. Кроме того, поскольку этому вопросу уже два года, и ответ с несколькими ответами был уже принят, вы можете уточнить уже существующую информацию.
IWS