1. 程式人生 > >機器學習:Python實現聚類算法(三)之總結

機器學習:Python實現聚類算法(三)之總結

.fig ask class ted ssi 缺點 處理 blob ron

考慮到學習知識的順序及效率問題,所以後續的幾種聚類方法不再詳細講解原理,也不再寫python實現的源代碼,只介紹下算法的基本思路,使大家對每種算法有個直觀的印象,從而可以更好的理解函數中參數的意義及作用,而重點是放在如何使用及使用的場景。

(題外話: 今天看到一篇博文:剛接觸機器學習這一個月我都做了什麽? 裏面對機器學習階段的劃分很不錯,就目前而言我們只要做到前兩階段即可)

因為前兩篇博客已經介紹了兩種算法,所以這裏的算法編號從3開始。

3.Mean-shift

1)概述

Mean-shift(即:均值遷移)的基本思想:在數據集中選定一個點,然後以這個點為圓心,r為半徑,畫一個圓(二維下是圓),求出這個點到所有點的向量的平均值,而圓心與向量均值的和為新的圓心,然後叠代此過程,直到滿足一點的條件結束。(Fukunage在1975年提出)

後來Yizong Cheng 在此基礎上加入了 核函數 和 權重系數 ,使得Mean-shift 算法開始流行起來。目前它在聚類、圖像平滑、分割、跟蹤等方面有著廣泛的應用。

2)圖解過程

為了方便大家理解,借用下幾張圖來說明Mean-shift的基本過程。

技術分享

由上圖可以很容易看到,Mean-shift 算法的核心思想就是不斷的尋找新的圓心坐標,直到密度最大的區域。

3)Mean-shift 算法函數

a)核心函數:sklearn.cluster.MeanShift(核函數:RBF核函數)

由上圖可知,圓心(或種子)的確定和半徑(或帶寬)的選擇,是影響算法效率的兩個主要因素。所以在sklearn.cluster.MeanShift中重點說明了這兩個參數的設定問題。

b)主要參數

bandwidth :半徑(或帶寬),float型。如果沒有給出,則使用sklearn.cluster.estimate_bandwidth計算出半徑(帶寬).(可選)

seeds :圓心(或種子),數組類型,即初始化的圓心。(可選)

bin_seeding :布爾值。如果為真,初始內核位置不是所有點的位置,而是點的離散版本的位置,其中點被分類到其粗糙度對應於帶寬的網格上。將此選項設置為True將加速算法,因為較少的種子將被初始化。默認值:False.如果種子參數(seeds)不為None則忽略。

c)主要屬性

cluster_centers_ : 數組類型。計算出的聚類中心的坐標。

labels_ :數組類型。每個數據點的分類標簽。

d)算法示例:代碼中有詳細講解內容

技術分享
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import MeanShift, estimate_bandwidth
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle  ##python自帶的叠代器模塊

##產生隨機數據的中心
centers = [[1, 1], [-1, -1], [1, -1]]
##產生的數據個數
n_samples=10000
##生產數據
X, _ = make_blobs(n_samples=n_samples, centers= centers, cluster_std=0.6, 
                  random_state =0)

##帶寬,也就是以某個點為核心時的搜索半徑
bandwidth = estimate_bandwidth(X, quantile=0.2, n_samples=500)
##設置均值偏移函數
ms = MeanShift(bandwidth=bandwidth, bin_seeding=True)
##訓練數據
ms.fit(X)
##每個點的標簽
labels = ms.labels_
print(labels)
##簇中心的點的集合
cluster_centers = ms.cluster_centers_
##總共的標簽分類
labels_unique = np.unique(labels)
##聚簇的個數,即分類的個數
n_clusters_ = len(labels_unique)

print("number of estimated clusters : %d" % n_clusters_)


##繪圖
plt.figure(1)
plt.clf()

colors = cycle(bgrcmykbgrcmykbgrcmykbgrcmyk)
for k, col in zip(range(n_clusters_), colors):
    ##根據lables中的值是否等於k,重新組成一個True、False的數組
    my_members = labels == k
    cluster_center = cluster_centers[k]
    ##X[my_members, 0] 取出my_members對應位置為True的值的橫坐標
    plt.plot(X[my_members, 0], X[my_members, 1], col + .)
    plt.plot(cluster_center[0], cluster_center[1], o, markerfacecolor=col,
             markeredgecolor=k, markersize=14)
