0

我正在对 12 维矩阵进行 KMean 聚类。我设法在 K 组集群中得到了结果。我想通过将结果绘制成二维图形来显示结果,但我不知道如何将 12 维数据转换为二维。

关于如何进行转换或可视化结果的任何替代方法的任何建议?我尝试了 Java 的多维缩放(MDSJ),但它不起作用。

我使用的 KMean 算法来自Java 机器学习库:Clustering basics

4

3 回答 3

1

我会做主成分分析(可能是多维缩放算法中最简单的算法)。(BTW PCA与KMeans无关,是一种通用的降维方法)

  1. 我假设变量在列中,观察值在行中。

  2. 标准化数据 - 将变量转换为 z 分数。这意味着:从每个单元格中减去列的平均值并将结果除以 std。柱的偏差。这样你得到零均值和单位方差。前者是强制性的,后者,我想说,很好。如果方差为零,则从协方差矩阵计算特征向量,否则必须使用自动标准化数据的相关矩阵。见这个解释)。

  3. 计算协方差矩阵的特征向量和特征值。按特征值对特征向量进行排序。(许多库已经为您提供了以这种方式排序的特征向量)。

  4. 使用特征向量矩阵的前两列并乘以原始矩阵(转换为 z 分数),可视化此数据。

使用colt库,您可以执行以下操作。它将与其他矩阵库类似:

    import cern.colt.matrix.DoubleMatrix1D;
    import cern.colt.matrix.DoubleMatrix2D;
    import cern.colt.matrix.doublealgo.Statistic;
    import cern.colt.matrix.impl.SparseDoubleMatrix2D;
    import cern.colt.matrix.linalg.Algebra;
    import cern.colt.matrix.linalg.EigenvalueDecomposition;
    import hep.aida.bin.DynamicBin1D;

    public class Pca {
        // to show matrix creation, it does not make much sense to calculate PCA on random data
        public static void main(String[] x) {
            double[][] data = {
                {2.0,4.0,1.0,4.0,4.0,1.0,5.0,5.0,5.0,2.0,1.0,4.0}, 
                {2.0,6.0,3.0,1.0,1.0,2.0,6.0,4.0,4.0,4.0,1.0,5.0},
                {3.0,4.0,4.0,4.0,2.0,3.0,5.0,6.0,3.0,1.0,1.0,1.0},
                {3.0,6.0,3.0,3.0,1.0,2.0,4.0,6.0,1.0,2.0,4.0,4.0}, 
                {1.0,6.0,4.0,2.0,2.0,2.0,3.0,4.0,6.0,3.0,4.0,1.0}, 
                {2.0,5.0,5.0,3.0,1.0,1.0,6.0,6.0,3.0,2.0,6.0,1.0}
            };

            DoubleMatrix2D matrix = new DenseDoubleMatrix2D(data);

            DoubleMatrix2D pm = pcaTransform(matrix);

            // print the first two dimensions of the transformed matrix - they capture most of the variance of the original data
            System.out.println(pm.viewPart(0, 0, pm.rows(), 2).toString());
        }

        /** Returns a matrix in the space of principal components, take the first n columns  */
        public static DoubleMatrix2D pcaTransform(DoubleMatrix2D matrix) {
            DoubleMatrix2D zScoresMatrix = toZScores(matrix);
            final DoubleMatrix2D covarianceMatrix = Statistic.covariance(zScoresMatrix);

            // compute eigenvalues and eigenvectors of the covariance matrix (flip needed since it is sorted by ascending).
            final EigenvalueDecomposition decomp = new EigenvalueDecomposition(covarianceMatrix);

            // Columns of Vs are eigenvectors = principal components = base of the new space; ordered by decreasing variance
            final DoubleMatrix2D Vs = decomp.getV().viewColumnFlip(); 

            // eigenvalues: ev(i) / sum(ev) is the percentage of variance captured by i-th column of Vs
            // final DoubleMatrix1D ev = decomp.getRealEigenvalues().viewFlip();

            // project the original matrix to the pca space
            return Algebra.DEFAULT.mult(zScoresMatrix, Vs);
        }


        /**
         * Converts matrix to a matrix of z-scores (by columns)
         */
        public static DoubleMatrix2D toZScores(final DoubleMatrix2D matrix) {
            final DoubleMatrix2D zMatrix = new SparseDoubleMatrix2D(matrix.rows(), matrix.columns());
            for (int c = 0; c < matrix.columns(); c++) {
                final DoubleMatrix1D column = matrix.viewColumn(c);
                final DynamicBin1D bin = Statistic.bin(column);

                if (bin.standardDeviation() == 0) {   // use epsilon
                    for (int r = 0; r < matrix.rows(); r++) {
                        zMatrix.set(r, c, 0.0);
                    }
                } else {
                    for (int r = 0; r < matrix.rows(); r++) {
                        double zScore = (column.get(r) - bin.mean()) / bin.standardDeviation();
                        zMatrix.set(r, c, zScore);
                    }
                }
            }

            return zMatrix;
        }
    }

你也可以使用weka。我会首先将您的数据加载到 weka,然后使用 GUI(在属性选择下)运行 PCA。您将看到使用哪些参数调用了哪些类,然后从您的代码中执行相同的操作。问题是您需要将矩阵转换/包装成 weka 使用的数据格式。

于 2013-06-29T18:49:37.943 回答
0

CrossValidated 2上讨论了一个类似的问题。基本思想是找到一个合适的投影来分离这些集群(例如,用discprojin R),然后在新空间上绘制集群上的投影。

于 2013-06-29T18:17:24.480 回答
0

除了其他答案建议您可能还应该看看多维缩放

于 2013-06-29T18:51:40.570 回答