用scikit-learn學習譜聚類


    在譜聚類(spectral clustering)原理總結中,我們對譜聚類的原理做了總結。這里我們就對scikit-learn中譜聚類的使用做一個總結。

1. scikit-learn譜聚類概述

    在scikit-learn的類庫中,sklearn.cluster.SpectralClustering實現了基於Ncut的譜聚類,沒有實現基於RatioCut的切圖聚類。同時,對於相似矩陣的建立,也只是實現了基於K鄰近法和全連接法的方式,沒有基於$\epsilon$-鄰近法的相似矩陣。最后一步的聚類方法則提供了兩種,K-Means算法和 discretize算法。

    對於SpectralClustering的參數,我們主要需要調參的是相似矩陣建立相關的參數和聚類類別數目,它對聚類的結果有很大的影響。當然其他的一些參數也需要理解,在必要時需要修改默認參數。

2. SpectralClustering重要參數與調參注意事項

    下面我們就對SpectralClustering的重要參數做一個介紹,對於調參的注意事項會一起介紹。

    1)n_clusters:代表我們在對譜聚類切圖時降維到的維數(原理篇第7節的$k_1$),同時也是最后一步聚類算法聚類到的維數(原理篇第7節的$k_2$)。也就是說scikit-learn中的譜聚類對這兩個參數統一到了一起。簡化了調參的參數個數。雖然這個值是可選的,但是一般還是推薦調參選擇最優參數。

    2) affinity: 也就是我們的相似矩陣的建立方式。可以選擇的方式有三類,第一類是 'nearest_neighbors'即K鄰近法。第二類是'precomputed'即自定義相似矩陣。選擇自定義相似矩陣時,需要自己調用set_params來自己設置相似矩陣。第三類是全連接法,可以使用各種核函數來定義相似矩陣,還可以自定義核函數。最常用的是內置高斯核函數'rbf'。其他比較流行的核函數有‘linear’即線性核函數, ‘poly’即多項式核函數, ‘sigmoid’即sigmoid核函數。如果選擇了這些核函數, 對應的核函數參數在后面有單獨的參數需要調。自定義核函數我沒有使用過,這里就不多講了。affinity默認是高斯核'rbf'。一般來說,相似矩陣推薦使用默認的高斯核函數。

    3) 核函數參數gamma: 如果我們在affinity參數使用了多項式核函數 'poly',高斯核函數‘rbf’, 或者'sigmoid'核函數,那么我們就需要對這個參數進行調參。

    多項式核函數中這個參數對應$K(x, z) = (\gamma x \bullet z  + r)^d$中的$\gamma$。一般需要通過交叉驗證選擇一組合適的$\gamma, r, d$

    高斯核函數中這個參數對應$K(x, z) = exp(-\gamma||x-z||^2)$中的$\gamma$。一般需要通過交叉驗證選擇合適的$\gamma$

    sigmoid核函數中這個參數對應$K(x, z) = tanh(\gamma x \bullet z  + r)$中的$\gamma$。一般需要通過交叉驗證選擇一組合適的$\gamma, r$

    $\gamma$默認值為1.0,如果我們affinity使用'nearest_neighbors'或者是'precomputed',則這么參數無意義。

    4)核函數參數degree:如果我們在affinity參數使用了多項式核函數 'poly',那么我們就需要對這個參數進行調參。這個參數對應$K(x, z) = (\gamma x \bullet z  + r)^d$中的$d$。默認是3。一般需要通過交叉驗證選擇一組合適的$\gamma, r, d$

    5)核函數參數coef0: 如果我們在affinity參數使用了多項式核函數 'poly',或者sigmoid核函數,那么我們就需要對這個參數進行調參。

    多項式核函數中這個參數對應$K(x, z) = (\gamma x \bullet z  + r)^d$中的$r$。一般需要通過交叉驗證選擇一組合適的$\gamma, r, d$

    sigmoid核函數中這個參數對應$K(x, z) = tanh(\gamma x \bullet z  + r)$中的$r$。一般需要通過交叉驗證選擇一組合適的$\gamma, r$

    coef0默認為1.

    6)kernel_params:如果affinity參數使用了自定義的核函數,則需要通過這個參數傳入核函數的參數。

    7 )n_neighbors: 如果我們affinity參數指定為'nearest_neighbors'即K鄰近法,則我們可以通過這個參數指定KNN算法的K的個數。默認是10.我們需要根據樣本的分布對這個參數進行調參。如果我們affinity不使用'nearest_neighbors',則無需理會這個參數。

    8)eigen_solver:1在降維計算特征值特征向量的時候,使用的工具。有 None, ‘arpack’, ‘lobpcg’, 和‘amg’4種選擇。如果我們的樣本數不是特別大,無需理會這個參數,使用''None暴力矩陣特征分解即可,如果樣本量太大,則需要使用后面的一些矩陣工具來加速矩陣特征分解。它對算法的聚類效果無影響。

    9)eigen_tol:如果eigen_solver使用了arpack’,則需要通過eigen_tol指定矩陣分解停止條件。

    10)assign_labels:即最后的聚類方法的選擇,有K-Means算法和 discretize算法兩種算法可以選擇。一般來說,默認的K-Means算法聚類效果更好。但是由於K-Means算法結果受初始值選擇的影響,可能每次都不同,如果我們需要算法結果可以重現,則可以使用discretize。

    11)n_init:即使用K-Means時用不同的初始值組合跑K-Means聚類的次數,這個和K-Means類里面n_init的意義完全相同,默認是10,一般使用默認值就可以。如果你的n_clusters值較大,則可以適當增大這個值。

    從上面的介紹可以看出,需要調參的部分除了最后的類別數n_clusters,主要是相似矩陣affinity的選擇,以及對應的相似矩陣參數。當我選定一個相似矩陣構建方法后,調參的過程就是對應的參數交叉選擇的過程。對於K鄰近法,需要對n_neighbors進行調參,對於全連接法里面最常用的高斯核函數rbf,則需要對gamma進行調參。     