plt.title(Estimated number of clusters: %d % n_clusters_)
plt.show()
View Code

e)效果圖

技術分享

圖4

4)openCV主要應用於圖像處理,而Mean-shift多用於圖像跟蹤等,所以對應圖像處理這部分而言,openCV中的Mean-shift算法的功能還是強大一點。

4.Spectral Clustering

1)概述

Spectral Clustering(SC,即譜聚類),是一種基於圖論的聚類方法,它能夠識別任意形狀的樣本空間且收斂於全局最有解,其基本思想是利用樣本數據的相似矩陣進行特征分解後得到的特征向量進行聚類.它與樣本特征無關而只與樣本個數有關。

基本思路:將樣本看作頂點,樣本間的相似度看作帶權的邊,從而將聚類問題轉為圖分割問題:找到一種圖分割的方法使得連接不同組的邊的權重盡可能低(這意味著組間相似度要盡可能低),組內的邊的權重盡可能高(這意味著組內相似度要盡可能高).

2)圖解過程

技術分享

圖5

如上圖所示,斷開虛線,六個數據被聚成兩類。

3)Spectral Clustering算法函數

a)核心函數:sklearn.cluster.SpectralClustering

因為是基於圖論的算法,所以輸入必須是對稱矩陣。

b)主要參數(參數較多,詳細參數)

n_clusters:聚類的個數。(官方的解釋:投影子空間的維度)

affinity:核函數,默認是‘rbf‘,可選:"nearest_neighbors","precomputed","rbf"或sklearn.metrics.pairwise_kernels支持的其中一個內核之一。

gamma :affinity指定的核函數的內核系數,默認1.0

c)主要屬性

labels_ :每個數據的分類標簽

d)算法示例:代碼中有詳細講解內容

技術分享
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import spectral_clustering
import numpy as np
import matplotlib.pyplot as plt
from sklearn import metrics
from itertools import cycle  ##python自帶的叠代器模塊

##產生隨機數據的中心
centers = [[1, 1], [-1, -1], [1, -1]]
##產生的數據個數
n_samples=3000
##生產數據
X, lables_true = make_blobs(n_samples=n_samples, centers= centers, cluster_std=0.6, 
                  random_state =0)

##變換成矩陣,輸入必須是對稱矩陣
metrics_metrix = (-1 * metrics.pairwise.pairwise_distances(X)).astype(np.int32)
metrics_metrix += -1 * metrics_metrix.min()
##設置譜聚類函數
n_clusters_= 4
lables = spectral_clustering(metrics_metrix,n_clusters=n_clusters_)

##繪圖
plt.figure(1)
plt.clf()

colors = cycle(bgrcmykbgrcmykbgrcmykbgrcmyk)
for k, col in zip(range(n_clusters_), colors):
    ##根據lables中的值是否等於k,重新組成一個True、False的數組
    my_members = lables == k
    ##X[my_members, 0] 取出my_members對應位置為True的值的橫坐標
    plt.plot(X[my_members, 0], X[my_members, 1], col + .)
    
plt.title(Estimated number of clusters: %d % n_clusters_)
plt.show()
View Code

e)效果圖

技術分享

圖5

5.Hierarchical Clustering

1)概述

Hierarchical Clustering(層次聚類):就是按照某種方法進行層次分類,直到滿足某種條件為止。

主要分成兩類:

a)凝聚:從下到上。首先將每個對象作為一個簇,然後合並這些原子簇為越來越大的簇,直到所有的對象都在一個簇中,或者某個終結條件被滿足。

b)分裂:從上到下。首先將所有對象置於同一個簇中,然後逐漸細分為越來越小的簇,直到每個對象自成一簇,或者達到了某個終止條件。(較少用)

2)算法步驟

a)將每個對象歸為一類, 共得到N類, 每類僅包含一個對象. 類與類之間的距離就是它們所包含的對象之間的距離.

b)找到最接近的兩個類並合並成一類, 於是總的類數少了一個.

c)重新計算新的類與所有舊類之間的距離.
d)重復第2步和第3步, 直到最後合並成一個類為止(此類包含了N個對象).

3)圖解過程

技術分享

圖6

4)Hierarchical Clustering算法函數

a)sklearn.cluster.AgglomerativeClustering

