K-means
原理
首先隨機選擇k個初始點作為質心
1. 對每一個樣本點,計算得到距離其最近的質心,將其類別標記為該質心對應的類別
2. 使用歸類好的樣本點,重新計算K個類別的質心
3. 重複上述過程,直到質心不發生變化
距離計算方法
在K-Means演算法中,需要注意的是,對於距離的計算有很多中方法:
(1)閔可夫斯基距離( Minkowski )
注意這裡p=2時則為常用的歐氏距離。
(2) 餘弦相似度( Cosine Similarity )
(3) 皮爾遜相關係數 ( Pearson Coefficient )
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聚類中提到的演算法,都是可以的,但是關於類比代表的選擇是需要多關注的,這個會影響聚類的效果,在實際應用中可以靈活選擇。
關於代表點的選擇有以下幾種方法, 不同的代表點選擇方法,也就代表了不同的類別融合方法
-
最小距離
選擇兩個類之間距離最近的兩個點作為代表點 -
最大距離
選擇兩個類之間距離最遠的點作為代表點 -
中心距離
計算類別中的平均值,作為代表點 -
均值距離
計算兩個類別所有點之間的距離,求平均,然後平均值最小的進行融合 -
最小方差
直接將幾個類別倆倆混到一起,計算方差,方差小的兩個類融合到一起
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
密度聚類不同於上述的兩種,密度聚類是不需要設定聚類的個數的,它可以自動找到聚類的個數,但是相應的,密度聚類需要其他引數的設定,這些設定會影響最終聚類的效果。
在理解密度聚類之前,需要理解幾個概念:
-
\(\epsilon\)鄰域
-
核心物件(Core object)
-
密度直達( directly density-reachable)
-
密度可達( density-reahable)
假設樣本空間一個點為 \(x\), 那麼\(\epsilon\)鄰域表示的是,以\(x\)為中心,\(\epsilon\)為半徑的空間。如果這個空間內,樣本的數量≥ minpts(預先設定的樣本閾值)這個時候,\(x\)可以被稱為這個空間的核心物件。同時,如果存在一個樣本點\(x_i\),處於以\(x\)為核心物件的\(\epsilon\)鄰域內,那麼就稱為密度直達。假設有n個核心物件\(x_1,x_2....x_n\), 如果有一條路徑是的\(x_1\)通過多次 密度直達 到達\(x_n\), 那麼就稱為密度可達。
密度聚類演算法原理
演算法思路,注意這裡這個方法不需要指定要最終要聚多少類別
- 首先要設定一個引數是鄰域半徑\(\epsilon\),其次是核心物件所需要的最小點個數minpts
- 確定核心物件,通過設定的鄰域半徑和最小點個數,可以找到所有滿足要求的核心物件,並儲存到一個列表\(\Omega\)中。
- 從列表\(\Omega\)隨機選擇一個核心物件\(x\),找到所有\(x\)密度可達的所有樣本,組成一個類別,並且將已經歸類的核心物件從\(\Omega\)中所找的的列表中刪除。
- 重複步驟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引數用來設定距離計算方法。
應用-壓縮資訊
聚類演算法一個很大的應用就是資訊壓縮,可以將資料進行聚類,然後,使用類別中的一個樣本代替全體樣本。