關注咱們的公衆號哦!獲取更多精彩哦!算法
假若有這樣一種狀況,在一天你想去某個城市旅遊,這個城市裏你想去的有70個地方,如今你只有每個地方的地址,這個地址列表很長,有70個位置。事先確定要作好攻略,你要把一些比較接近的地方放在一塊兒組成一組,這樣就能夠安排交通工具抵達這些組的「某個地址」,而後步行到每一個組內的地址。那麼,如何肯定這些組,如何肯定這些組的「某個地址」?答案就是聚類。而本文所提供的k-means聚類分析方法就能夠用於解決這類問題。數組
聚類是一個將數據集中在某些方面類似的數據成員進行分類組織的過程。k均值聚類是最著名的劃分聚類算法,因爲簡潔和效率使得他成爲全部聚類算法中最普遍使用的。給定一個數據點集合和須要的聚類數目k,k由用戶指定,k均值算法(k-means)根據某個距離函數反覆把數據分入k個聚類中。k-means 算法的工做過程說明以下:首先從n個數據對象任意選擇 k 個對象做爲初始聚類中心;而對於所剩下其它對象,則根據它們與這些聚類中心的類似度(距離),分別將它們分配給與其最類似的(聚類中心所表明的)聚類;而後再計算每一個所獲新聚類的聚類中心(該聚類中全部對象的均值);不斷重複這一過程直到標準測度函數開始收斂爲止。通常都採用均方差做爲標準測度函數。app
用如下例子加以解釋:函數
圖1:給定一個數據集;工具
圖2:根據K = 5初始化聚類中心,保證 聚類中心處於數據空間內;學習
圖3:根據計算類內對象和聚類中心之間的類似度指標,將數據進行劃分;編碼
圖4:將類內之間數據的均值做爲聚類中心,更新聚類中心。url
最後判斷算法結束與否便可,目的是爲了保證算法的收斂。3d
以往的迴歸分類、樸素貝葉斯分類、SVM分類的樣本的標籤是已知的,經過大量的訓練樣本獲得模型,而後判斷新的樣本所屬已知類別中的哪一類。而k-means聚類屬於無監督學習,樣本所屬的類別是未知的,只是根據特徵將樣本分類,且類別空間也是根據人爲須要選定的。code
K-means核心思想:最小化全部樣本到所屬類別中心的歐式距離和,採用迭代的方式實現收斂。
K-means算法的具體步驟以下:
1)原理比較簡單,實現也是很容易,收斂速度快。
2)聚類效果較優。
3)算法的可解釋度比較強。
4)主要須要調參的參數僅僅是簇數k。
1)K值的選取很差把握
2)對於不是凸的數據集比較難收斂
3)若是各隱含類別的數據不平衡,好比各隱含類別的數據量嚴重失衡,或者各隱含類別的方差不一樣,則聚類效果不佳。
4)採用迭代方法,獲得的結果只是局部最優。
5)對噪音和異常點比較的敏感。
6)可能收斂到局部最小值,在大規模數據集上收斂較慢。
聚類是一種無監督的學習,它將類似的對象歸到同一簇中。聚類的方法幾乎能夠應用全部對象,簇內的對象越類似,聚類的效果就越好。K-means算法中的k表示的是聚類爲k個簇,means表明取每個聚類中數據值的均值做爲該簇的中心,或者稱爲質心,即用每個的類的質心對該簇進行描述。聚類和分類最大的不一樣在於,分類的目標是事先已知的,而聚類則不同,聚類事先不知道目標變量是什麼,類別沒有像分類那樣被預先定義出來,因此,聚類有時也叫無監督學習。聚類分析試圖將類似的對象納入同一簇,將不類似的對象歸爲不一樣簇,那麼,顯然須要一種合適的類似度計算方法,咱們已知的有不少類似度的計算方法,好比歐氏距離,餘弦距離,漢明距離等。事實上,咱們應該根據具體的應用來選取合適的類似度計算方法。 固然,任何一種算法都有必定的缺陷,沒有一種算法時完美的,有的只是人類不斷追求完美,不斷創新的意志。K-means算法也有它的缺陷,可是咱們能夠經過一些後處理來獲得更好的聚類結果,這些在後面都會講到。K-means算法雖然比較容易實現,可是其可能收斂到局部最優解,且在大規模數據集上收斂速度相對較慢。
首先,隨機肯定k個初始點的質心;而後將數據集中的每個點分配到一個簇中,即爲每個點找到距其最近的質心,並將其分配給該質心所對應的簇;該步完成後,每個簇的質心更新爲該簇全部點的平均值。具體算法表示以下:下圖展現了K-means聚類算法的支持函數在Python環境下的具體表示:
在上述算法清單中,包含了幾個K-均值算法中要用到的輔助函數。LoadDataSet()函數是將文本文件導入到列表中,文本文件每一行爲tab分隔的浮點數,每個列表會被添加到dataMat中,最後返回dataMat;函數distEclud()用於計算兩個向量的歐式距離;函數randCent()爲給定數據集構建一個包含k個隨機質心的集合。下圖表示以上3個函數的實際效果。
若是3個支持函數均可以正常運行,就能夠準備實現完整的K-means算法了,該算法會建立K個質心,而後將每一個點分配到最近的質心,再從新計算質心,直到數據點的簇分配結果再也不改變爲止。具體代碼以下:
上面的代碼給出了完整的K-means算法。上述算法的運行邏輯以下:在第一步創建的Kmeans()函數接受4個輸入參數。只有數據集及簇的數目是必選的,而用來計算距離(咱們這裏用的是歐式距離)和建立初始質心的函數都是可選的(這裏用的是randCent函數)。Kmeans()函數一開始肯定數據集中數據點的總數,而後建立一個矩陣來存儲每一個點的簇分配結果。這個矩陣clusterAssment有兩列:簇索引值和聚類偏差。
按照上述方式反覆迭代,直到全部數據點的簇分配結果再也不改變爲止。程序中建立一個標誌變量clusterChanged,若是該值爲True,則繼續迭代。上述迭代使用while循環來實現。接下來遍歷全部數據找到距離每一個點最近的質心(經過對每一個點遍歷全部質心並計算點到每一個質心的歐式距離)。若是任一點的簇分配結果發生改變,則更新clusterChanged標誌。最後遍歷全部質心並更新它們的取值,具體實現步驟以下:經過數組過濾來得到給定簇的全部點;而後計算全部點的均值,選項axis=0表示沿矩陣的列方向進行均值計算;最後程序返回全部的類質心和點分配結果。
算法的運行效果以下圖所示,咱們能夠看到上面的結果通過了3次迭代以後k-means算法收斂:
K-means算法進行到這裏,咱們彷佛已經得出了聚類的質心,可是不要忘記了咱們的算法採起的是隨機初始化k個簇的質心的方法,這樣的話聚類效果可能會陷入局部最優解的狀況,這樣雖然有效果,但不如全局最優解的效果好。所以接下來的二分K--means算法就是針對這一問題所採起的相應的後處理,使算法跳出局部最優解,達到全局最優解,得到最好的聚類效果。二分K-means算法首先將全部點做爲一個簇,而後將簇一分爲二,以後選擇其中一個簇繼續進行劃分,選擇哪個簇取決於對其劃分是否可以最大程度地下降SSE(偏差平方和,即clusterAssment矩陣的第一列之和)的值。具體的代碼以下:
這個函數首先建立一個矩陣來存儲數據集中每一個點的簇分配結果及平方偏差,而後計算整個數據集的質心,並使用一個列表來保留全部的質心。獲得上述質心之後,能夠遍歷數據集中全部點來計算每一個點到質心的偏差值(後面會用到)。而後程序進入while循環,該循環會不停劃分簇,直到獲得想要的簇數目爲止。具體循環作法如上圖所示,當while循環結束時,函數返回質心列表與簇分配結果。下圖展現了一個上面全部算法一塊兒運行的結果:
二分k-means算法中,直到簇的數目達到k值,算法纔會中止。在算法中經過將全部的簇進行劃分,而後分別計算劃分後全部簇的偏差。選擇使得總偏差最小的那個簇進行劃分。劃分完成後,要更新簇的質心列表,數據點的分類結果及偏差平方。具體地,假設劃分的簇爲m(m<k)個簇中的第i個簇,那麼這個簇分紅的兩個簇後,其中一個取代該被劃分的簇,成爲第i個簇,並計算該簇的質心;此外,將劃分獲得的另一個簇,做爲一個新的簇,成爲第m+1個簇,並計算該簇的質心。此外,算法中還存儲了各個數據點的劃分結果和偏差平方,此時也應更新相應的存儲信息。這樣,重複該過程,直至簇個數達到k。經過上述算法,以前陷入局部最小值的的這些數據,通過二分K-means算法屢次劃分後,逐漸收斂到全局最小值,從而達到了使人滿意的聚類效果。
回到剛開始的問題,咱們如今有70個地方的地址,可是隻知道地址是不夠的,咱們須要知道的是這些地址之間的距離遠近信息。所以,咱們須要獲得每一個地址的經度和緯度,而後對這些地址進行聚類以安排行程。具體的地址轉換與算法過程以下所示:
這一部分屬於數據預處理工做,在上述代碼中,首先建立一個字典,字典裏面存儲的是經過URL獲取經緯度所必要的參數,即咱們想要的返回的數據格式flogs=J;獲取數據的appid;以及要輸入的地址信息(stAddress,city)。而後,經過urlencode()函數幫助咱們將字典類型的信息轉化爲URL能夠傳遞的字符串格式。最後,打開URL獲取返回的JSON類型數據,經過JSON工具來解析返回的數據。且在返回的結果中,當錯誤編碼爲0時表示,獲得了經緯度信息,而爲其餘值時,則表示返回經緯度信息失敗。此外,在代碼中,每次獲取完一個地點的經緯度信息後,延遲一秒鐘。這樣作的目的是爲了不頻繁的調用API,請求被封掉的狀況。接下來就要正式利用k—means聚類方法對地理座標進行聚類。
將上述算法加入到第三部分「算法示例」中的算法中,而後在Python提示符下輸入以下圖所示的命令,獲得的結果以下圖所示:
執行上面的命令以後,最後得出的聚類結果以下圖所示:
責編 | 薛 李 蔡 孫 趙
指導 | 老薛
指導教授簡介:
薛巍立,男,博士,東南大學經濟管理學院教授,博士生導師,國家天然科學基金優秀青年基金項目得到者。博士畢業於香港中文大學系統工程與工程管理系,主要從事供應鏈物流管理、運營風險管理和醫療服務運做管理等。主要成果發表在Operations Research、Production and Operations Management、Transportation Science、European Journal of Operational Research、Operations Research Letters等期刊上。