我必须为我的最后一年项目做的概念验证原型是在大数据集上实施 K-Means聚类并在图表上显示结果。我只知道像Java和C#这样的面向对象语言,并决定试试MATLAB。我注意到使用函数式语言解决问题的方法是非常不同的,所以如果可能的话,我想对一些事情有所了解。
假设我有以下数据集:
raw_data
400.39 513.29 499.99 466.62 396.67
234.78 231.92 215.82 203.93 290.43
15.07 14.08 12.27 13.21 13.15
334.02 328.79 272.2 306.99 347.79
49.88 52.2 66.35 47.69 47.86
732.88 744.62 687.53 699.63 694.98
我选择第2行和第4行作为2个质心:
质心
234.78 231.92 215.82 203.93 290.43 % Centroid 1
334.02 328.79 272.2 306.99 347.79 % Centroid 2
我想现在计算每个点到每个质心的欧氏距离,然后将每个点分配给它最近的质心并在图形上显示。让我们说我想要将质心分类为蓝色和绿色。我怎样才能在MATLAB中做到这一点?如果这是Java,我会将每一行初始化为一个对象,并添加到单独的ArrayLists(代表集群)。
如果第1,2和3行都属于第一个质心/簇,第4,5和6行属于第二个质心/簇 - 我怎样才能将它们分类为在图形上显示为蓝色或绿色点?我是MATLAB的新手,对此非常好奇。谢谢你的帮助。
答案 0 :(得分:1)
(首先,Matlab具有灵活的距离测量功能,#define SLICES 10000
/*
* Computes the integral of min(f, g) on [a, b].
*
* Intended use is for when f and g are both non-negative, real-valued
* functions of one variable.
*
* That is, f: R -> R and g: R -> R.
*
* Assumes b ≥ a.
*
* @param a left boundary of interval to integrate over
* @param b right boundary of interval to integrate over
* @param f function accepting one double argument which returns a double
* @param g function accepting one double argument which returns a double
* @return integral of min(f, g) on [a, b]
*/
double minIntegrate (double a, double b, double (*f)(double), double (*g)(double)) {
double area = 0.0;
// the height of each trapezoid
double deltaX = (b - a) / SLICES;
/*
* We are integrating by partitioning the interval into SLICES pieces, then
* adding the areas of the trapezoids formed to our running total.
* To save a computation, we can cache the last side encountered.
* That is, let lastSide be the minimum of f(x) and g(x), where x was the
* previous "fence post" (side of the trapezoid) encountered.
* Initialize lastSide with the minimum of f and g at the left boundary.
*/
double lastSide = min(f(a), g(a));
// The loop starts at 1 since we already have the last (trapezoid) side
// for the 0th fencepost.
for (int i = 1; i <= SLICES; i++) {
double fencePost = a + (i * deltaX);
double currentSide = min(f(fencePost), g(fencePost));
area += trapezoid(lastSide, currentSide, deltaX);
lastSide = currentSide;
}
return area;
}
/*
* Computes the area of a trapezoid with bases `a` and `b` and height `height`.
*/
double trapezoid (double a, double b, double height) {
return h * (a + b) / 2.0;
}
以及pdist2
实现,但我假设您想从头开始构建代码。
在Matlab中,您尝试将所有内容都实现为矩阵代数,而不是在元素上进行循环。
在您的情况下,如果R是raw_data矩阵而C是质心矩阵,
您可以将表示质心数的维度移到第3位
kmeans
;然后,permC=permute(C,[3 2 1])
函数允许您从R中减去C,同时根据需要展开R的第三维:bsxfun
。元素方形,然后在列D=bsxfun(@minus,R,permC)
之间进行求和,将为您提供每个质心的每个观测值的平方距离。在单个语句中执行所有这些操作并将第三个(质心)维度移回第二个位置将如下所示:
SqD=sum(D.^2,2)
挑选最小距离的质心现在很简单:SqD=permute(sum(bsxfun(@minus,R,permute(C,[3 2 1])).^2,2),[1 3 2])
如果这看起来很复杂,我建议检查每个子步骤的产品并阅读每个命令的帮助。