Mahout canopy聚類
Canopy 聚類
一、Canopy算法流程
Canopy 算法,流程簡單,easy實現,一下是算法
(1)設樣本集合為S,確定兩個閾值t1和t2。且t1>t2。
(2)任取一個樣本點p,作為一個Canopy,記為C,從S中移除p。
(3)計算S中全部點到p的距離dist
(4)若dist<t1。則將對應點歸到C,作為弱關聯。
(5)若dist<t2。則將對應點移出S,作為強關聯。
(6)反復(2)~(5),直至S為空。
上面的過程能夠看出。dist<t2的點屬於有且僅有一個簇,t2<dist<t1 的點可能屬於多個簇。可見Canopy是一種軟聚類。
數據集合劃分完後:
Canopy有消除孤立點的作用,而K-means在這方面卻無能為力。建立canopies之後,能夠刪除那些包括數據點數目較少的canopy。往往這些canopy是包括孤立點的。依據canopy內點的數目,來決定聚類中心數目k,這樣效果比較好。
當T1過大時,會使很多點屬於多個Canopy,可能會造成各個簇的中心點間距離較近,各簇間差別不明顯;當T2過大時。增加強標記數據點的數量,會降低簇個個數;T2過小,會增加簇的個數。同一時候增加計算時間。
二、MapReduce實現
在運行Canopy之前須要用將文本合並,然後用Mahout文本向量化模塊計算TFIDF,作為文本向量。向量化之後再用Canopy算法聚類。
(一)簇定義
簇Cluster是一個實體,保存該簇的關鍵信息,canopy 就是一個cluster。
privateint id; 簇編號
核心參數:計算完數據後終於的簇屬性
private long numPoints; 簇中點的個數
private Vector center; 中心向量 center=
private Vector radius; 半徑向量 radius =
調整參數:簇中增加一個點後調整的參數
private double s0; s0= 權重和。對於canopy,w=1 ,全部s0=numPoints
private Vector s1; s1= x
為
private Vector s2 ; s2= x 為point。w為權重。對canopyw =1
(二)發現中心點
該Job 通過多個Map 尋找局部Canopy ,用1個reduce將map計算的canopy合並,終於輸出全局的中心。
輸入數據:SequenceFile 格式。key 文件路徑。value TFIDF向量。
Map: key 文件路徑 , value TFIDF 向量
Collection<Canopy> canopies = new ArrayList<Canopy>()
Map(WritableComparable<?> key, VectorWritable point){
CanopyClusterer 將Point 增加到canopies 集合中。增加集合的過程中計算T1,T2.增加到對應的Canopy中。
}
Close(){
遍歷canopies 集合,計算每個Canopy的中心點。
For(canopy :canopies){
計算每個Canopy的中心點。
輸出 key :Text(“centroid”)value: Canopy中心點向量。
}
}
Reduce:key Text(“centroid”) value VectorWritable
用1個reduce 將全部map 計算的canopy 中心合並。
Reduce中運行的代碼和map的一樣。
終於輸出canopy 。
For(canopy c :canopys ){
輸出:key c.getIdentifier() 。Value c
}
(三)劃分數據
通過上一步找到中心點後,劃分數據的過程就比較easy了。輸入數據為向量化後的TFIDF向量。該過程僅僅需用Map 即可。
輸入格式:key 文檔路徑 value TFIDF向量
Map:
Collection<Canopy>canopies = new ArrayList<Canopy>()
Map(WritableComparable<?
> key, VectorWritable point){
計算point 和全部中心點的距離。將其劃分到距離近期的canopy中
CanopyClusterer.emitPointToClosestCanopy(point,canopyes)
輸出 key: canopyid 。value:point
}
setup(){
讀Canopy ,到 canopies
}
三、API說明
API
CanopyDriver.main(args); |
|
--input (-i) |
輸入路徑 |
--output(-o) |
輸出路徑 |
--distanceMeasure(-dm) |
距離度量類的權限命名。如:”org.apache.mahout.common.distance.CosineDistanceMeasure” |
--t1 (-t1) |
t1值 (t1>t2) |
--t2 (-t2) |
t2值 |
--t3 (-t3) |
t3值,默認t3=t1 |
--t4(-t4) |
t4值。默認t4=t2 |
--overwrite (-ow) |
是否覆蓋上次操作的結果 |
--clustering (-cl) |
是否運行聚類操作。即劃分數據 |
--method (-method) |
默認,mapreduce。 還可選sequential,運行單機模式 |
演示樣例
String [] args ={“--input”,“vector/tfidf-vectors”, “--output”, “cluster/canopy”, “--method”, “mapreduce”, “--distanceMeasure”, “org.apache.mahout.common.distance .CosineDistanceMeasure”, “--t1”, “0.45”, “--t2”, 0.38”, “--overwrite”, “--clustering”} CanopyDriver.main(args); |
輸出
結果文件 |
Key類型 |
Value類型 |
說明 |
clusters-* |
類id (org.apache.hadoop.io.Text) |
類中心 (org.apache.mahout. clustering.kmeans.Cluster) |
每條記錄以類id和類中心表示一個類別 |
clusteredPoints |
類id (org.apache.hadoop.io.IntWritable) |
文檔向量 (org.apache. mahout.clustering.WeightedVectorWritable) |
每條記錄中,文檔向量代表文檔。類id代表該文檔所屬類別 |
註:clusters-*中*代表數字。第i次叠代產生的類信息即為clusters-i
四、參考文獻
Mahout canopy聚類