将模板方法模式应用到kmeans聚类算法
生活随笔
收集整理的這篇文章主要介紹了
将模板方法模式应用到kmeans聚类算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README
0.1)本文描述和源代碼均為原創,旨在說明 如何將模板方法模式應用到kmean聚類算法;
0.2)模板方法模式的intro, 參見 ?模板方法模式
0.3)for kmeans alg source code, please visit ?kmeans&templateMethodPattern
【1】intro to kmeans
1.1)準備工作:隨機初始化聚類質心(隨機更新質心),讀取數據等;
1.2)核心算法:
for i in round
step1)為每個樣本item分配質心;
step2)更新質心;
step3)打印每輪聚類結果(可選)或重定向到 持久化文件;
public final void cluster() {// 聚類方法randomRefineInitialCentroid(); // 隨機初始化聚類質心for (int i = 0; i < ClusterParam.clusterExeTimes; i++) {Arrays.fill(ClusterData.clusterMemberNum, 0); // 清空聚類成員個數記錄for (int j = 0; j < ClusterData.rowno; j++){ ClusterData.rownoWithClusterid[j] = assign(j);}clearDoubleArray(ClusterData.centroid); // 清空質心refine();PrintResult.print(i+1);}}
【2】將模板方法模式應用到kmean聚類算法
2.1)intro to 模板方法模式: 一句話說完,模板方法模式就是為 封裝算法而生的,主要是在基類 先對 算法的steps 給出 outline, 然后 抽取各個子類的共同 steps 到 基類進行具體實現,其他的都抽象為抽象方法 有子類實現;這樣一來,整個alg 的 steps 無比清晰,且易于擴展,特別是對于學術型alg,有很多變體算法,如基于kmeans的 聚類算法就有很多;
2.2) kmeans 聚類算法基類和子類
package com.research.alg2;import static java.lang.System.out;import java.util.Arrays;import com.research.io2.PrintResult; import com.research.pojo2.ClusterData; import com.research.pojo2.ClusterParam;public abstract class ClusterAlg {public static String algName;abstract int assign(int index); // 為 第 index 個item 分配質心,返回結果是質心編號indexabstract void refine();// 精煉質心public final void cluster() {// 聚類方法randomRefineInitialCentroid(); // 隨機初始化聚類質心for (int i = 0; i < ClusterParam.clusterExeTimes; i++) {Arrays.fill(ClusterData.clusterMemberNum, 0); // 清空聚類成員個數記錄for (int j = 0; j < ClusterData.rowno; j++){ ClusterData.rownoWithClusterid[j] = assign(j);}clearDoubleArray(ClusterData.centroid); // 清空質心refine();PrintResult.print(i+1);}}// reset centroid array zerosfinal void clearIntArray(int[][] data) {for (int i = 0; i < data.length; i++)Arrays.fill(data[i], 0);}// reset centroid array zerosfinal void clearDoubleArray(double[][] data) {for (int i = 0; i < data.length; i++)Arrays.fill(data[i], 0);}// randomly update or refine init centroidsfinal void randomRefineInitialCentroid() {int[] initCentorid = generateRandom(ClusterData.rowno, ClusterParam.clusterNum);System.out.println("==== init centroids are as follows:");for (int i = 0; i < initCentorid.length; i++){ClusterData.centroid[i] = ClusterData.items[initCentorid[i]].clone();out.printf("%-8s", "item" + initCentorid[i]);}out.printf("\n============================================================================\n");}/*** fabricate random array* @param volumn , random number upper limit* @param interval , interval number and there is a random number in every interval* @return a random array*/final int[] generateRandom(int volume, int interval) {int[] r_data = new int[interval];int intervalVolume = volume / interval;for (int i = 0; i < interval; i++) {int r = (int) (Math.random() * intervalVolume);r_data[i] = r + intervalVolume * i;}// r_data[0] = 1; // r_data[1] = 101; // r_data[2] = 301; // r_data[3] = 501; // r_data[4] = 701; // r_data[5] = 901;return r_data;} } package com.research.alg2;import static java.lang.Math.pow;import com.research.pojo2.ClusterData; import com.research.pojo2.ClusterParam;public class KmeansAlg extends ClusterAlg {/*** compute the centroid the item should be assigned to* @param index refers to item index* @return cluster id whose has the smallest distance between centroid and* the item*/@Overrideint assign(int index) {double sum = 0;double miniSum = 0;int miniIndex = 0;double[] item = ClusterData.items[index];for (int i = 0; i < ClusterData.dimension; i++)sum += pow(item[i] - ClusterData.centroid[0][i], 2.0);miniSum = sum;for (int i = 1; i < ClusterParam.clusterNum; i++) {sum = 0;for (int j = 0; j < ClusterData.dimension; j++)sum += Math.pow(item[j] - ClusterData.centroid[i][j], 2.0);if (miniSum > sum) {miniSum = sum;miniIndex = i;}}ClusterData.clusterMemberNum[miniIndex]++;return miniIndex;}@Overridevoid refine() {int clusterId;for (int i = 0; i < ClusterData.rowno; i++) {clusterId = ClusterData.rownoWithClusterid[i];for (int j = 0; j < ClusterData.dimension; j++)ClusterData.centroid[clusterId][j] += ClusterData.items[i][j];}// update centroids(refinement procedure)for (int i = 0; i < ClusterParam.clusterNum; i++)for (int j = 0; j < ClusterData.dimension; j++)ClusterData.centroid[i][j] /= ClusterData.clusterMemberNum[i];} }
總結
以上是生活随笔為你收集整理的将模板方法模式应用到kmeans聚类算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抗ddos产品报表不支持怎么办(抗DDO
- 下一篇: 单件模式(单例模式)