Canopy一般用在Kmeans之前的粗聚類。考慮到Kmeans在使用上必須要確定K的大小,而往往數據集預先不能確定K的值大小的,這樣如果 K取的不合理會帶來K均值的誤差很大(也就是說K均值對噪聲的抗干擾能力較差)。總之基於以下三種原因,選擇利用Canopy聚類做為Kmeans的前奏 比較科學、也是Canopy的優點。
一、canopy算法的優缺點
Canopy的優點:
1、Kmeans對噪聲抗干擾較弱,通過Canopy對比較小的NumPoint的Cluster直接去掉 有利於抗干擾。
2、Canopy選擇出來的每個Canopy的centerPoint作為Kmeans比較科學。
3、只是針對每個Canopy的內容做Kmeans聚類,減少相似計算的數量。
Canopy的缺點:算法中 T1、T2(T2 < T1) 的確定問題 (在並行計算上Maper的T1、T2 可以和Raduce的T1、T2不同)
二、canopy聚類過程
while D is not empty
select element d from D to initialize canopy c
remove d from D
Loop through remaining elements in D
if distance between d_i and c < T1 : add element to the canopy c
if distance between d_i and c < T2 : remove element from D
end
add canopy c to the list of canopies C
end
當距離小於T1大於T2時,這些點會被歸入到該中心所在的canopy中,但是它們並不會從D中被移除,也就是說,它們將會參與到下一輪的聚類過程中,成為新的canopy類的中心或者成員。亦即,兩個Canopy類中有些成員是重疊的。
三、公式推導
Canopy的關鍵是以下公式:
S0 表示Canopy包含點的權重之和
S1 表示各點的加權和
S2 表示各點平方的加權和
聚類分析的抽象是計算: NumPoint、Radius、Center、(其中 Radius、Center 均是N維向量)
計算公式推導如下:
NumPoint = S0
Center = S1/S0
Radius = Sqrt(S2*S0-S1*S1)/S0
推導過程如下:
public void computeParameters();
#根據s0、s1、s2計算numPoints、center和Radius,
其中numPoints=(int)s0,
center=s1/s0,
Radius=sqrt(s2*s0-s1*s1)/s0
簡單點來,假設所有點權重都是1,
,其中
,其中
四、參數調整
當T1過大時,會使許多點屬於多個Canopy,可能會造成各個簇的中心點間距離較近,各簇間區別不明顯;
當T2過大時,增加強標記數據點的數量,會減少簇個個數;T2過小,會增加簇的個數,同時增加計算時間
另外:mahout提供了幾種常見距離計算的實現 ,均實現org.apache.mahout.common.distance.DistanceMeasure接口
CosineDistanceMeasure:計算兩向量間的夾角
SquaredEuclideanDistanceMeasure:計算歐式距離的平方
EuclideanDistanceMeasure:計算歐式距離
ManhattanDistanceMeasure:馬氏距離,貌似圖像處理中用得比較多
TanimotoDistanceMeasure:Jaccard相似度,T(a, b) = a.b / (|a|^2 + |b|^2 - a.b)
以及帶權重的歐式距離和馬氏距離。
需要注意:
1. 首先是輕量距離量度的選擇,是選擇數據模型其中的一個屬性,還是其它外部屬性這對canopy的分布最為重要。
2. T1, T2的取值影響到canopy重疊率f,以及canopy的粒度。
3. Canopy有消除孤立點的作用,而K-means在這方面卻無能為力。建立canopies之后,可以刪除那些包含數據點數目較少的canopy,往往這些canopy是包含孤立點的。
4. 根據canopy內點的數目,來決定聚類中心數目k,這樣效果比較好
五、算法實現
單機版Canopy算法:
1、從PointList中取一個Point ,尋找已經建立好的Canopy 計算這個點於所有的Canopy的距離。如果和某一個Canopy的距離小於T1, 則把這個點加到Canopy中,如果沒有Canopy則選擇這個點為一個Canopy的中心。
2、如果這個店Point和某個Canopy的距離小於T2,則把這個點從PointList中刪除(這個點以后做不了其他的Canopy的中心了)。
3、循環直到所有的Point都被加入進來,然后計算各個Canopy的Center和Radius。
模型MapReduce版本:
1、把數據整理成SequcnceFile格式(Mahout-InputMapper)作為初始化文件PointFile
2、CanopyMapper階段本機聚成小的Canopy 中間文件寫成SequenceFile 這一步的T1、T2 和Reduce的T1、T2可以是不同的( index、Canpy)
3、所有的Mapper階段的輸出到1個Reducer中 然后Reduce把Map階段中的Center點再次做聚類算法。聚出全局的Canopy。同時計算每個Canopy的CenterPoint點。寫到臨時文件CenterPoint中。
4、針對全集合PointFile在CenterPoint上的findClosestCanopy操作(通過傳入的距離算法)。然后輸出一個SequenceFile。
六、問題總結
有2個問題不知道如何答案:
1、T1、T2 的選擇(我需要采樣計算出嗎?)
2、如何和Kmeans結合?(只在Canopy內做K均值是什么意思呢?)
Reference:
http://trailblizer.blog.163.com/blog/static/59630364201141973937341/
http://www.shahuwang.com/2012/08/14/canopy%E8%81%9A%E7%B1%BB%E7%AE%97%E6%B3%95.html