聚類--(摘自西瓜書)


一、聚類性能度量

通常我們希望聚類結果的“簇內相似度”(intra-cluster similarity)高且“簇間相似度”(inter-cluster similarity)低。聚類性能度量大致有兩類:一類是將聚類結果與某個“參考模型”(reference model)進行比較,稱為“外部指標”(external index);另一類是直接考查聚類結果而不利用任何參考模型。稱為“內部指標”(internal index)

外部指標

假定C是聚類給出的簇划分,C*是參考模型給出的簇划分,$\lambda$ 與 $\lambda^*$分別表示C和C*對應的簇標記向量。

基於上式導出常用的聚類性能度量外部指標:

 1. Jaccard系數(Jaccard Coefficient,JC)


2. FM指數(Fowlkes and Mallows Index,FMI)


3. Rand指數(Rand Index,RI)

上述三值均在[0,1]區間,值越大越好

內部指標

簇C內樣本間的平均距離

簇C內樣本間最遠距離

簇Ci與Cj最近樣本間的距離

簇Ci與Cj中心點間的距離

 基於上式可導出常用的聚類性能度量內部指標:
1. DB指數(Davies-Bouldin Index,DBI)
類比簇間相似度


2. Dunn指數(Dunn Index,DI)
類比簇內相似度

DBI的值越小越好,DI相反,越大越好

 

二、距離計算

最常用的是“閔可夫斯基距離”(Minkowski distance)


p=2時,閔可夫斯基距離即歐氏距離(Euclidean distance)


p=1時,閔可夫斯基距離即曼哈頓距離(Manhattan distance)

 我們常將屬性划分為“連續屬性”(continuous attribute)(數值屬性)和“離散屬性”(categorical attribute)(列名屬性)。但在討論距離計算時,屬性上是否定義了“序”關系更為重要。能直接在屬性值上計算距離的稱為“有序屬性”,不能直接在屬性值上計算距離的稱為“無序屬性”(大多數類別特征)。顯然,閔可夫斯基距離可用於有序屬性。

 對無序屬性可采用VDM(Value Difference Metric)。令Mu,a表示在屬性u上取值為a的樣本數,Mu,a,i表示在第i個樣本簇中在屬性u上取值為a的樣本數,k為樣本簇數,則屬性u上兩個離散值a與b之間的VDM距離為:

將閔可夫斯基距離和VDM結合可處理混合屬性。不失一般性,令有序屬性排列在無序屬性之前,則

當樣本空間中不同屬性的重要性不同時,可使用“加權距離”,以加權閔可夫斯基距離為例:通常權值之和為1。

 

三、原型聚類

k-means算法

給定樣本集D={x1,x2,…,xm},“k均值”(k-means)算法針對聚類所得簇划分C={C1,C2,…,Ck}最小化平方誤差


最小化式(9.24)並不容易,找到它的最優解需考察樣本集D所有可能的簇划分,這是一個NP難問題。k均值算法采用了貪心策略,通過迭代優化來近似求解式。以下是k均值算法描述

kmeans缺點1、需先確定k的個數  2、對噪聲和離群點敏感 3、結果不一定是全局最優,只能保證局部最優 

如何初始化簇中心:http://blog.csdn.net/shennongzhaizhu/article/details/51871891

K個初始類簇點的選取除了隨機選取之外還有兩種方法:1)選擇彼此距離盡可能遠的K個點   2)先對數據用層次聚類算法或者Canopy算法進行聚類,得到K個簇之后,從每個類簇中選擇一個點,該點可以是該類簇的中心點,或者是距離類簇中心點最近的那個點。

1) 選擇彼此距離盡可能遠的K個點

  首先隨機選擇一個點作為第一個初始類簇中心點,然后選擇距離該點最遠的那個點作為第二個初始類簇中心點,然后再選擇距離前兩個點的最近距離最大的點作為第三個初始類簇的中心點,以此類推,直至選出K個初始類簇中心點。

2) 選用層次聚類或者Canopy算法進行初始聚類,然后利用這些簇的中心點作為KMeans算法初始簇中心點

K值的確定

給定一個合適的簇指標,比如平均半徑或直徑,只要我們假設的簇的數目等於或者高於真實的簇的數目時,該指標上升會很緩慢,而一旦試圖得到少於真實數目的簇時,該指標會急劇上升

類簇的直徑是指類簇內任意兩點之間的最大距離。

類簇的半徑是指類簇內所有點到類簇中心距離的最大值。

kmeans實現

def loadDataSet(fileName):
    dataMat = []
    fr = open(fileName)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float, curLine)
        dataMat.append(fltLine)
    return dataMat
    
#計算兩個向量的距離,用的是歐幾里得距離
def distEclud(vecA, vecB):
    return sqrt(sum(power(vecA - vecB, 2)))

