scikit-learn:查找有助于每个KMeans集群的功能

时间:2014-12-15 19:01:24

标签: python scikit-learn cluster-analysis k-means

假设您有10个功能用于创建3个群集。有没有办法看到每个功能对每个群集的贡献水平?

我希望能够说的是,对于群集k1,特征1,4,6是主要特征,其中群集k2的主要特征是2,5,7。

这是我正在使用的基本设置:

k_means = KMeans(init='k-means++', n_clusters=3, n_init=10)
k_means.fit(data_features)
k_means_labels = k_means.labels_

5 个答案:

答案 0 :(得分:17)

您可以使用

Principle Component Analysis (PCA)

  PCA可以通过数据协方差(或相关)矩阵的特征值分解或数据矩阵的奇异值分解来完成,通常在对每个属性的平均居中(和归一化或使用Z分数)数据矩阵之后。 PCA的结果通常根据组件得分进行讨论,有时称为因子得分(对应于特定数据点的转换变量值)和加载(每个标准化原始变量应乘以得到组件得分的权重) )。

一些要点:

  • 特征值反映了由相应组件解释的方差部分。比方说,我们有4个特征值1, 4, 1, 2的特征。这些是由corresp解释的差异。向量。第二个值属于第一个主要成分,因为它解释了整体方差的50%,最后一个值属于第二个主要成分,解释了整体方差的25%。
  • 特征向量是组件的线性组合。为特征赋予权重,以便您可以知道哪个特征具有高/低影响。
  • 使用基于相关矩阵的PCA 而不是经验协方差矩阵,如果特征值强烈不同(幅度)。

示例方法

  • 对整个数据集执行PCA(以下功能是什么)
    • 带有观察和特征的矩阵
    • 将其居中于其平均值(所有观测值中的特征值的平均值)
    • 计算经验协方差矩阵(例如np.cov)或相关性(见上文)
    • 执行分解
    • 通过特征值对特征值和特征向量进行排序,以获得影响最大的组件
    • 在原始数据上使用组件
  • 检查转换后的数据集中的聚类。通过检查每个组件的位置,您可以获得对分布/差异具有高和低影响的功能

示例功能

您需要import numpy as npscipy as sp。它使用sp.linalg.eigh进行分解。您可能还想查看scikit decomposition module

PCA在数据矩阵上执行,其中行中的观察(对象)和列中的特征。

def dim_red_pca(X, d=0, corr=False):
    r"""
    Performs principal component analysis.

    Parameters
    ----------
    X : array, (n, d)
        Original observations (n observations, d features)

    d : int
        Number of principal components (default is ``0`` => all components).

    corr : bool
        If true, the PCA is performed based on the correlation matrix.

    Notes
    -----
    Always all eigenvalues and eigenvectors are returned,
    independently of the desired number of components ``d``.

    Returns
    -------
    Xred : array, (n, m or d)
        Reduced data matrix

    e_values : array, (m)
        The eigenvalues, sorted in descending manner.

    e_vectors : array, (n, m)
        The eigenvectors, sorted corresponding to eigenvalues.

    """
    # Center to average
    X_ = X-X.mean(0)
    # Compute correlation / covarianz matrix
    if corr:
        CO = np.corrcoef(X_.T)
    else:
        CO = np.cov(X_.T)
    # Compute eigenvalues and eigenvectors
    e_values, e_vectors = sp.linalg.eigh(CO)

    # Sort the eigenvalues and the eigenvectors descending
    idx = np.argsort(e_values)[::-1]
    e_vectors = e_vectors[:, idx]
    e_values = e_values[idx]
    # Get the number of desired dimensions
    d_e_vecs = e_vectors
    if d > 0:
        d_e_vecs = e_vectors[:, :d]
    else:
        d = None
    # Map principal components to original data
    LIN = np.dot(d_e_vecs, np.dot(d_e_vecs.T, X_.T)).T
    return LIN[:, :d], e_values, e_vectors

样本用法

这是一个示例脚本,它使用给定的函数并使用scipy.cluster.vq.kmeans2进行聚类。请注意,结果因每次运行而异。这是由于起始集群随机初始化。

import numpy as np
import scipy as sp
from scipy.cluster.vq import kmeans2
import matplotlib.pyplot as plt

