我正在12维矩阵上进行KMean聚类。我设法在K集群中得到结果。我想通过将其绘制成2D图来显示结果,但我无法弄清楚如何将12维数据转换为2维。
有关如何进行转换或任何可视化结果的替代方法的建议?我试过了Multidimensional Scaling for Java (MDSJ),但它没有用。
我使用的KMean算法来自Java Machine Learning Library: Clustering basics。
答案 0 :(得分:1)
我会做Principal Component Analysis(可能是Multidimensional scaling算法中最简单的算法)。 (BTW PCA与KMeans无关,它是降维的一般方法)
我假设变量在列中,观察在行中。
标准化数据 - 将变量转换为z分数。这意味着:从每个单元格中减去列的平均值,并将结果除以std。列的偏差。这样你就可以获得零均值和单位方差。前者是强制性的,后者,我会说,很好。如果方差为零,则从协方差矩阵计算特征向量,否则必须使用哪种自动标准化数据的相关矩阵。见this for explanation)。
计算协方差矩阵的特征向量和特征值。通过特征值对特征向量进行排序。 (许多图书馆已经为你提供了那种方式排序的特征向量)。
使用特征向量矩阵的前两列并乘以原始矩阵(转换为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使用的数据格式。
答案 1 :(得分:0)
CrossValidated 2讨论了一个类似的问题。基本思想是找到一个适当的投影来分隔这些聚类(例如,discproj
中的R
),然后绘制新空间上聚类的投影。
答案 2 :(得分:0)
除了其他答案所暗示的,你也应该看一下multidimensional scaling。