顧名思義,k均值聚類是一種對數據進行聚類的技術,即將數據分割成指定數量的幾個類,揭示數據的內在性質及規律。
咱們知道,在機器學習中,有三種不一樣的學習模式:監督學習、無監督學習和強化學習:python
- 監督學習,也稱爲有導師學習,網絡輸入包括數據和相應的輸出標籤信息。例如,在 MNIST 數據集中,手寫數字的每一個圖像都有一個標籤,表明圖片中的數字值。
- 強化學習,也稱爲評價學習,不給網絡提供指望的輸出,但空間會提供給出一個獎懲的反饋,當輸出正確時,給網絡獎勵,當輸出錯誤時就懲罰網絡。
- 無監督學習,也稱爲無導師學習,在網絡的輸入中沒有相應的輸出標籤信息,網絡接收輸入,但既沒有提供指望的輸出,也沒有提供來自環境的獎勵,神經網絡要在這種狀況下學習輸入數據中的隱藏結構。無監督學習很是有用,由於現存的大多數數據是沒有標籤的,這種方法能夠用於諸如模式識別、特徵提取、數據聚類和降維等任務。
k 均值聚類是一種無監督學習方法。
還記得哈利波特故事中的分院帽嗎?那就是聚類,將新學生(無標籤)分紅四類:格蘭芬多、拉文克拉、赫奇帕奇和斯特萊林。
人是很是擅長分類的,聚類算法試圖讓計算機也具有這種相似的能力,聚類技術不少,例如層次法、貝葉斯法和劃分法。k 均值聚類屬於劃分聚類方法,將數據分紅 k 個簇,每一個簇有一箇中心,稱爲質心,k 值須要給定。
k 均值聚類算法的工做原理以下:git
- 隨機選擇 k 個數據點做爲初始質心(聚類中心)。
- 將每一個數據點劃分給距離最近的質心,衡量兩個樣本數據點的距離有多種不一樣的方法,最經常使用的是歐氏距離。
- 從新計算每一個簇的質心做爲新的聚類中心,使其總的平方距離達到最小。
- 重複第 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 文檔對這些參數的定義以下:github
- 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 方法返回獲得簇的索引。dom
具體作法
- 與之前同樣,從加載必要的模塊開始,這裏須要 TensorFlow、NumPy 和 Matplotlib。這裏使用鳶尾花卉數據集,該數據集分爲三類,每類都是指一種鳶尾花卉,每類有 50 個實例。能夠從https://archive.ics.uci.edu/ml/datasets/iris上下載 .csv 文件,也可使用 sklearn 庫的數據集模塊(scikit-learn)來加載數據:
- 加載數據集:
- 繪出數據集查看一下:
代碼輸出以下:
- 能夠看到數據中並無明顯可見的分類。定義 input_fn 來給 fit() 方法輸入數據,函數返回一個 TensorFlow 常量,用來指定x的值和維度,類型爲 float。
- 開始使用 KmeansClustering 類,分爲 3 類,設置 num_clusters=3。一般狀況下事先並不知道最優的聚類數量,在這種狀況下,經常使用的方法是採用肘部法則(elbow method)來估計聚類數量:
- 使用 clusters() 方法找到這些簇,使用 predict_cluster_idx() 方法爲每一個輸入點計算分配的簇索引:
- 對建立的簇進行可視化操做,建立一個包裝函數 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 均值聚類因其簡單、快速、強大而被普遍應用,固然它也有不足之處,最大的不足就是用戶必須指定簇的數量;其次,算法不保證全局最優;再次,對異常值很是敏感。.net