3.SpectralClustering實例

    這里我們用一個例子講述下SpectralClustering的聚類。我們選擇最常用的高斯核來建立相似矩陣,用K-Means來做最后的聚類。

    完整代碼參見我的github: https://github.com/ljpzzz/machinelearning/blob/master/classic-machine-learning/spectral_cluster.ipynb

    首先我們生成500個個6維的數據集,分為5個簇。由於是6維,這里就不可視化了,代碼如下:

import numpy as np
from sklearn import datasets
X, y = datasets.make_blobs(n_samples=500, n_features=6, centers=5, cluster_std=[0.4, 0.3, 0.4, 0.3, 0.4], random_state=11)

    接着我們看看默認的譜聚類的效果:

from sklearn.cluster import SpectralClustering
y_pred = SpectralClustering().fit_predict(X)
from sklearn import metrics
print "Calinski-Harabasz Score", metrics.calinski_harabaz_score(X, y_pred) 

    輸出的Calinski-Harabasz分數為:

Calinski-Harabasz Score 14908.9325026  

    由於我們使用的是高斯核,那么我們一般需要對n_clusters和gamma進行調參。選擇合適的參數值。代碼如下:

for index, gamma in enumerate((0.01,0.1,1,10)):
    for index, k in enumerate((3,4,5,6)):
        y_pred = SpectralClustering(n_clusters=k, gamma=gamma).fit_predict(X)
        print "Calinski-Harabasz Score with gamma=", gamma, "n_clusters=", k,"score:", metrics.calinski_harabaz_score(X, y_pred) 

    輸出如下:

Calinski-Harabasz Score with gamma= 0.01 n_clusters= 3 score: 1979.77096092
Calinski-Harabasz Score with gamma= 0.01 n_clusters= 4 score: 3154.01841219
Calinski-Harabasz Score with gamma= 0.01 n_clusters= 5 score: 23410.63895
Calinski-Harabasz Score with gamma= 0.01 n_clusters= 6 score: 19303.7340877
Calinski-Harabasz Score with gamma= 0.1 n_clusters= 3 score: 1979.77096092
Calinski-Harabasz Score with gamma= 0.1 n_clusters= 4 score: 3154.01841219
Calinski-Harabasz Score with gamma= 0.1 n_clusters= 5 score: 23410.63895
Calinski-Harabasz Score with gamma= 0.1 n_clusters= 6 score: 19427.9618944
Calinski-Harabasz Score with gamma= 1 n_clusters= 3 score: 687.787319232
Calinski-Harabasz Score with gamma= 1 n_clusters= 4 score: 196.926294549
Calinski-Harabasz Score with gamma= 1 n_clusters= 5 score: 23410.63895
Calinski-Harabasz Score with gamma= 1 n_clusters= 6 score: 19384.9657724
Calinski-Harabasz Score with gamma= 10 n_clusters= 3 score: 43.8197355672
Calinski-Harabasz Score with gamma= 10 n_clusters= 4 score: 35.2149370067
Calinski-Harabasz Score with gamma= 10 n_clusters= 5 score: 29.1784898767
Calinski-Harabasz Score with gamma= 10 n_clusters= 6 score: 47.3799111856

    可見最好的n_clusters是5,而最好的高斯核參數是1或者0.1.

    我們可以看看不輸入可選的n_clusters的時候,僅僅用最優的gamma為0.1時候的聚類效果,代碼如下:

y_pred = SpectralClustering(gamma=0.1).fit_predict(X)
print "Calinski-Harabasz Score", metrics.calinski_harabaz_score(X, y_pred) 

    輸出為:

Calinski-Harabasz Score 14950.4939717

    可見n_clusters一般還是調參選擇比較好。

 

(歡迎轉載,轉載請注明出處。歡迎溝通交流: liujianping-ok@163.com)     


免責聲明!

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



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