聚类相关矩阵


20

我有一个相关矩阵,该矩阵说明每个项目如何与另一个项目相关。因此,对于N个项目,我已经具有N * N个相关矩阵。使用此相关矩阵,如何将N个项目聚类在M个仓中,以便可以说第k个仓中的Nk个项目表现相同。请帮我。所有项目值都是分类的。

谢谢。请让我知道是否需要更多信息。我需要使用Python解决方案,但是任何将我推向要求的帮助都会有很大帮助。


N通常有多大?
罗丹

1
对于我的问题,我不需要分层聚类。只需说出哪些项目的行为相同即可。
Abhishek093 2015年

N是通常为250 - 300
Abhishek093

3
仅供参考,此问题称为双向群集。可以在scikit-learn.org/stable/auto_examples/bicluster/…中
chanp 2016年

Answers:


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 2015年

1)是,2)我是这样,3)是(高度相关的值很接近)
Rodin

好的。我看穿了前几个链接。我仍然不知道这将如何帮助我解决我的问题。
Abhishek093 2015年

我已经编辑了答案。希望对您有用。
罗丹

我现在要检查一下。我会告诉您是否适合我的问题。非常感谢。
Abhishek093 2015年

6

您是否看过分层集群?它可以具有相似性,而不仅仅是距离。您可以在将树状图拆分成k个簇的高度处切割树状图,但通常最好是目视检查树状图并确定要切割的高度。

分层聚类通常也用于对相似矩阵虚拟化产生巧妙的重新排序,如另一个答案所示:它将更多相似的条目彼此相邻放置。这也可以用作用户的验证工具!


2

您是否研究了相关性聚类?该聚类算法使用成对的正/负相关信息自动提出具有良好定义的功能和严格的生成概率解释的最佳聚类数。


升级后的Wikipedia文章: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)之所以被称为“相关性聚类”,是因为它期望将成对的相关矩阵作为输入(请参见Bansal,N .; Blum,A .; Chawla,S.(2004)的开创性工作。 “。机器学习。56:89)。
Shai 2013年

@ttnphns关于“最佳簇数”:您对“最佳”模棱两可的事实是正确的,在什么情况下“最佳”是正确的?对于相关性聚类,如果您接受Bagon&Galun在“大型相关性聚类”中提出的生成模型,则该方法会输出最佳数量。
Shai 2013年

Shai,看来您是该方法的发明者之一。如果您有时间和渴望,我鼓励您给出一个更简洁的答案。具体而言,人们想知道该方法是如何放置在一些公认的方法中的,例如k均值或分层方法。还请注意,相关性很容易转换为欧几里德距离(以后可以应用任何标准聚类方法),-知道该事实/技巧后,您的方法又允许哪些东西,而“技巧”则不允许呢?写吧。(提前感谢!)
ttnphns

1
我希望它能覆盖。我只是想说,在此网站上发布的答案中提供更多细节总是一个好主意,尤其是当一种方法相当新并且当一个人知道要说什么时,他就是发明家。:-)不,不是“太宽泛”。
ttnphns

-1

我将过滤某个有意义的(统计显着性)阈值,然后使用dulmage-mendelsohn分解来获取连接的组件。也许在您尝试消除传递相关性之类的问题之前(A与B,B与C,C与D高度相关,因此有一个包含所有这些成分的组件,但实际上D与A的相关性很低)。您可以使用一些基于中间性的算法。就像有人建议的那样,这不是一个双重问题,因为相关矩阵是对称的,因此不存在二元性。


这个答案并没有完全解释如何设置建议的阈值,IMO似乎是任意的。此外,由于这个问题已有两年历史了,并且已经接受了两次投票的答案,所以您可能想详细说明现有的信息。
IWS
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.