以前做項目時候?qū)懙拇a,數(shù)據(jù)是一維的,多維的也一樣,把距離計算的改一改就行int?term?=?Math.abs(dotlist.get(centerIndex[j]).x-?dotlist.get(i).x);
創(chuàng)新互聯(lián)建站是一家專業(yè)提供濱州企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計、成都網(wǎng)站設(shè)計、H5頁面制作、小程序制作等業(yè)務(wù)。10年已為濱州眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進行中。
[java]?view?plaincopy
package?uestc.dmlab.call;??
import?java.io.BufferedReader;??
import?java.io.FileReader;??
import?java.security.KeyStore.Entry;??
import?java.util.HashMap;??
import?java.util.HashSet;??
import?java.util.Iterator;??
import?java.util.LinkedList;??
import?java.util.List;??
import?java.util.Map;??
import?java.util.Random;??
import?java.util.Set;??
public?class?Clustering?{??
/**?
*??
*?@param?fileName?
*????????????文件中每個字段對應(yīng)一個概率?
*?@param?k?
*????????????聚成k個類?
*?@param?minDistance?
*????????????聚類中心位移小于minDistance時停止迭代?
*?@return?
*/??
public?static?HashMapString,?Integer?cluster(String?fileName,?int?k,??
int?minDistance)?{??
try?{??
BufferedReader?br?=?new?BufferedReader(new?FileReader(fileName));??
ListDot?dotlist?=?new?LinkedListDot();??
String?line;??
int?count?=?0;//?行數(shù)??
while?((line?=?br.readLine())?!=?null)?{??
String?s[]?=?line.split(",");??
Dot?dot?=?new?Dot();??
dot.isCenter?=?false;??
dot.isVirtual?=?false;??
dot.name?=?s[0];??
//?if(s.length4){??
//?System.out.println(line);??
//?}??
dot.x?=?Integer.parseInt(s[3]);??
dotlist.add(dot);??
count++;??
}??
if?(count??k)?{??
k?=?count;??
}??
//?隨機初始化k個聚類中心??
int?centerIndex[]?=?new?int[k];?//?存儲k個中心點在dotlist中的索引??
int?centerNum?=?k;??
while?(centerNum??0)?{??
int?index?=?new?Random().nextInt(count);??
if?(!dotlist.get(index).isCenter)?{??
centerNum--;??
dotlist.get(index).isCenter?=?true;??
centerIndex[centerNum]?=?index;??
}??
}??
//?K個聚類??
Cluster[]?clusers?=?new?Cluster[k];??
boolean?flag?=?true;??
while?(flag)?{??
flag?=?false;??
clusers?=?new?Cluster[k];??
for?(int?i?=?0;?i??clusers.length;?i++)?{??
clusers[i]?=?new?Cluster();??
}??
//System.out.println(clusers.length);??
//?找到離第i個點最近的聚類中心??
for?(int?i?=?0;?i??dotlist.size();?i++)?{??
//?該點不是中心點也不是虛擬點就計算它與所有中心點的距離并取最小值??
//?if(!dotlist.get(i).isCenter!dotlist.get(i).isVirtual){??
if?(!dotlist.get(i).isVirtual)?{??
int?distance?=?Integer.MAX_VALUE;??
int?c?=?0;//?記錄離該節(jié)點最近的中心點的索引??
for?(int?j?=?0;?j??k;?j++)?{??
int?term?=?Math.abs(dotlist.get(centerIndex[j]).x??
-?dotlist.get(i).x);??
if?(distance??term)?{??
distance?=?term;??
c?=?j;??
}??
}??
clusers[c].dots.add(i);??
}??
}??
//?重新計算聚類中心??
for?(int?i?=?0;?i??k;?i++)?{??
Cluster?cluster?=?clusers[i];??
if?(cluster.dots.size()??0)?{?//若該類中有點??
int?sum?=?0;??
for?(int?j?=?0;?j??cluster.dots.size();?j++)?{??
sum?+=?dotlist.get(cluster.dots.get(j)).x;??
}??
Dot?dot?=?new?Dot();??
dot.x?=?sum?/?cluster.dots.size();??
dot.isCenter?=?true;??
dot.isVirtual?=?true;??
//?新舊聚類中心的距離??
int?term?=?Math.abs(dotlist.get(centerIndex[i]).x??
-?dot.x);??
if?(term??minDistance)??
flag?=?true;??
dotlist.add(dot);??
centerIndex[i]?=?dotlist.indexOf(dot);?//?第i個聚類的中心改變??
}??
}??
}??
//?生成分類映射??
HashMapString,?Integer?map?=?new?HashMapString,?Integer();??
for?(Dot?dot?:?dotlist)?{??
if?(dot.isVirtual?==?false)?{??
int?className?=?-1;??
for?(int?i?=?0;?i??k;?i++)?{??
if?(clusers[i].dots.contains(dotlist.indexOf(dot)))??
className?=?i;??
}??
map.put(dot.name,?className);??
}??
}??
return?map;??
}?catch?(Exception?e)?{??
e.printStackTrace();??
}??
return?new?HashMapString,?Integer();??
}??
public?static?void?main(String[]?args)?{??
MapString,?Integer?map?=?Clustering.cluster(??
"C:/Documents?and?Settings/Administrator/桌面/123.txt",?2,?0);??
IteratorMap.EntryString,?Integer?it?=?map.entrySet().iterator();??
while(it.hasNext()){??
Map.EntryString,?Integer?entry?=?it.next();??
System.out.println(entry.getKey()+","+entry.getValue());??
}??
}??
}??
class?Dot?{??
String?name;??
int?x;??
boolean?isCenter;??
boolean?isVirtual;??
}??
class?Cluster?{??
//?記錄了該類中點的索引值??
LinkedListInteger?dots?=?new?LinkedListInteger();
ClusterEvaluation eval = new ClusterEvaluation();
eval.setClusterer(KM);
eval.evaluateClusterer(ins);
//**這句獲得了每條記錄所屬的clusterer
**/
double[] cnum = cl.getClusterAssignments();
k個聚類以便使得所獲得的聚類滿足:同一聚類中的對象相似度較高;而不同聚類 算法實現(xiàn)起來應(yīng)該很容易,就不幫你編寫代碼了。
K-MEANS算法:
k-means 算法接受輸入量 k ;然后將n個數(shù)據(jù)對象劃分為 k個聚類以便使得所獲得的聚類滿足:同一聚類中的對象相似度較高;而不同聚類中的對象相似度較小。聚類相似度是利用各聚類中對象的均值所獲得一個“中心對象”(引力中心)來進行計算的。
k-means 算法的工作過程說明如下:首先從n個數(shù)據(jù)對象任意選擇 k 個對象作為初始聚類中心;而對于所剩下其它對象,則根據(jù)它們與這些聚類中心的相似度(距離),分別將它們分配給與其最相似的(聚類中心所代表的)聚類;然后再計算每個所獲新聚類的聚類中心(該聚類中所有對象的均值);不斷重復(fù)這一過程直到標準測度函數(shù)開始收斂為止。一般都采用均方差作為標準測度函數(shù). k個聚類具有以下特點:各聚類本身盡可能的緊湊,而各聚類之間盡可能的分開。
具體如下:
輸入:k, data[n];
(1) 選擇k個初始中心點,例如c[0]=data[0],…c[k-1]=data[k-1];
(2) 對于data[0]….data[n], 分別與c[0]…c[n-1]比較,假定與c[i]差值最少,就標記為i;
(3) 對于所有標記為i點,重新計算c[i]=/標記為i的個數(shù);
(4) 重復(fù)(2)(3),直到所有c[i]值的變化小于給定閾值。
算法實現(xiàn)起來應(yīng)該很容易,就不幫你編寫代碼了。
第一次迭代下,除了a4點,其他點都歸為一類c1:(a1 a2 a3 a5);c2:(a4) 聚類中心:c1:(2,2);c2(5,4)(聚類中心的計算方式是平均類中所有點)
第二次迭代下,c1(a1 a2 a5);c2(a3 a4) 聚類中心c1:(4/3,5/3);c2(9/2 7/2)
第三次迭代下,c1(a1 a2 a5);c2(a3 a4) 聚類中心c1:(4/3,5/3);c2(9/2 7/2)結(jié)果已經(jīng)穩(wěn)定跳出循環(huán)
這得分詞+vsm+k-means啊。k-means算法網(wǎng)上應(yīng)該不少,但是對文檔的話,還得進行分詞,構(gòu)建矢量空間模型才能進行聚類啊。