【问题标题】:scikit-learn: Finding the features that contribute to each KMeans clusterscikit-learn:查找对每个 KMeans 集群有贡献的特征
【发布时间】:2015-02-13 23:18:33
【问题描述】:

假设您有 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_

【问题讨论】:

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


    【解决方案1】:

    我想出的一种方法是计算每个特征相对于分布的标准差 - 基本上数据是如何分布在每个特征中的

    散布越小,基本上每个簇的特征越好:

    1 - (std(x) / (max(x) - min(x))
    

    我写了一篇文章和一个类来维护它

    https://github.com/GuyLou/python-stuff/blob/main/pluster.py

    https://medium.com/@guylouzon/creating-clustering-feature-importance-c97ba8133c37

    【讨论】:

      【解决方案2】:

      可能很难单独讨论每个集群的特征重要性。相反,最好在全球范围内讨论哪些特征对于分离不同的集群最重要。

      为了这个目标,一个非常简单的方法描述如下。请注意,两个聚类中心之间的欧几里得距离是各个特征之间的平方差之和。然后我们可以只使用平方差作为每个特征的权重。

      【讨论】:

        【解决方案3】:

        试试这个,

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

        你会得到cluster和feature_weights的矩阵,从中你可以得出结论,具有更大权重的特征对cluster有很大的贡献。

        【讨论】:

        • cluster_centers_ 不返回特征权重,而是返回簇位置。
        【解决方案4】:

        你可以使用

        Principle Component Analysis (PCA)

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

        一些要点:

        • 特征值反映了相应分量解释的方差部分。比如说,我们有 4 个特征值 1, 4, 1, 2。这些是对应解释的差异。向量。第二个值属于第一个主成分,因为它解释了 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')
        

        输出

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

        简短解释

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

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

        【讨论】:

          【解决方案5】:

          我假设您所说的“主要功能”是指 - 对课程的影响最大。您可以做的一个很好的探索是查看集群中心的坐标。例如,为每个特征绘制它在每个 K 中心的坐标。

          当然,任何大规模的特征都会对观测值之间的距离产生更大的影响,因此在执行任何分析之前,请确保您的数据具有良好的缩放比例。

          【讨论】:

          【解决方案6】:

          你可以这样做:

          >>> 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])
          

          【讨论】:

            猜你喜欢
            • 2015-03-28
            • 2016-05-16
            • 2011-08-15
            • 2018-08-01
            • 2022-11-23
            • 2015-04-05
            • 1970-01-01
            • 1970-01-01
            • 2019-12-31
            相关资源
            最近更新 更多