SN = np.array([ [1.325, 1.000, 1.825, 1.750],
                [2.000, 1.250, 2.675, 1.750],
                [3.000, 3.250, 3.000, 2.750],
                [1.075, 2.000, 1.675, 1.000],
                [3.425, 2.000, 3.250, 2.750],
                [1.900, 2.000, 2.400, 2.750],
                [3.325, 2.500, 3.000, 2.000],
                [3.000, 2.750, 3.075, 2.250],
                [2.075, 1.250, 2.000, 2.250],
                [2.500, 3.250, 3.075, 2.250],
                [1.675, 2.500, 2.675, 1.250],
                [2.075, 1.750, 1.900, 1.500],
                [1.750, 2.000, 1.150, 1.250],
                [2.500, 2.250, 2.425, 2.500],
                [1.675, 2.750, 2.000, 1.250],
                [3.675, 3.000, 3.325, 2.500],
                [1.250, 1.500, 1.150, 1.000]], dtype=float)

clust,labels_ = kmeans2(SN,3)    # cluster with 3 random initial clusters
# PCA on orig. dataset 
# Xred will have only 2 columns, the first two princ. comps.
# evals has shape (4,) and evecs (4,4). We need all eigenvalues 
# to determine the portion of variance
Xred, evals, evecs = dim_red_pca(SN,2)   

xlab = '1. PC - ExpVar = {:.2f} %'.format(evals[0]/sum(evals)*100) # determine variance portion
ylab = '2. PC - ExpVar = {:.2f} %'.format(evals[1]/sum(evals)*100)
# plot the clusters, each set separately
plt.figure()    
ax = plt.gca()
scatterHs = []
clr = ['r', 'b', 'k']
for cluster in set(labels_):
    scatterHs.append(ax.scatter(Xred[labels_ == cluster, 0], Xred[labels_ == cluster, 1], 
                   color=clr[cluster], label='Cluster {}'.format(cluster)))
plt.legend(handles=scatterHs,loc=4)
plt.setp(ax, title='First and Second Principle Components', xlabel=xlab, ylabel=ylab)
# plot also the eigenvectors for deriving the influence of each feature
fig, ax = plt.subplots(2,1)
ax[0].bar([1, 2, 3, 4],evecs[0])
plt.setp(ax[0], title="First and Second Component's Eigenvectors ", ylabel='Weight')
ax[1].bar([1, 2, 3, 4],evecs[1])
plt.setp(ax[1], xlabel='Features', ylabel='Weight')

输出

特征向量显示组件的每个特征的权重

enter image description here

enter image description here

简短解释

让我们看看群集零,红色群。我们对第一个组件最感兴趣,因为它解释了3/4的分布。红色簇位于第一个组件的上部区域。所有观察都产生相当高的值。这是什么意思?现在看一下我们第一眼看到的第一个组件的线性组合,第二个特征相当不重要(对于这个组件)。第一和第四个特征是加权最高的,第三个特征是负分。这意味着,因为所有红色顶点在第一台PC上都有相当高的分数 - 这些顶点在第一个和最后一个特征中具有较高的值,同时它们的分数较低第三个特点。

关于第二个功能,我们可以看一下第二台PC。但请注意,总体影响要小得多,因为该组件仅解释了大约16%的差异,而第一台PC的差异仅为74%。

答案 1 :(得分:3)

你可以这样做:

>>> import numpy as np
>>> import sklearn.cluster as cl
>>> data = np.array([99,1,2,103,44,63,56,110,89,7,12,37])
>>> k_means = cl.KMeans(init='k-means++', n_clusters=3, n_init=10)
>>> k_means.fit(data[:,np.newaxis]) # [:,np.newaxis] converts data from 1D to 2D
>>> k_means_labels = k_means.labels_
>>> k1,k2,k3 = [data[np.where(k_means_labels==i)] for i in range(3)] # range(3) because 3 clusters
>>> k1
array([44, 63, 56, 37])
>>> k2
array([ 99, 103, 110,  89])
>>> k3
array([ 1,  2,  7, 12])

答案 2 :(得分:1)

我认为通过说"一个主要特征"你的意思是 - 对班级产生了最大的影响。您可以做的一个很好的探索是查看聚类中心的坐标。例如,在每个K中心协调每个特征的坐标。

当然,任何大规模的特征都会对观察之间的距离产生更大的影响,因此在进行任何分析之前,请确保您的数据得到很好的扩展。

答案 3 :(得分:1)

试试这个,

estimator=KMeans()
estimator.fit(X)
res=estimator.__dict__
print res['cluster_centers_']

您将获得群集矩阵和feature_weights,您可以得出结论,具有更多权重的功能主要用于贡献群集。

答案 4 :(得分:0)

可能很难分别讨论每个群集的功能重要性。相反,最好全局地讨论哪些功能对于分离不同的群集最重要。

为此,一个非常简单的方法描述如下。请注意,两个聚类中心之间的欧式距离是各个要素之间平方差的总和。然后,我们可以使用平方差作为每个功能的权重。

Euclidean Distance