#隨機生成初始的質心(ng的課說的初始方式是隨機選K個點)    
def randCent(dataSet, k):
    n = shape(dataSet)[1]
    centroids = mat(zeros((k,n)))
    for j in range(n):
        minJ = min(dataSet[:,j])
        rangeJ = float(max(array(dataSet)[:,j]) - minJ)
        centroids[:,j] = minJ + rangeJ * random.rand(k,1)
    return centroids
    
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
    m = shape(dataSet)[0]
    clusterAssment = mat(zeros((m,2)))#create mat to assign data points 
                                      #to a centroid, also holds SE of each point
    centroids = createCent(dataSet, k)
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False
        for i in range(m):#for each data point assign it to the closest centroid
            minDist = inf
            minIndex = -1
            for j in range(k):
                distJI = distMeas(centroids[j,:],dataSet[i,:])
                if distJI < minDist:
                    minDist = distJI; minIndex = j
            if clusterAssment[i,0] != minIndex: 
                clusterChanged = True
            clusterAssment[i,:] = minIndex,minDist**2
        print centroids
        for cent in range(k):#recalculate centroids
            ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#get all the point in this cluster
            centroids[cent,:] = mean(ptsInClust, axis=0) #assign centroid to mean 
    return centroids, clusterAssment

 

學習向量量化(LVQ)

 與k均值算法類似,“學習向量量化”(Learning Vector Quantization,LVQ)也是試圖找到一組原型向量來刻畫聚類結構,LVQ假設數據樣本帶有類別標記,學習過程利用樣本的這些監督信息來輔助聚類。

樣本$x_i$是n維向量,每個原型向量也是n維向量,每個原型向量代表一個聚類簇。

LVQ算法描述如下:

 

首先對原型向量進行初始化,然后對原型向量進行迭代優化,在每一輪迭代中,算法隨機選取一個有標記訓練樣本,找出與其距離最近的原型向量,並根據兩者的類別標記是否一致來對原型向量進行更新。LVQ的關鍵是第6-10行的更新原型向量,對樣本Xj,若最近的原型向量pi與Xj的類別標記相同,則令pi向Xj的方向靠。若標簽不同,則遠離Xj。
在學得一組原型向量后,即可實現對樣本空間X的簇划分。對任意樣本x,它將被划入於其距離最近的原型向量所代表的簇中

高斯混合聚類

與k均值、LVQ用原型向量來刻畫聚類結構不同,高斯混合聚類采用概率模型來表達聚類原型。
高斯分布的定義:對n維樣本空間X中的隨機向量x,若x服從高斯分布,其概率密度函數為

高斯分布完全由均值向量和協方差矩陣這兩個參數確定

 根據概率密度函數可定義高斯混合分布

該分布共由k個混合成分組成,每個混合成分對應一個高斯分布。假設樣本的生成過程由高斯混合分布給出。令隨機變量Zj∈{1,2,…,k}表示生成樣本Xj的高斯混合成分,根據貝葉斯定理,Zj的后驗分布對應於:

換言之,PM(Zj=i|Xj)給出了樣本Xj由第i個高斯混合成分生成的后驗概率,為方便敘述,將其簡記為γji(i=1,2,…,k)。當高斯混合分布(9.29)已知時,高斯混合聚類將把樣本集D划分為k個簇C={C1,C2,…,Ck},每個樣本Xj的簇標記λj如下確定

將樣本划分進后驗概率最大的那個高斯混合成分。因此,從原型聚類的角度來看,高斯混合聚類是采用概率模型(高斯分布)對原型進行刻畫,簇划分則由原型對應后驗概率確定。對於式(9.29)模型參數{(αi,μi,Σi)|1≤i≤k}如何求解呢?可以采用極大似然估計,即最大化(對數)似然

 

LL(D)是對數似然的期望值。上式常采用EM算法進行迭代優化求解。EM算法步驟在此簡要復習一下:
EM(Expectation-Maximization)算法是常用的估計參數隱變量(隱變量:未觀測變量的學名)的利器,它是一種迭代式地方法,基本思想是:若參數θ已知,則可根據訓練數據推斷出最優隱變量Z的值(E步);反之,若Z的值已知,則可方便地對參數θ做極大似然估計(M步)。EM算法可看作是一種非梯度優化方法(坐標下降法)。
簡要來說,EM算法使用E步和M步交替計算:
E步(期望E步):利用當前估計的參數計算對數似然的期望值
M步(最大化M步):尋找能使E步產生的似然期望最大化的參數值
重復E步、M步直至收斂。
根據上述的EM算法步驟可得高斯混合模型的EM算法:在每步迭代中,先根據當前參數來計算每個樣本屬於每個高斯成分的后驗概率(E步),再根據更新公式更新模型參數,包括均值向量、協方差矩陣以及新混合系數。具體高斯混合聚類算法步驟如下:

 四、層次聚類

 層次聚類(hierarchical clustering)試圖在不同層次對數據集進行划分,從而形成樹形的聚類結構。數據集的划分可采用“自底向上”的聚合策略,也可采用“自頂向下”的分拆策略。
AGNES是一種采用自底向上聚合策略的層次聚類算法。它先將數據集中的每個樣本看作一個初始聚類簇,然后在算法運行的每一步中找出距離最近的兩個聚類簇進行合並,該過程不斷重復,直至達到預設的聚類簇個數,這里的關鍵是如何計算聚類簇之間的距離。可根據如下式子計算距離:

顯然,最小距離由兩個簇的最近樣本決定,最大距離由兩個簇的最遠樣本決定,而平均距離則有兩個簇的所有樣本共同決定。當聚類簇距離分別由這三個距離計算時,AGNES算法被相應地稱為“單鏈接”(single-linkage)、“全鏈接”(complete-linkage)或“均鏈接”(average-linkage)算法。AGNES算法描述如下:

 

 

參考:

http://bealin.github.io/2017/02/27/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%B3%BB%E5%88%97%E2%80%9410-%E8%81%9A%E7%B1%BB/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM