前面有文章提到过,K-means算法,第一步骤是找出样本点的的所属聚类。下面用两种方式实现,一种是普通的循环,一种是完全向量化计算。
假设 :
X 是m×n样本矩阵,其每一行是一个样本,m表示样本数目,n表示特征数目;
centroids是K×n矩阵,K表示聚类数目,n表示特征数目,每一行是一个聚类的中心。
idx是m×1矩阵,idx(i) 表示第i个样本所属的聚类下标。(取值范围 1..K )
半循环半向量化方式 实现:
思想:循环遍历每一个样本点,计算每一个样本点距离K个聚类中心的值,并取最小值的那个聚类下标
for i = 1 : size(X, 1) dif = bsxfun(@minus, X(i, :), centroids); [w, iw] = min(sum(dif .* dif, 2)); idx(i, :) = iw; endfor
完全向量化式 实现:
思想: 首先,构造两个m×n×K矩阵, 第一个矩阵为样本点的值,第二个矩阵为聚类中心值;
然后,计算样本点距离聚类中心的值,并找到最小值的那个聚类下标。
X_ext = bsxfun(@plus, X, zeros([size(X), K])); centroids_ext = permute(centroids, [3, 2, 1]); dif_ext = bsxfun(@minus, X_ext, centroids_ext); [~, ix] = min(sum(dif_ext .* dif_ext, 2), [], 3); idx = ix;
跟上面那个半循环半向量的实现方式相比,这个完全向量化代码即很难看懂,也没有更简洁。速度效率也不知道也不会更快。奇巧淫技。