-Means聚類算法
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括潁上網(wǎng)站建設(shè)、潁上網(wǎng)站制作、潁上網(wǎng)頁制作以及潁上網(wǎng)絡(luò)營(yíng)銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,潁上網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到潁上省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
k-means算法以k為參數(shù),把n個(gè)對(duì)象分成k個(gè)簇,使簇內(nèi)具有較高的相似度,而簇間的相似度較低。
隨機(jī)選擇k個(gè)點(diǎn)作為初始的聚類中心。
對(duì)于剩下的點(diǎn),根據(jù)其與聚類中心的距離,將其歸入最近的簇。
對(duì)每個(gè)簇,計(jì)算所有點(diǎn)的均值作為新的聚類中心。
重復(fù)2,3直到聚類中心不再發(fā)生改變
Figure 1
K-means的應(yīng)用
數(shù)據(jù)介紹:
現(xiàn)有1999年全國(guó)31個(gè)省份城鎮(zhèn)居民家庭平均每人全年消費(fèi)性支出的八大主要變量數(shù)據(jù),這八大變量分別是:食品、衣著、家庭設(shè)備用品及服務(wù)、醫(yī)療保健、交通和通訊、娛樂教育文化服務(wù)、居住以及雜項(xiàng)商品和服務(wù)。利用已有數(shù)據(jù),對(duì)31個(gè)省份進(jìn)行聚類。
實(shí)驗(yàn)?zāi)康模?/p>
通過聚類,了解1999年各個(gè)省份的消費(fèi)水平在國(guó)內(nèi)的情況。
技術(shù)路線:
sklearn.cluster.Kmeans
數(shù)據(jù)實(shí)例:
聚類或聚類分析是無監(jiān)督學(xué)習(xí)問題。它通常被用作數(shù)據(jù)分析技術(shù),用于發(fā)現(xiàn)數(shù)據(jù)中的有趣模式,例如基于其行為的客戶群。有許多聚類算法可供選擇,對(duì)于所有情況,沒有單一的最佳聚類算法。相反,最好探索一系列聚類算法以及每種算法的不同配置。在本教程中,你將發(fā)現(xiàn)如何在 python 中安裝和使用頂級(jí)聚類算法。完成本教程后,你將知道:
聚類分析,即聚類,是一項(xiàng)無監(jiān)督的機(jī)器學(xué)習(xí)任務(wù)。它包括自動(dòng)發(fā)現(xiàn)數(shù)據(jù)中的自然分組。與監(jiān)督學(xué)習(xí)(類似預(yù)測(cè)建模)不同,聚類算法只解釋輸入數(shù)據(jù),并在特征空間中找到自然組或群集。
群集通常是特征空間中的密度區(qū)域,其中來自域的示例(觀測(cè)或數(shù)據(jù)行)比其他群集更接近群集。群集可以具有作為樣本或點(diǎn)特征空間的中心(質(zhì)心),并且可以具有邊界或范圍。
聚類可以作為數(shù)據(jù)分析活動(dòng)提供幫助,以便了解更多關(guān)于問題域的信息,即所謂的模式發(fā)現(xiàn)或知識(shí)發(fā)現(xiàn)。例如:
聚類還可用作特征工程的類型,其中現(xiàn)有的和新的示例可被映射并標(biāo)記為屬于數(shù)據(jù)中所標(biāo)識(shí)的群集之一。雖然確實(shí)存在許多特定于群集的定量措施,但是對(duì)所識(shí)別的群集的評(píng)估是主觀的,并且可能需要領(lǐng)域?qū)<?。通常,聚類算法在人工合成?shù)據(jù)集上與預(yù)先定義的群集進(jìn)行學(xué)術(shù)比較,預(yù)計(jì)算法會(huì)發(fā)現(xiàn)這些群集。
有許多類型的聚類算法。許多算法在特征空間中的示例之間使用相似度或距離度量,以發(fā)現(xiàn)密集的觀測(cè)區(qū)域。因此,在使用聚類算法之前,擴(kuò)展數(shù)據(jù)通常是良好的實(shí)踐。
一些聚類算法要求您指定或猜測(cè)數(shù)據(jù)中要發(fā)現(xiàn)的群集的數(shù)量,而另一些算法要求指定觀測(cè)之間的最小距離,其中示例可以被視為“關(guān)閉”或“連接”。因此,聚類分析是一個(gè)迭代過程,在該過程中,對(duì)所識(shí)別的群集的主觀評(píng)估被反饋回算法配置的改變中,直到達(dá)到期望的或適當(dāng)?shù)慕Y(jié)果。scikit-learn 庫提供了一套不同的聚類算法供選擇。下面列出了10種比較流行的算法:
每個(gè)算法都提供了一種不同的方法來應(yīng)對(duì)數(shù)據(jù)中發(fā)現(xiàn)自然組的挑戰(zhàn)。沒有最好的聚類算法,也沒有簡(jiǎn)單的方法來找到最好的算法為您的數(shù)據(jù)沒有使用控制實(shí)驗(yàn)。在本教程中,我們將回顧如何使用來自 scikit-learn 庫的這10個(gè)流行的聚類算法中的每一個(gè)。這些示例將為您復(fù)制粘貼示例并在自己的數(shù)據(jù)上測(cè)試方法提供基礎(chǔ)。我們不會(huì)深入研究算法如何工作的理論,也不會(huì)直接比較它們。讓我們深入研究一下。
在本節(jié)中,我們將回顧如何在 scikit-learn 中使用10個(gè)流行的聚類算法。這包括一個(gè)擬合模型的例子和可視化結(jié)果的例子。這些示例用于將粘貼復(fù)制到您自己的項(xiàng)目中,并將方法應(yīng)用于您自己的數(shù)據(jù)。
1.庫安裝
首先,讓我們安裝庫。不要跳過此步驟,因?yàn)槟阈枰_保安裝了最新版本。你可以使用 pip Python 安裝程序安裝 scikit-learn 存儲(chǔ)庫,如下所示:
接下來,讓我們確認(rèn)已經(jīng)安裝了庫,并且您正在使用一個(gè)現(xiàn)代版本。運(yùn)行以下腳本以輸出庫版本號(hào)。
運(yùn)行該示例時(shí),您應(yīng)該看到以下版本號(hào)或更高版本。
2.聚類數(shù)據(jù)集
我們將使用 make _ classification ()函數(shù)創(chuàng)建一個(gè)測(cè)試二分類數(shù)據(jù)集。數(shù)據(jù)集將有1000個(gè)示例,每個(gè)類有兩個(gè)輸入要素和一個(gè)群集。這些群集在兩個(gè)維度上是可見的,因此我們可以用散點(diǎn)圖繪制數(shù)據(jù),并通過指定的群集對(duì)圖中的點(diǎn)進(jìn)行顏色繪制。這將有助于了解,至少在測(cè)試問題上,群集的識(shí)別能力如何。該測(cè)試問題中的群集基于多變量高斯,并非所有聚類算法都能有效地識(shí)別這些類型的群集。因此,本教程中的結(jié)果不應(yīng)用作比較一般方法的基礎(chǔ)。下面列出了創(chuàng)建和匯總合成聚類數(shù)據(jù)集的示例。
運(yùn)行該示例將創(chuàng)建合成的聚類數(shù)據(jù)集,然后創(chuàng)建輸入數(shù)據(jù)的散點(diǎn)圖,其中點(diǎn)由類標(biāo)簽(理想化的群集)著色。我們可以清楚地看到兩個(gè)不同的數(shù)據(jù)組在兩個(gè)維度,并希望一個(gè)自動(dòng)的聚類算法可以檢測(cè)這些分組。
已知聚類著色點(diǎn)的合成聚類數(shù)據(jù)集的散點(diǎn)圖接下來,我們可以開始查看應(yīng)用于此數(shù)據(jù)集的聚類算法的示例。我已經(jīng)做了一些最小的嘗試來調(diào)整每個(gè)方法到數(shù)據(jù)集。3.親和力傳播親和力傳播包括找到一組最能概括數(shù)據(jù)的范例。
它是通過 AffinityPropagation 類實(shí)現(xiàn)的,要調(diào)整的主要配置是將“ 阻尼 ”設(shè)置為0.5到1,甚至可能是“首選項(xiàng)”。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,我無法取得良好的結(jié)果。
數(shù)據(jù)集的散點(diǎn)圖,具有使用親和力傳播識(shí)別的聚類
4.聚合聚類
聚合聚類涉及合并示例,直到達(dá)到所需的群集數(shù)量為止。它是層次聚類方法的更廣泛類的一部分,通過 AgglomerationClustering 類實(shí)現(xiàn)的,主要配置是“ n _ clusters ”集,這是對(duì)數(shù)據(jù)中的群集數(shù)量的估計(jì),例如2。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,可以找到一個(gè)合理的分組。
使用聚集聚類識(shí)別出具有聚類的數(shù)據(jù)集的散點(diǎn)圖
5.BIRCHBIRCH
聚類( BIRCH 是平衡迭代減少的縮寫,聚類使用層次結(jié)構(gòu))包括構(gòu)造一個(gè)樹狀結(jié)構(gòu),從中提取聚類質(zhì)心。
它是通過 Birch 類實(shí)現(xiàn)的,主要配置是“ threshold ”和“ n _ clusters ”超參數(shù),后者提供了群集數(shù)量的估計(jì)。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,可以找到一個(gè)很好的分組。
使用BIRCH聚類確定具有聚類的數(shù)據(jù)集的散點(diǎn)圖
6.DBSCANDBSCAN
聚類(其中 DBSCAN 是基于密度的空間聚類的噪聲應(yīng)用程序)涉及在域中尋找高密度區(qū)域,并將其周圍的特征空間區(qū)域擴(kuò)展為群集。
它是通過 DBSCAN 類實(shí)現(xiàn)的,主要配置是“ eps ”和“ min _ samples ”超參數(shù)。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,盡管需要更多的調(diào)整,但是找到了合理的分組。
使用DBSCAN集群識(shí)別出具有集群的數(shù)據(jù)集的散點(diǎn)圖
7.K均值
K-均值聚類可以是最常見的聚類算法,并涉及向群集分配示例,以盡量減少每個(gè)群集內(nèi)的方差。
它是通過 K-均值類實(shí)現(xiàn)的,要優(yōu)化的主要配置是“ n _ clusters ”超參數(shù)設(shè)置為數(shù)據(jù)中估計(jì)的群集數(shù)量。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,可以找到一個(gè)合理的分組,盡管每個(gè)維度中的不等等方差使得該方法不太適合該數(shù)據(jù)集。
使用K均值聚類識(shí)別出具有聚類的數(shù)據(jù)集的散點(diǎn)圖
8.Mini-Batch
K-均值Mini-Batch K-均值是 K-均值的修改版本,它使用小批量的樣本而不是整個(gè)數(shù)據(jù)集對(duì)群集質(zhì)心進(jìn)行更新,這可以使大數(shù)據(jù)集的更新速度更快,并且可能對(duì)統(tǒng)計(jì)噪聲更健壯。
它是通過 MiniBatchKMeans 類實(shí)現(xiàn)的,要優(yōu)化的主配置是“ n _ clusters ”超參數(shù),設(shè)置為數(shù)據(jù)中估計(jì)的群集數(shù)量。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,會(huì)找到與標(biāo)準(zhǔn) K-均值算法相當(dāng)?shù)慕Y(jié)果。
帶有最小批次K均值聚類的聚類數(shù)據(jù)集的散點(diǎn)圖
9.均值漂移聚類
均值漂移聚類涉及到根據(jù)特征空間中的實(shí)例密度來尋找和調(diào)整質(zhì)心。
它是通過 MeanShift 類實(shí)現(xiàn)的,主要配置是“帶寬”超參數(shù)。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,可以在數(shù)據(jù)中找到一組合理的群集。
具有均值漂移聚類的聚類數(shù)據(jù)集散點(diǎn)圖
10.OPTICSOPTICS
聚類( OPTICS 短于訂購(gòu)點(diǎn)數(shù)以標(biāo)識(shí)聚類結(jié)構(gòu))是上述 DBSCAN 的修改版本。
它是通過 OPTICS 類實(shí)現(xiàn)的,主要配置是“ eps ”和“ min _ samples ”超參數(shù)。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,我無法在此數(shù)據(jù)集上獲得合理的結(jié)果。
使用OPTICS聚類確定具有聚類的數(shù)據(jù)集的散點(diǎn)圖
11.光譜聚類
光譜聚類是一類通用的聚類方法,取自線性線性代數(shù)。
它是通過 Spectral 聚類類實(shí)現(xiàn)的,而主要的 Spectral 聚類是一個(gè)由聚類方法組成的通用類,取自線性線性代數(shù)。要優(yōu)化的是“ n _ clusters ”超參數(shù),用于指定數(shù)據(jù)中的估計(jì)群集數(shù)量。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,找到了合理的集群。
使用光譜聚類聚類識(shí)別出具有聚類的數(shù)據(jù)集的散點(diǎn)圖
12.高斯混合模型
高斯混合模型總結(jié)了一個(gè)多變量概率密度函數(shù),顧名思義就是混合了高斯概率分布。它是通過 Gaussian Mixture 類實(shí)現(xiàn)的,要優(yōu)化的主要配置是“ n _ clusters ”超參數(shù),用于指定數(shù)據(jù)中估計(jì)的群集數(shù)量。下面列出了完整的示例。
運(yùn)行該示例符合訓(xùn)練數(shù)據(jù)集上的模型,并預(yù)測(cè)數(shù)據(jù)集中每個(gè)示例的群集。然后創(chuàng)建一個(gè)散點(diǎn)圖,并由其指定的群集著色。在這種情況下,我們可以看到群集被完美地識(shí)別。這并不奇怪,因?yàn)閿?shù)據(jù)集是作為 Gaussian 的混合生成的。
使用高斯混合聚類識(shí)別出具有聚類的數(shù)據(jù)集的散點(diǎn)圖
在本文中,你發(fā)現(xiàn)了如何在 python 中安裝和使用頂級(jí)聚類算法。具體來說,你學(xué)到了:
Python寫程序原則是所有進(jìn)來的字符串(讀文件,爬網(wǎng)頁),一進(jìn)來就decode,處理完之后在要輸出的地方在encode。題主讀入(read)和輸出(print)在一行里,要在win下面想不出錯(cuò)就這么寫 print response.decode('utf-8').encode('gbk')
譜聚類概念 :
譜聚類是一種基于圖論的聚類方法,通過對(duì)樣本數(shù)據(jù)的拉普拉斯矩陣的特征向量進(jìn)行聚類,從而達(dá)到對(duì)樣本數(shù)據(jù)聚類的母的。譜聚類可以理解為將高維空間的數(shù)據(jù)映射到低維,然后在低維空間用其它聚類算法(如KMeans)進(jìn)行聚類。
算法步驟
1 計(jì)算相似度矩陣 W
2 計(jì)算度矩陣 D
3 計(jì)算拉普拉斯矩陣L=D-W
4 計(jì)算L的特征值,將特征值從小到大排序,取前k個(gè)特征值.將這個(gè)特征值向量轉(zhuǎn)換為矩陣
5 通過其他聚類算法對(duì)其進(jìn)行聚類,如k-means
詳細(xì)公式和概念請(qǐng)到 大佬博客
相比較PCA降維中取前k大的特征值對(duì)應(yīng)的特征向量,這里取得是前k小的特征值對(duì)應(yīng)的特征向量。但是上述的譜聚類算法并不是最優(yōu)的,接下來我們一步一步的分解上面的步驟,總結(jié)一下在此基礎(chǔ)上進(jìn)行優(yōu)化的譜聚類的版本。
python實(shí)現(xiàn)
例子一:使用譜聚類從噪聲背景中分割目標(biāo)
效果圖
例子2:分割圖像中硬幣的區(qū)域
效果圖
注意
1)當(dāng)聚類的類別個(gè)數(shù)較小的時(shí)候,譜聚類的效果會(huì)很好,但是當(dāng)聚類的類別個(gè)數(shù)較大的時(shí)候,則不建議使用譜聚類;
(2)譜聚類算法使用了降維的技術(shù),所以更加適用于高維數(shù)據(jù)的聚類;
(3)譜聚類只需要數(shù)據(jù)之間的相似度矩陣,因此對(duì)于處理稀疏數(shù)據(jù)的聚類很有效。這點(diǎn)傳統(tǒng)聚類算法(比如K-Means)很難做到
(4)譜聚類算法建立在譜圖理論基礎(chǔ)上,與傳統(tǒng)的聚類算法相比,它具有能在任意形狀的樣本空間上聚類且收斂于全局最優(yōu)解
(5)譜聚類對(duì)相似度圖的改變和聚類參數(shù)的選擇非常的敏感;
(6)譜聚類適用于均衡分類問題,即各簇之間點(diǎn)的個(gè)數(shù)相差不大,對(duì)于簇之間點(diǎn)個(gè)數(shù)相差懸殊的聚類問題,譜聚類則不適用;
參考
譜聚類算法介紹
sklearn官網(wǎng)
實(shí)現(xiàn)原理:
首先從Tourist_spots_5A_BD.txt中讀取景點(diǎn)信息,然后通過調(diào)用無界面瀏覽器PhantomJS(Firefox可替代)訪問百度百科鏈接"",通過Selenium獲取輸入對(duì)話框ID,輸入關(guān)鍵詞如"故宮",再訪問該百科頁面。最后通過分析DOM樹結(jié)構(gòu)獲取摘要的ID并獲取其值。核心代碼如下:
driver.find_elements_by_xpath("http://div[@class='lemma-summary']/div")
PS:Selenium更多應(yīng)用于自動(dòng)化測(cè)試,推薦Python爬蟲使用scrapy等開源工具。
# coding=utf-8
"""
Created on 2015-09-04 @author: Eastmount
"""
import time
import re
import os
import sys
import codecs
import shutil
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import selenium.webdriver.support.ui as ui
from selenium.webdriver.common.action_chains import ActionChains
#Open PhantomJS
driver = webdriver.PhantomJS(executable_path="G:\phantomjs-1.9.1-windows\phantomjs.exe")
#driver = webdriver.Firefox()
wait = ui.WebDriverWait(driver,10)
#Get the Content of 5A tourist spots
def getInfobox(entityName, fileName):
try:
#create paths and txt files
print u'文件名稱: ', fileName
info = codecs.open(fileName, 'w', 'utf-8')
#locate input notice: 1.visit url by unicode 2.write files
#Error: Message: Element not found in the cache -
# Perhaps the page has changed since it was looked up
#解決方法: 使用Selenium和Phantomjs
print u'實(shí)體名稱: ', entityName.rstrip('\n')
driver.get("")
elem_inp = driver.find_element_by_xpath("http://form[@id='searchForm']/input")
elem_inp.send_keys(entityName)
elem_inp.send_keys(Keys.RETURN)
info.write(entityName.rstrip('\n')+'\r\n') #codecs不支持'\n'換行
time.sleep(2)
#load content 摘要
elem_value = driver.find_elements_by_xpath("http://div[@class='lemma-summary']/div")
for value in elem_value:
print value.text
info.writelines(value.text + '\r\n')
time.sleep(2)
except Exception,e: #'utf8' codec can't decode byte
print "Error: ",e
finally:
print '\n'
info.close()
#Main function
def main():
#By function get information
path = "BaiduSpider\\"
if os.path.isdir(path):
shutil.rmtree(path, True)
os.makedirs(path)
source = open("Tourist_spots_5A_BD.txt", 'r')
num = 1
for entityName in source:
entityName = unicode(entityName, "utf-8")
if u'故宮' in entityName: #else add a '?'
entityName = u'北京故宮'
name = "%04d" % num
fileName = path + str(name) + ".txt"
getInfobox(entityName, fileName)
num = num + 1
print 'End Read Files!'
source.close()
driver.close()
if __name__ == '__main__':
main()
1、從Kmeans說起
Kmeans是一個(gè)非常基礎(chǔ)的聚類算法,使用了迭代的思想,關(guān)于其原理這里不說了。下面說一下如何在matlab中使用kmeans算法。
創(chuàng)建7個(gè)二維的數(shù)據(jù)點(diǎn):
復(fù)制代碼 代碼如下:
x=[randn(3,2)*.4;randn(4,2)*.5+ones(4,1)*[4 4]];
使用kmeans函數(shù):
復(fù)制代碼 代碼如下:
class = kmeans(x, 2);
x是數(shù)據(jù)點(diǎn),x的每一行代表一個(gè)數(shù)據(jù);2指定要有2個(gè)中心點(diǎn),也就是聚類結(jié)果要有2個(gè)簇。 class將是一個(gè)具有70個(gè)元素的列向量,這些元素依次對(duì)應(yīng)70個(gè)數(shù)據(jù)點(diǎn),元素值代表著其對(duì)應(yīng)的數(shù)據(jù)點(diǎn)所處的分類號(hào)。某次運(yùn)行后,class的值是:
復(fù)制代碼 代碼如下:
2
2
2
1
1
1
1
這說明x的前三個(gè)數(shù)據(jù)點(diǎn)屬于簇2,而后四個(gè)數(shù)據(jù)點(diǎn)屬于簇1。 kmeans函數(shù)也可以像下面這樣使用:
復(fù)制代碼 代碼如下:
[class, C, sumd, D] = kmeans(x, 2)
class =
2
2
2
1
1
1
1
C =
4.0629 4.0845
-0.1341 0.1201
sumd =
1.2017
0.2939
D =
34.3727 0.0184
29.5644 0.1858
36.3511 0.0898
0.1247 37.4801
0.7537 24.0659
0.1979 36.7666
0.1256 36.2149
class依舊代表著每個(gè)數(shù)據(jù)點(diǎn)的分類;C包含最終的中心點(diǎn),一行代表一個(gè)中心點(diǎn);sumd代表著每個(gè)中心點(diǎn)與所屬簇內(nèi)各個(gè)數(shù)據(jù)點(diǎn)的距離之和;D的
每一行也對(duì)應(yīng)一個(gè)數(shù)據(jù)點(diǎn),行中的數(shù)值依次是該數(shù)據(jù)點(diǎn)與各個(gè)中心點(diǎn)之間的距離,Kmeans默認(rèn)使用的距離是歐幾里得距離(參考資料[3])的平方值。
kmeans函數(shù)使用的距離,也可以是曼哈頓距離(L1-距離),以及其他類型的距離,可以通過添加參數(shù)指定。
kmeans有幾個(gè)缺點(diǎn)(這在很多資料上都有說明):
1、最終簇的類別數(shù)目(即中心點(diǎn)或者說種子點(diǎn)的數(shù)目)k并不一定能事先知道,所以如何選一個(gè)合適的k的值是一個(gè)問題。
2、最開始的種子點(diǎn)的選擇的好壞會(huì)影響到聚類結(jié)果。
3、對(duì)噪聲和離群點(diǎn)敏感。
4、等等。
2、kmeans++算法的基本思路
kmeans++算法的主要工作體現(xiàn)在種子點(diǎn)的選擇上,基本原則是使得各個(gè)種子點(diǎn)之間的距離盡可能的大,但是又得排除噪聲的影響。 以下為基本思路:
1、從輸入的數(shù)據(jù)點(diǎn)集合(要求有k個(gè)聚類)中隨機(jī)選擇一個(gè)點(diǎn)作為第一個(gè)聚類中心
2、對(duì)于數(shù)據(jù)集中的每一個(gè)點(diǎn)x,計(jì)算它與最近聚類中心(指已選擇的聚類中心)的距離D(x)
3、選擇一個(gè)新的數(shù)據(jù)點(diǎn)作為新的聚類中心,選擇的原則是:D(x)較大的點(diǎn),被選取作為聚類中心的概率較大
4、重復(fù)2和3直到k個(gè)聚類中心被選出來
5、利用這k個(gè)初始的聚類中心來運(yùn)行標(biāo)準(zhǔn)的k-means算法
假定數(shù)據(jù)點(diǎn)集合X有n個(gè)數(shù)據(jù)點(diǎn),依次用X(1)、X(2)、……、X(n)表示,那么,在第2步中依次計(jì)算每個(gè)數(shù)據(jù)點(diǎn)與最近的種子點(diǎn)(聚類中心)的
距離,依次得到D(1)、D(2)、……、D(n)構(gòu)成的集合D。在D中,為了避免噪聲,不能直接選取值最大的元素,應(yīng)該選擇值較大的元素,然后將其對(duì)應(yīng)
的數(shù)據(jù)點(diǎn)作為種子點(diǎn)。
如何選擇值較大的元素呢,下面是一種思路(暫未找到最初的來源,在資料[2]等地方均有提及,筆者換了一種讓自己更好理解的說法):
把集合D中的每個(gè)元素D(x)想象為一根線L(x),線的長(zhǎng)度就是元素的值。將這些線依次按照L(1)、L(2)、……、L(n)的順序連接起來,組成長(zhǎng)
線L。L(1)、L(2)、……、L(n)稱為L(zhǎng)的子線。根據(jù)概率的相關(guān)知識(shí),如果我們?cè)贚上隨機(jī)選擇一個(gè)點(diǎn),那么這個(gè)點(diǎn)所在的子線很有可能是比較長(zhǎng)的子
線,而這個(gè)子線對(duì)應(yīng)的數(shù)據(jù)點(diǎn)就可以作為種子點(diǎn)。下文中kmeans++的兩種實(shí)現(xiàn)均是這個(gè)原理。
3、python版本的kmeans++
在 中能找到多種編程語言版本的Kmeans++實(shí)現(xiàn)。下面的內(nèi)容是基于python的實(shí)現(xiàn)(中文注釋是筆者添加的):
復(fù)制代碼 代碼如下:
from math import pi, sin, cos
from collections import namedtuple
from random import random, choice
from copy import copy
try:
import psyco
psyco.full()
except ImportError:
pass
FLOAT_MAX = 1e100
class Point:
__slots__ = ["x", "y", "group"]
def __init__(self, x=0.0, y=0.0, group=0):
self.x, self.y, self.group = x, y, group
def generate_points(npoints, radius):
points = [Point() for _ in xrange(npoints)]
# note: this is not a uniform 2-d distribution
for p in points:
r = random() * radius
ang = random() * 2 * pi
p.x = r * cos(ang)
p.y = r * sin(ang)
return points
def nearest_cluster_center(point, cluster_centers):
"""Distance and index of the closest cluster center"""
def sqr_distance_2D(a, b):
return (a.x - b.x) ** 2 + (a.y - b.y) ** 2
min_index = point.group
min_dist = FLOAT_MAX
for i, cc in enumerate(cluster_centers):
d = sqr_distance_2D(cc, point)
if min_dist d:
min_dist = d
min_index = i
return (min_index, min_dist)
'''
points是數(shù)據(jù)點(diǎn),nclusters是給定的簇類數(shù)目
cluster_centers包含初始化的nclusters個(gè)中心點(diǎn),開始都是對(duì)象-(0,0,0)
'''
def kpp(points, cluster_centers):
cluster_centers[0] = copy(choice(points)) #隨機(jī)選取第一個(gè)中心點(diǎn)
d = [0.0 for _ in xrange(len(points))] #列表,長(zhǎng)度為len(points),保存每個(gè)點(diǎn)離最近的中心點(diǎn)的距離
for i in xrange(1, len(cluster_centers)): # i=1...len(c_c)-1
sum = 0
for j, p in enumerate(points):
d[j] = nearest_cluster_center(p, cluster_centers[:i])[1] #第j個(gè)數(shù)據(jù)點(diǎn)p與各個(gè)中心點(diǎn)距離的最小值
sum += d[j]
sum *= random()
for j, di in enumerate(d):
sum -= di
if sum 0:
continue
cluster_centers[i] = copy(points[j])
break
for p in points:
p.group = nearest_cluster_center(p, cluster_centers)[0]
'''
points是數(shù)據(jù)點(diǎn),nclusters是給定的簇類數(shù)目
'''
def lloyd(points, nclusters):
cluster_centers = [Point() for _ in xrange(nclusters)] #根據(jù)指定的中心點(diǎn)個(gè)數(shù),初始化中心點(diǎn),均為(0,0,0)
# call k++ init
kpp(points, cluster_centers) #選擇初始種子點(diǎn)
# 下面是kmeans
lenpts10 = len(points) 10
changed = 0
while True:
# group element for centroids are used as counters
for cc in cluster_centers:
cc.x = 0
cc.y = 0
cc.group = 0
for p in points:
cluster_centers[p.group].group += 1 #與該種子點(diǎn)在同一簇的數(shù)據(jù)點(diǎn)的個(gè)數(shù)
cluster_centers[p.group].x += p.x
cluster_centers[p.group].y += p.y
for cc in cluster_centers: #生成新的中心點(diǎn)
cc.x /= cc.group
cc.y /= cc.group
# find closest centroid of each PointPtr
changed = 0 #記錄所屬簇發(fā)生變化的數(shù)據(jù)點(diǎn)的個(gè)數(shù)
for p in points:
min_i = nearest_cluster_center(p, cluster_centers)[0]
if min_i != p.group:
changed += 1
p.group = min_i
# stop when 99.9% of points are good
if changed = lenpts10:
break
for i, cc in enumerate(cluster_centers):
cc.group = i
return cluster_centers
def print_eps(points, cluster_centers, W=400, H=400):
Color = namedtuple("Color", "r g b");
colors = []
for i in xrange(len(cluster_centers)):
colors.append(Color((3 * (i + 1) % 11) / 11.0,
(7 * i % 11) / 11.0,
(9 * i % 11) / 11.0))
max_x = max_y = -FLOAT_MAX
min_x = min_y = FLOAT_MAX
for p in points:
if max_x p.x: max_x = p.x
if min_x p.x: min_x = p.x
if max_y p.y: max_y = p.y
if min_y p.y: min_y = p.y
scale = min(W / (max_x - min_x),
H / (max_y - min_y))
cx = (max_x + min_x) / 2
cy = (max_y + min_y) / 2
print "%%!PS-Adobe-3.0\n%%%%BoundingBox: -5 -5 %d %d" % (W + 10, H + 10)
print ("/l {rlineto} def /m {rmoveto} def\n" +
"/c { .25 sub exch .25 sub exch .5 0 360 arc fill } def\n" +
"/s { moveto -2 0 m 2 2 l 2 -2 l -2 -2 l closepath " +
" gsave 1 setgray fill grestore gsave 3 setlinewidth" +
" 1 setgray stroke grestore 0 setgray stroke }def")
for i, cc in enumerate(cluster_centers):
print ("%g %g %g setrgbcolor" %
(colors[i].r, colors[i].g, colors[i].b))
for p in points:
if p.group != i:
continue
print ("%.3f %.3f c" % ((p.x - cx) * scale + W / 2,
(p.y - cy) * scale + H / 2))
print ("\n0 setgray %g %g s" % ((cc.x - cx) * scale + W / 2,
(cc.y - cy) * scale + H / 2))
print "\n%%%%EOF"
def main():
npoints = 30000
k = 7 # # clusters
points = generate_points(npoints, 10)
cluster_centers = lloyd(points, k)
print_eps(points, cluster_centers)
main()
上述代碼實(shí)現(xiàn)的算法是針對(duì)二維數(shù)據(jù)的,所以Point對(duì)象有三個(gè)屬性,分別是在x軸上的值、在y軸上的值、以及所屬的簇的標(biāo)識(shí)。函數(shù)lloyd是
kmeans++算法的整體實(shí)現(xiàn),其先是通過kpp函數(shù)選取合適的種子點(diǎn),然后對(duì)數(shù)據(jù)集實(shí)行kmeans算法進(jìn)行聚類。kpp函數(shù)的實(shí)現(xiàn)完全符合上述
kmeans++的基本思路的2、3、4步。
分享標(biāo)題:python聚類核函數(shù),python做聚類
路徑分享:http://jinyejixie.com/article14/hojige.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、外貿(mào)網(wǎng)站建設(shè)、云服務(wù)器、網(wǎng)頁設(shè)計(jì)公司、移動(dòng)網(wǎng)站建設(shè)、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)