Spectral Clustering Scikit学习Cluster中的打印项目

时间:2015-09-26 11:41:00

标签: python machine-learning scikit-learn

我知道我可以使用scikit-learn使用以下代码在K-means聚类中获取特定聚类的内容。

    order_centroids = model.cluster_centers_.argsort()[:, ::-1]
    terms = vectorizer.get_feature_names()
    for i in range(true_k):
        print "Cluster %d:" % i,
        for ind in order_centroids[i, :10]:
            print ' %s' % terms[ind],
        print

如何对光谱聚类进行同样的操作,因为没有用于光谱聚类的属性'cluster_centers_'?我正在尝试在文本文档中对术语进行聚类。

3 个答案:

答案 0 :(得分:3)

更新: 对不起,我第一次没有正确理解你的问题。

我认为用光谱聚类做你想做的事是不可能的,因为谱聚类方法本身并不能计算任何中心,它根本不需要它们。它甚至不会对原始空间中的采样点进行操作,“光谱聚类”会将数据集转换为不同的子空间,然后尝试聚集此数据集中的点。而且我不知道如何以数学方式反转这种转变。

A Tutorial on Spectral Clustering

也许您应该将您的问题作为更多关于数学相关社区的理论问题。

spectral = cluster.SpectralClustering(n_clusters=2, eigen_solver='arpack', affinity="nearest_neighbors")
spectral.fit(X)
y_pred = spectral.labels_.astype(np.int)

来自here

答案 1 :(得分:1)

虽然您确实无法获得用于光谱聚类的聚类中心,但是您可以做一些接近的事情,在某些情况下可能有用。为了进行说明,我将快速遍历光谱聚类算法并说明修改。

首先,我们将其称为数据集X = {x_1, ..., x_N},其中每个点都是d维(d是您数据集中具有的要素数)。我们可以将X视为Nd的矩阵。假设我们要将这些数据放入k集群中。谱聚类首先将数据集转换为另一个表示形式,然后对数据的新表示形式使用K均值聚类以获得聚类。首先,通过使用K邻居信息形成亲和度矩阵A。为此,我们需要选择一个正整数n来构造A。如果A_{i, j}x_i都在彼此的前x_j个邻居的列表中,并且n等于,则元素A_{i, j}等于1。否则为0。 AN的对称N矩阵。接下来,我们构造L的{​​{3}} A,即L = I - D^{-1/2}AD^{-1/2},其中D是度矩阵。然后在L上执行normalized Laplacian matrix以获得L = VEV^{-1},其中VL的特征向量矩阵,而E是对角线对角线中L的特征值的矩阵。由于L是正半定数,因此其特征值都是非负实数。对于频谱聚类,我们使用它对V的列进行排序,以使V的第一列对应于L的最小特征值,最后一列对应于{ {1}}。

接下来,我们取L的前k列,并将其作为V维空间中的N点进行查看。让我们将此截断的矩阵写为k,并将其行写为V',其中每个{v'_1, ..., v'_N}的维数为v'_i。然后,我们使用K-means算法将这些点聚类为k聚类; k。然后,通过将簇从{C'_1,...,C'_k}“拉回”到X,将簇分配给数据集V'中的点:点X在簇{{1}中}并且仅当x_i在群集C_j中时。

现在,将v'_i转换为C'_j并在该表示上进行聚类的要点之一是,X通常不是球形分布的,至少V'接近如此。由于X更接近于球形分布,因此质心将位于其定义的点簇的“内部”。我们可以得出V'中最接近每个群集的群集质心的点。让我们将群集质心称为V'。这些是表示参数V'的参数空间中的点。然后,对于每个聚类,选择最接近聚类质心的{c_1,...,c_k}的点,以获取{{1 }}。假设V'是最接近V'簇质心的代表点。然后选择k作为V'集群的集群代表。

此方法可能并不总是按您希望的方式工作,但它至少是一种更接近所需的方法,也许您可​​以对其进行修改以更接近所需的内容。这是一些示例代码,展示了如何执行此操作。

让我们使用scikit-learn提供的一些虚假数据。

{v'_i_1,...,v'_i_k}

eigenvalue decomposition

我要作弊,并使用scikit-learn提供的光谱聚类方法,然后从那里提取亲和矩阵。

V'

noisy_moons

接下来,我们将计算亲和矩阵的归一化拉普拉斯算子,而不是计算拉普拉斯算子的整个特征值分解,而是使用{x_i_1,...,x_i_k}函数noisy_moons_clustered来提取两者(因为我们想要两个聚类)对应于两个最小特征值的特征向量。

X

eigsh

然后,让我们使用K均值对数据的这种新表示进行聚类。我们还要在此新表示形式中找到最接近聚类质心的两个点,并突出显示它们。

import numpy as np
import pandas as pd
from sklearn.datasets import make_moons

moons_data = make_moons(n_samples=1000, noise=0.07, random_state=0)
moons = pd.DataFrame(data=moons_data[0], columns=['x', 'y'])
moons['label_truth'] = moons_data[1]

moons.plot(
    kind='scatter',
    x='x',
    y='y',
    figsize=(8, 8),
    s=10,
    alpha=0.7
);

eigenvector_plot

最后,让我们绘制原始数据集并突出显示相应的点。

from sklearn.cluster import SpectralClustering

sclust = SpectralClustering(
    n_clusters=2,
    random_state=42,
    affinity='nearest_neighbors',
    n_neighbors=10,
    assign_labels='kmeans'
)

sclust.fit(moons[['x', 'y']]);

moons['label_cluster'] = sclust.labels_

moons.plot(
    kind='scatter',
    x='x',
    y='y',
    figsize=(16, 14),
    s=10,
    alpha=0.7,
    c='label_cluster',
    cmap='Spectral'
);

eigenvectors_centroid_reps

正如我们所看到的,突出显示的点可能不在我们期望的位置,但是这可能有助于通过算法从每个群集中选择点。

答案 2 :(得分:0)

光谱聚类不计算任何质心。在更实际的情况下,如果您确实需要一种由光谱聚类算法得出的“质心”,则在聚类过程结束之后,您始终可以计算属于同一聚类的点的平均值(均值)。这些将是在典型k均值算法的上下文中定义的质心的近似值。相同的原理也适用于其他不产生质心(例如分层)的聚类算法。