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

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

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

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

3.Mean-shift數據庫

     1)概述數組

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

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

    2)圖解過程ide

       爲了方便你們理解,借用下幾張圖來講明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

 

8.GaussianMixtureModel(補)

     1)概述

        正太分佈也叫高斯分佈,正太分佈的機率密度曲線也叫高斯分佈機率曲線

        GaussianMixtureModel(混合高斯模型,GMM)。

         聚類算法大多數經過類似度來判斷,而類似度又大多采用歐式距離長短做爲衡量依據。而GMM採用了新的判斷依據:機率,即經過屬於某一類的機率大小來判斷最終的歸屬類別。

        GMM的基本思想就是:任意形狀的機率分佈均可以用多個高斯分佈函數去近似,也就是說GMM就是有多個單高斯密度分佈(Gaussian)組成的,每一個Gaussian叫一個"Component",這些"Component"線性加成在一塊兒就組成了 GMM 的機率密度函數,也就是下面的函數。

    2)數學公式

         

         這裏不講公式的具體推導過程,也不實現具體算法。列出來公式只是方便理解下面的函數中爲何須要那些參數。

         K:模型的個數,即Component的個數(聚類的個數)

         爲第k個高斯的權重

         p(x |k) 則爲第k個高斯機率密度,其均值爲μk,方差爲σk

         上述參數,除了K是直接給定以外,其餘參數都是經過EM算法估算出來的。(有個參數是指定EM算法參數的)

     3)GaussianMixtureModel 算法函數

         a)from sklearn.mixture.GaussianMixture

         b)主要參數(詳細參數

             n_components :高斯模型的個數,即聚類的目標個數

            covariance_type : 經過EM算法估算參數時使用的協方差類型,默認是"full"

                  full:每一個模型使用本身的通常協方差矩陣

                  tied:所用模型共享一個通常協方差矩陣

                  diag:每一個模型使用本身的對角線協方差矩陣

                  spherical:每一個模型使用本身的單一方差

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

 

import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.mixture import GaussianMixture

# 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 = 0)

##設置gmm函數
gmm = GaussianMixture(n_components=4, covariance_type='full').fit(X)
##訓練數據
y_pred = gmm.predict(X)

##繪圖
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
View Code

         5)效果圖

 

                     圖(16)

       跟圖15對比能夠看出,雖然使用一樣的數據,可是不一樣的算法的聚類效果是不同的

相關文章
相關標籤/搜索