機器學習Sklearn系列:(五)聚類演算法

Neo0oeN發表於2021-07-22

K-means

原理

首先隨機選擇k個初始點作為質心

1. 對每一個樣本點,計算得到距離其最近的質心,將其類別標記為該質心對應的類別
2. 使用歸類好的樣本點,重新計算K個類別的質心
3. 重複上述過程,直到質心不發生變化

距離計算方法

在K-Means演算法中,需要注意的是,對於距離的計算有很多中方法:

(1)閔可夫斯基距離( Minkowski )

\[d(x,y) = (\sum_{i=1}^n|x_i-y_i|^p)^{\frac{1}{p}} \]

注意這裡p=2時則為常用的歐氏距離。

(2) 餘弦相似度( Cosine Similarity )

\[d(x,y) = cos(\theta) = \frac{x^Ty}{|x| \cdot|y| } = \frac{\sum_{i=1}^n x_iy_i}{\sqrt{\sum_{i=1}^n x_i^2} \sqrt{\sum_{i=1}^n y_i^2 }} \]

(3) 皮爾遜相關係數 ( Pearson Coefficient )

\[p(x,y) = \frac{cov(x,y)}{\sigma_x \sigma_y} = \frac{\sum_{i=1}^n(x_i-\mu_x)(y_i-\mu_y)}{\sqrt{\sum_{i=1}^n(x_i-\mu_x)^2}\sqrt{\sum_{i=1}^n(y_i-\mu_y)^2}} \]

sklearn中的k-mean方法

class sklearn.cluster.KMeans (n_clusters=8, init=’k-means++’, 
n_init=10, max_iter=300, tol=0.0001,
precompute_distances=’auto’, verbose=0,
random_state=None, copy_x=True, n_jobs=None, 
algorithm=’auto’)

n_clusters: 設定聚類的數量

init:設定初心質心的方法,可輸入"k-means++","random"或者一個n維陣列。這是初始化質心的方法,預設"k-means++"。輸入k-means++":一種為K均值聚類選擇初始聚類中心的聰明的辦法,以加速收斂。如果輸入了n維陣列,陣列的形狀應該是(n_clusters,n_features)並給出初始質心。

random_state:控制每次質心隨機初始化的隨機數種子

n_init:整數,預設10,使用不同的質心隨機初始化的種子來執行k-means演算法的次數。最終結果會是基於Inertia來計算的n_init次連續執行後的最佳輸出。等價於執行10次,選擇最好一次的質心種子

max_iter:整數,預設300,單次執行的k-means演算法的最大迭代次數

tol:浮點數,預設1e-4,兩次迭代間Inertia下降的量,如果兩次迭代之間Inertia下降的值小於tol所設定的值,迭代就會停下

precompute_distances: 是否餘弦把所有點之間的距離計算出來,這樣的好處是在後面只需要檢索,不需要計算了,但是比較耗費記憶體。

一個例子:

from sklearn cluster import KMeans

model = Kmeans(n_cluster=3, max_iter=10)

model.cluster_centers_   #獲取聚類中心
model.labels  #獲取樣本所屬類別
model.inertia # 檢視總距離平方和,主要用來比較聚類效果 

層級聚類AgglomerativeClustering

層次聚類的思想是通過層次化的自上而下,或者下而上來將相似的類別歸到一起,最終實現聚類目的。具體流程如下:

1. 首先將所有樣本都看做成是單獨的類別,m個樣本表示m 個類別
2. 計算類別之間的距離,然後將距離最短的兩個類進行合併。
3. 重複2操作,直到類別個數為設定的聚類數k停止。

在層次聚類中,有兩個點需要注意,第一是選擇哪個作為類別的代表,二是兩個類別的代表點如何計算距離。這其中,距離的計算選擇比較多,例如上述K-Means聚類中提到的演算法,都是可以的,但是關於類比代表的選擇是需要多關注的,這個會影響聚類的效果,在實際應用中可以靈活選擇。

關於代表點的選擇有以下幾種方法, 不同的代表點選擇方法,也就代表了不同的類別融合方法

  1. 最小距離
    選擇兩個類之間距離最近的兩個點作為代表點

  2. 最大距離
    選擇兩個類之間距離最遠的點作為代表點

  3. 中心距離
    計算類別中的平均值,作為代表點

  4. 均值距離
    計算兩個類別所有點之間的距離,求平均,然後平均值最小的進行融合

  5. 最小方差
    直接將幾個類別倆倆混到一起,計算方差,方差小的兩個類融合到一起

sklearn中的層次聚類

from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(n_clusters=3,affinity="euclidean",
linkage="complete")
print("每個樣本的舉例",model.labels_)

這裡有兩個引數需要注意:

affinity: 主要表示距離計算的方法

linkage: 表示兩個類別之間的融合方法,有些也可以理解為兩個類中代表點的選擇方法,常用的方法如下:

# ward 最小方差
# complete 最大距離
# average 平均距離
# single 最小距離 

密度聚類 DBSCAN

密度聚類不同於上述的兩種,密度聚類是不需要設定聚類的個數的,它可以自動找到聚類的個數,但是相應的,密度聚類需要其他引數的設定,這些設定會影響最終聚類的效果。

在理解密度聚類之前,需要理解幾個概念:

  1. \(\epsilon\)鄰域

  2. 核心物件(Core object)

  3. 密度直達( directly density-reachable)

  4. 密度可達( density-reahable)

假設樣本空間一個點為 \(x\), 那麼\(\epsilon\)鄰域表示的是,以\(x\)為中心,\(\epsilon\)為半徑的空間。如果這個空間內,樣本的數量≥ minpts(預先設定的樣本閾值)這個時候,\(x\)可以被稱為這個空間的核心物件。同時,如果存在一個樣本點\(x_i\),處於以\(x\)為核心物件的\(\epsilon\)鄰域內,那麼就稱為密度直達。假設有n個核心物件\(x_1,x_2....x_n\), 如果有一條路徑是的\(x_1\)通過多次 密度直達 到達\(x_n\), 那麼就稱為密度可達。

密度聚類演算法原理

演算法思路,注意這裡這個方法不需要指定要最終要聚多少類別

  1. 首先要設定一個引數是鄰域半徑\(\epsilon\),其次是核心物件所需要的最小點個數minpts
  2. 確定核心物件,通過設定的鄰域半徑和最小點個數,可以找到所有滿足要求的核心物件,並儲存到一個列表\(\Omega\)中。
  3. 從列表\(\Omega\)隨機選擇一個核心物件\(x\),找到所有\(x\)密度可達的所有樣本,組成一個類別,並且將已經歸類的核心物件從\(\Omega\)中所找的的列表中刪除。
  4. 重複步驟3 , 直到所有核心物件列表為空結束。

sklearn中的密度聚類


from sklearn.cluster import DBSCAN
model = DBScan(eps = 0.5, min_samples = 5, metric = "euclidean")
model.fit(X)
print(model.labels_) 

這裡eps就是上述的引數\(\epsilon\), min_samples就是上述的引數minpts, metric引數用來設定距離計算方法。

應用-壓縮資訊

聚類演算法一個很大的應用就是資訊壓縮,可以將資料進行聚類,然後,使用類別中的一個樣本代替全體樣本。

相關文章