【hadoop】大規模中文網站聚類kmeans的mapreduce實現(下)

         接上一篇,上一篇主要是計算tfidf,下篇主要是文檔向量的建立以及kmeas的實現。

四 網頁向量以及初始中心點選取

        網頁向量以及初始中心點的選取在 DocumentVetorBuid 中的一個 Mapreduce 中完成,中間過程如下表所示。

        輸出類似如下:
16  26272:0.00587873/22456:0.00264058/22502:0.00289516/23702:0.00278015/

五 Kmeans 聚類實現

     DocTool 功能簡介

       爲了簡化 Kmeans 過程中的代碼,將計算網頁向量與中心點向量之間的餘弦距離,並根據最大的餘弦距離判斷網頁屬於哪一類的方法抽象出來, Kmeans 的迭代過程中可以直接在調用,簡化了 Kmeans 主類的代碼複雜度。
        其中,DocTool類中主要方法爲:
        public static int returnNearestCentNum(Map<Long, Double> doc,Map<Integer, Map<Long, Double>> centers, long dictSize)
       輸入:doc 指代網頁向量,centers 指代所有的中心點向量的集合,dictSize 指代詞表中詞的總數。

       輸出:網頁所歸屬的中心點編號。

      詳細請見github代碼https://github.com/shenguojun/hadoop/blob/master/WebKmeans/src/edu/sysu/shen/hadoop/DocTool.java

      Kmeans 主要 Mapreduce 介紹

       Kmeans 主類由兩個 Mapreduce 組成,一個是在迭代過程中更新中心點,一個是生成最後的結果,這兩個 Mapreduce 的 Mapper 和 Rducer 的詳細說明如下面兩表所示。

       輸出類似如下:
16   26272:0.00587873/22456:0.00264058/22502:0.00289516/23702:0.00278015/
      上述的 Mapreduce 是在迭代過程的進行的,輸入的是網頁向量,並藉助中心點向量通過計算後得到新的中心點向量作爲輸出。在迭代完畢後,需要最後一個 Mapreduce 輸出符合格式的最終文件。最後一個 Mapreduce 詳細說明如下表。

      輸出類似如下:
2977  34
2978  46
2979  36
2980  34
2981  34
2982  34
2983  34

      KmeansDriver 流程

     KmeansDriver 負責控制所有 MapduceJob 的執行流程,以及建立 configuration 傳入每個Mapreduce 所需要的參數。
控制流程如第一部分的實現流程圖所示。其中較爲關鍵是 Kmeans過程中的迭代過程,在迭代過程中由兩個因素控制循環的結束,一個是輸入參數中的最大迭代次數,當達到最大迭代次數後循環就會結束。另一個是判斷新生成的中心點與就的中心點是否相等,如果相等的話就會提前結束,在實驗中,設置 20 箇中心點,平均在迭代 10 次左右就會達到收斂條件。
     其中判斷中心點是否收斂的代碼如下。
     詳細代碼請見https://github.com/shenguojun/hadoop/blob/master/WebKmeans/src/edu/sysu/shen/hadoop/KmeansDriver.java
//計算是否提前結束
StringBuilder oldCentroid = new StringBuilder();
StringBuilder newCentroid = new StringBuilder();
Path oldCenPath = new Path(tmpPath + "/clustering/depth_"+ (iteration - 1) + "/part-r-00000");
SequenceFile.Reader oldReader = new Reader(fs5, oldCenPath, conf);
IntWritable key = new IntWritable();
Text value = new Text();
//得到舊的中心點向量
while (oldReader.next(key, value)) {
   oldCentroid.append(key.toString() + value.toString());
}
oldReader.close();
Path newCenPath = new Path(tmpPath + "/clustering/depth_"+ (iteration) + "/part-r-00000");
SequenceFile.Reader newReader = new Reader(fs5, newCenPath, conf);
IntWritable key1 = new IntWritable();
Text value1 = new Text();
//得到新的中心點向量
while (newReader.next(key1, value1)) {
   newCentroid.append(key1.toString() + value1.toString());
}
newReader.close();
iteration++;
//如果聚類中心不變,提前結束迭代
if (newCentroid.toString().equals(oldCentroid.toString()))
   break;

六 運行結果

實驗中僞分佈方式對一萬個網站進行聚類,設置 50 箇中心點,執行 5 次迭代,得到運行時間如下表。實驗成功輸出了每個網頁所屬的聚類編號。需要進一步處理的地方是建立網頁向量時維度很大,容易造成維數災難,進一步需要考慮如何降低維數。

七 參考

書籍:

《大數據:互聯網大規模數據挖掘與分佈式處理》
《Mahout in Action》
《Hadoop in Action》
《Hadoop: The Definitive Guide》

論文:

Weizhong Zhao, Huifang Ma, Qing He.Parallel K-Means Clustering Based on MapReduce .2009
Jiang Xiaoping, Li Chenghua, Xiang Wen, Zhang Xinfang, Yan Haitao.k-means 聚 類 算 法 的
MapReduce 並行化實現

網站:

http://codingwiththomas.blogspot.com/2011/05/k-means-clustering-with-mapreduce.html
https://github.com/thomasjungblut/thomasjungblut-common/tree/master/src/de/jungblut/clustering
/mapreduce
http://code.google.com/p/hadoop-clusternet/wiki/RunningMapReduceExampleTFIDF
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章