k均值聚類算法原理和(TensorFlow)實現


顧名思義,k均值聚類是一種對數據進行聚類的技術,即將數據分割成指定數量的幾個類,揭示數據的內在性質及規律。

我們知道,在機器學習中,有三種不同的學習模式:監督學習、無監督學習和強化學習:

  1. 監督學習,也稱為有導師學習,網絡輸入包括數據和相應的輸出標簽信息。例如,在 MNIST 數據集中,手寫數字的每個圖像都有一個標簽,代表圖片中的數字值。
  2. 強化學習,也稱為評價學習,不給網絡提供期望的輸出,但空間會提供給出一個獎懲的反饋,當輸出正確時,給網絡獎勵,當輸出錯誤時就懲罰網絡。
  3. 無監督學習,也稱為無導師學習,在網絡的輸入中沒有相應的輸出標簽信息,網絡接收輸入,但既沒有提供期望的輸出,也沒有提供來自環境的獎勵,神經網絡要在這種情況下學習輸入數據中的隱藏結構。無監督學習非常有用,因為現存的大多數數據是沒有標簽的,這種方法可以用於諸如模式識別、特征提取、數據聚類和降維等任務。


k 均值聚類是一種無監督學習方法。

還記得哈利波特故事中的分院帽嗎?那就是聚類,將新學生(無標簽)分成四類:格蘭芬多、拉文克拉、赫奇帕奇和斯特萊林。

人是非常擅長分類的,聚類算法試圖讓計算機也具備這種類似的能力,聚類技術很多,例如層次法、貝葉斯法和划分法。k 均值聚類屬於划分聚類方法,將數據分成 k 個簇,每個簇有一個中心,稱為質心,k 值需要給定。

k 均值聚類算法的工作原理如下:

  1. 隨機選擇 k 個數據點作為初始質心(聚類中心)。
  2. 將每個數據點划分給距離最近的質心,衡量兩個樣本數據點的距離有多種不同的方法,最常用的是歐氏距離。
  3. 重新計算每個簇的質心作為新的聚類中心,使其總的平方距離達到最小。
  4. 重復第 2 步和第 3 步,直到收斂。

准備工作

使用 TensorFlow 的 Estimator 類 KmeansClustering 來實現 k 均值聚類,具體實現可參考https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/contrib/learn/python/learn/estimators/kmeans.py,可以直接進行 k 均值聚類和推理。根據 TensorFlow 文檔,KmeansClustering 類對象可以使用以下__init__方法進行實例化: 



TensorFlow 文檔對這些參數的定義如下:

  • num_clusters:要訓練的簇數。
  • model_dir:保存模型結果和日志文件的目錄。
  • initial_clusters:指定如何對簇初始化,取值請參閱 clustering_ops.kmeans。
  • distance_metric:聚類的距離度量方式,取值請參閱 clustering_ops.kmeans。
  • random_seed:Python 中的整數類型,用於初始化質心的偽隨機序列發生器的種子。
  • use_mini_batch:如果為 true,運行算法時分批處理數據,否則一次使用全部數據集。
  • mini_batch_steps_per_iteration:經過指定步數后將計算的簇中心更新回原數據。更多詳細信息參見 clustering_ops.py。
  • kmeans_plus_plus_num_retries:對於在 kmeans++ 方法初始化過程中采樣的每個點,該參數指定在選擇最優值之前從當前分布中提取的附加點數。如果指定了負值,則使用試探法對 O(log(num_to_sample)) 個附加點進行抽樣。
  • relative_tolerance:相對誤差,在每一輪迭代之間若損失函數的變化小於這個值則停止計算。有一點要注意就是,如果將 use_mini_batch 設置為 True,程序可能無法正常工作。

配置:請參閱 Estimator。

TensorFlow 支持將歐氏距離和余弦距離作為質心的度量,KmeansClustering 類提供了多種交互方法。在這里使用 fit()、clusters() 和 predict_clusters_idx() 方法:



根據 TensorFlow 文檔描述,需要給 fit() 提供 input_fn() 函數,cluster 方法返回簇質心,predict_cluster_idx 方法返回得到簇的索引。

具體做法

  1. 與以前一樣,從加載必要的模塊開始,這里需要 TensorFlow、NumPy 和 Matplotlib。這里使用鳶尾花卉數據集,該數據集分為三類,每類都是指一種鳶尾花卉,每類有 50 個實例。可以從https://archive.ics.uci.edu/ml/datasets/iris上下載 .csv 文件,也可以使用 sklearn 庫的數據集模塊(scikit-learn)來加載數據:


     
  2. 加載數據集:


     
  3. 繪出數據集查看一下:


     
    代碼輸出如下:


     
  4. 可以看到數據中並沒有明顯可見的分類。定義 input_fn 來給 fit() 方法輸入數據,函數返回一個 TensorFlow 常量,用來指定x的值和維度,類型為 float。


     
  5. 開始使用 KmeansClustering 類,分為 3 類,設置 num_clusters=3。通常情況下事先並不知道最優的聚類數量,在這種情況下,常用的方法是采用肘部法則(elbow method)來估計聚類數量:


     
  6. 使用 clusters() 方法找到這些簇,使用 predict_cluster_idx() 方法為每個輸入點計算分配的簇索引:


     
  7. 對創建的簇進行可視化操作,創建一個包裝函數 ScatterPlot,它將每個點的 X 和 Y 值與每個數據點的簇和簇索引對應起來:


     
    使用下面的函數畫出簇:


     
    結果如下:

    其中“+”號代表三個簇的質心。

解讀分析

上面的案例中使用 TensorFlow Estimator 的 k 均值聚類進行了聚類,這里是提前知道簇的數目,因此設置 num_clusters=3。但是在大多數情況下,數據沒有標簽,我們也不知道有多少簇存在,這時候可以使用肘部法則確定簇的最佳數量。

肘部法則選擇簇數量的原則是減少距離的平方誤差和(SSE),隨着簇數量 k 的增加,SSE 是逐漸減小的,直到 SSE=0,當k等於數據點的數量時,每個點都是自己的簇。

這里想要的是一個較小的 k 值,而且 SSE 也較小。在 TensorFlow 中,可以使用 KmeansClustering 類中定義的 score() 方法計算 SSE,該方法返回所有樣本點距最近簇的距離之和:



 

對於鳶尾花卉數據,如果針對不同的 k 值繪制 SSE,能夠看到 k=3 時,SSE 的變化是最大的;之后變化趨勢減小,因此肘部 k 值可設置為 3:



k 均值聚類因其簡單、快速、強大而被廣泛應用,當然它也有不足之處,最大的不足就是用戶必須指定簇的數量;其次,算法不保證全局最優;再次,對異常值非常敏感。


免責聲明!

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



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