b)主要參數(詳細參數)

n_clusters:聚類的個數

linkage:指定層次聚類判斷相似度的方法,有以下三種:

ward:組間距離等於兩類對象之間的最小距離。(即single-linkage聚類)

average:組間距離等於兩組對象之間的平均距離。(average-linkage聚類)

complete:組間距離等於兩組對象之間的最大距離。(complete-linkage聚類)

c)主要屬性

labels_: 每個數據的分類標簽

d)算法示例:代碼中有詳細講解內容

技術分享
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import AgglomerativeClustering
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle  ##python自帶的叠代器模塊

##產生隨機數據的中心
centers = [[1, 1], [-1, -1], [1, -1]]
##產生的數據個數
n_samples=3000
##生產數據
X, lables_true = make_blobs(n_samples=n_samples, centers= centers, cluster_std=0.6, 
                  random_state =0)


##設置分層聚類函數
linkages = [ward, average, complete]
n_clusters_ = 3
ac = AgglomerativeClustering(linkage=linkages[2],n_clusters = n_clusters_)
##訓練數據
ac.fit(X)

##每個數據的分類
lables = ac.labels_

##繪圖
plt.figure(1)
plt.clf()

colors = cycle(bgrcmykbgrcmykbgrcmykbgrcmyk)
for k, col in zip(range(n_clusters_), colors):
    ##根據lables中的值是否等於k,重新組成一個True、False的數組
    my_members = lables == k
    ##X[my_members, 0] 取出my_members對應位置為True的值的橫坐標
    plt.plot(X[my_members, 0], X[my_members, 1], col + .)
    
plt.title(Estimated number of clusters: %d % n_clusters_)
plt.show()
View Code

e)效果圖:參數linkage的取值依次為:[‘ward‘, ‘average‘, ‘complete‘]

技術分享

6.DBSCAN

1)概述

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪聲的基於密度的聚類方法)是一種基於密度的空間聚類算法。該算法將具有足夠密度的區域劃分為簇(即要求聚類空間中的一定區域內所包含對象的數目不小於某一給定閾值)並在具有噪聲的空間數據庫中發現任意形狀的簇,它將簇定義為密度相連的點的最大集合。

2) 算法步驟(大致非詳細)

DBSCAN需要二個參數:掃描半徑 (eps)和最小包含點數(min_samples)

a)遍歷所有點,尋找核心點

b)連通核心點,並且在此過程中擴展某個分類集合中點的個數

3)圖解過程

技術分享

圖10

在上圖中,第一步就是尋找紅色的核心點,第二步就是用綠色箭頭聯通紅色點。圖中點以綠色線條為中心被分成了兩類。沒在黑色圓中的點是噪聲點。

4)DBSCAN算法函數

a)sklearn.cluster.DBSCAN

b)主要參數(詳細參數)

eps:兩個樣本之間的最大距離,即掃描半徑

min_samples :作為核心點的話鄰域(即以其為圓心,eps為半徑的圓,含圓上的點)中的最小樣本數(包括點本身)。

c)主要屬性

core_sample_indices_:核心樣本指數。(此參數在代碼中有詳細的解釋)

labels_:數據集中每個點的集合標簽給,噪聲點標簽為-1。

d)算法示例:代碼中有詳細講解內容

技術分享
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import DBSCAN
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle  ##python自帶的叠代器模塊
from sklearn.preprocessing import StandardScaler

##產生隨機數據的中心
centers = [[1, 1], [-1, -1], [1, -1]]
##產生的數據個數
n_samples=750
##生產數據:此實驗結果受cluster_std的影響,或者說受eps 和cluster_std差值影響
X, lables_true = make_blobs(n_samples=n_samples, centers= centers, cluster_std=0.4, 
                  random_state =0)


##設置分層聚類函數
db = DBSCAN(eps=0.3, min_samples=10)
##訓練數據
db.fit(X)
##初始化一個全是False的bool類型的數組
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
‘‘‘
   這裏是關鍵點(針對這行代碼:xy = X[class_member_mask & ~core_samples_mask]):
   db.core_sample_indices_  表示的是某個點在尋找核心點集合的過程中暫時被標為噪聲點的點(即周圍點
   小於min_samples),並不是最終的噪聲點。在對核心點進行聯通的過程中,這部分點會被進行重新歸類(即標簽
   並不會是表示噪聲點的-1),也可也這樣理解,這些點不適合做核心點,但是會被包含在某個核心點的範圍之內
‘‘‘
core_samples_mask[db.core_sample_indices_] = True

##每個數據的分類
lables = db.labels_

##分類個數:lables中包含-1,表示噪聲點
n_clusters_ =len(np.unique(lables)) - (1 if -1 in lables else 0)

##繪圖
unique_labels = set(lables)
‘‘‘
   1)np.linspace 返回[0,1]之間的len(unique_labels) 個數
   2)plt.cm 一個顏色映射模塊
   3)生成的每個colors包含4個值,分別是rgba
   4)其實這行代碼的意思就是生成4個可以和光譜對應的顏色值
‘‘‘
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))

plt.figure(1)
plt.clf()


for k, col in zip(unique_labels, colors):
    ##-1表示噪聲點,這裏的k表示黑色
    if k == -1:
        col = k

    ##生成一個True、False數組,lables == k 的設置成True
    class_member_mask = (lables == k)
    
    ##兩個數組做&運算,找出即是核心點又等於分類k的值  markeredgecolor=‘k‘,
    xy = X[class_member_mask & core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], o, c=col,markersize=14)
    ‘‘‘
       1)~優先級最高,按位對core_samples_mask 求反,求出的是噪音點的位置
       2)& 於運算之後,求出雖然剛開始是噪音點的位置,但是重新歸類卻屬於k的點
       3)對核心分類之後進行的擴展
    ‘‘‘
    xy = X[class_member_mask & ~core_samples_mask]     
    plt.plot(xy[:, 0], xy[:, 1], o, c=col,markersize=6)
    
plt.title(Estimated number of clusters: %d % n_clusters_)
plt.show()
View Code

e)效果圖

技術分享

圖11

如果不進行第二步中的擴展,所有的小圓點都應該是噪聲點(不符合第一步核心點的要求)

5)算法優缺點

a)優點

可以發現任意形狀的聚類

b)缺點

隨著數據量的增加,對I/O、內存的要求也隨之增加。

如果密度分布不均勻,聚類效果較差

7.Birch

1)概述

Birch(利用層次方法的平衡叠代規約和聚類):就是通過聚類特征(CF)形成一個聚類特征樹,root層的CF個數就是聚類個數。

2)相關概念:

聚類特征(CF):每一個CF是一個三元組,可以用(N,LS,SS)表示.其中N代表了這個CF中擁有的樣本點的數量;LS代表了這個CF中擁有的樣本點各特征維度的和向量,SS代表了這個CF中擁有的樣本點各特征維度的平方和。

技術分享

圖12

如上圖所示:N = 5

LS=(3+2+4+4+3,4+6+5+7+8)=(16,30)

SS =(32+22+42+42+32,42+62+52+72+82)=(54,190)

3)圖解過程

技術分享

圖13

對於上圖中的CF Tree,限定了B=7,L=5, 也就是說內部節點最多有7個CF(CF90下的圓),而葉子節點最多有5個CF(CF90到CF94)。葉子節點是通過雙向鏈表連通的。

4)Birch算法函數

a)sklearn.cluster.Birch

b)主要參數(詳細參數)

n_clusters :聚類的目標個數。(可選)

threshold :掃描半徑(個人理解,官方說法比較繞口),設置小了分類就多。

branches_factor:每個節點中CF子集群的最大數量,默認為50。

c)主要屬性

labels_ :每個數據點的分類

5) 算法示例:代碼中有詳細講解內容

技術分享
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import Birch

# X為樣本特征,Y為樣本簇類別, 共1000個樣本,每個樣本2個特征,共4個簇,簇中心在[-1,-1], [0,0],[1,1], [2,2]
X, y = make_blobs(n_samples=1000, n_features=2, centers=[[-1,-1], [0,0], [1,1], [2,2]], cluster_std=[0.4, 0.3, 0.4, 0.3], 
                  random_state =9)

##設置birch函數
birch = Birch(n_clusters = None)
##訓練數據
y_pred = birch.fit_predict(X)
##繪圖
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
View Code

6)效果圖:分別為n_clusters = None 和n_clusters = 4

技術分享 技術分享

圖14 圖15

機器學習:Python實現聚類算法(三)之總結