久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

一步步教你輕松學K

 石開九穴新聞學 2020-04-05
一步步教你輕松學K-means聚類算法
(白寧超   2018年9月13日09:10:33)

導讀:k-均值算法(英文:k-means clustering),,屬于比較常用的算法之一,文本首先介紹聚類的理論知識包括什么是聚類,、聚類的應用,、聚類思想、聚類優(yōu)缺點等等,;然后通過k-均值聚類案例實現(xiàn)及其可視化有一個直觀的感受,,針對算法模型進行分析和結(jié)果優(yōu)化提出了二分k-means算法。最后我們調(diào)用機器學習庫函數(shù),,很短的代碼完成聚類算法,。(本文原創(chuàng),轉(zhuǎn)載必須注明出處: 一步步教你輕松學K-means聚類算法

目錄

機器學習:一步步教你輕松學KNN模型算法

機器學習:一步步教你輕松學決策樹算法

機器學習:一步步教你輕松學樸素貝葉斯模型算法理論篇1 

機器學習:一步步教你輕松學樸素貝葉斯模型實現(xiàn)篇2 

機器學習:一步步教你輕松學樸素貝葉斯模型算法Sklearn深度篇3

機器學習:一步步教你輕松學邏輯回歸模型算法

機器學習:一步步教你輕松學K-means聚類算法

機器學習:一步步教你輕松學關(guān)聯(lián)規(guī)則Apriori算法

機器學習: 一步步教你輕松學支持向量機SVM算法之理論篇1

10 機器學習: 一步步教你輕松學支持向量機SVM算法之案例篇2

11 機器學習: 一步步教你輕松學主成分分析PCA降維算法

12 機器學習: 一步步教你輕松學支持向量機SVM降維算法

更多文章請點擊這里>>

理論介紹

聚類

什么是聚類

統(tǒng)計數(shù)據(jù)分析的一門技術(shù),,在許多領(lǐng)域受到廣泛應用,,包括機器學習,數(shù)據(jù)挖掘,模式識別,,圖像分析以及生物信息,。聚類是把相似的對象通過靜態(tài)分類的方法分成不同的組別或者更多的子集(subset),這樣讓在同一個子集中的成員對象都有相似的一些屬性,,常見的包括在坐標系中更加短的空間距離等,。

聚類的應用

在商務上,聚類能幫助市場分析人員從客戶基本庫中發(fā)現(xiàn)不同的客戶群,,并且用購買模式來刻畫不同的客戶群的特征,。在生物學上,聚類能用于推導植物和動物的分類,,對基因進行分類,,獲得對種群中固有結(jié)構(gòu)的認識。聚類在地球觀測數(shù)據(jù)庫中相似地區(qū)的確定,,汽車保險單持有者的分組,,及根據(jù)房子的類型、價值和地理位置對一個城市中房屋的分組上也可以發(fā)揮作用,。聚類也能用于對Web上的文檔進行分類,,以發(fā)現(xiàn)信息。諸如此類,,聚類有著廣泛的實際應用,。

K-means(k均值)聚類算法

什么是k-means聚類算法

k-平均算法(英文:k-means clustering)源于信號處理中的一種向量量化方法,現(xiàn)在則更多地作為一種聚類分析方法流行于數(shù)據(jù)挖掘領(lǐng)域,。k-平均聚類的目的是:把 n個點劃分到k個聚類中,,使得每個點都屬于離他最近的均值(此即聚類中心)對應的聚類,以之作為聚類的標準,。k-平均聚類與k-近鄰之間沒有任何關(guān)系(后者是另一流行的機器學習技術(shù)),。

K-Means 是發(fā)現(xiàn)給定數(shù)據(jù)集的 K 個簇的聚類算法, 之所以稱之為 K-均值 是因為它可以發(fā)現(xiàn) K 個不同的簇, 且每個簇的中心采用簇中所含值的均值計算而成.簇個數(shù) K 是用戶指定的, 每一個簇通過其質(zhì)心(centroid), 即簇中所有點的中心來描述.
聚類與分類算法的最大區(qū)別在于, 分類的目標類別已知, 而聚類的目標類別是未知的.

發(fā)展歷史

雖然其思想能夠追溯到1957年的Hugo Steinhaus,術(shù)語“k-均值”于1967年才被James MacQueen 首次使用,。標準算法則是在1957年被Stuart Lloyd作為一種脈沖碼調(diào)制的技術(shù)所提出,,但直到1982年才被貝爾實驗室公開出版。在1965年,,E.W.Forgy發(fā)表了本質(zhì)上相同的方法,,所以這一算法有時被稱為Lloyd-Forgy方法。更高效的版本則被Hartigan and Wong提出,。

算法描述

已知觀測集,,其中每個觀測都是一個 d-維實向量,k-平均聚類要把這 n個觀測劃分到k個集合中(k≤n),使得組內(nèi)平方和最小,。換句話說,,它的目標是找到使得下式滿足的聚類,,

其中 中所有點的均值,。

k-means術(shù)語

  • 簇: 所有數(shù)據(jù)的點集合,,簇中的對象是相似的。

  • 質(zhì)心: 簇中所有點的中心(計算所有點的均值而來).

  • SSE: Sum of Sqared Error(誤差平方和), 它被用來評估模型的好壞,,SSE 值越小,,表示越接近它們的質(zhì)心. 聚類效果越 好。由于對誤差取了平方,,因此更加注重那些遠離中心的點(一般為邊界點或離群點),。詳情見kmeans的評價標準。
    有關(guān) 簇 和 質(zhì)心 術(shù)語更形象的介紹, 請參考下圖:


k-means應用場景

kmeans,,用于數(shù)據(jù)集內(nèi)種類屬性不明晰,,希望能夠通過數(shù)據(jù)挖掘出或自動歸類出有相似特點的對象的場景。其商業(yè)界的應用場景一般為挖掘出具有相似特點的潛在客戶群體以便公司能夠重點研究,、對癥下藥,。

例如,在2000年和2004年的美國總統(tǒng)大選中,,候選人的得票數(shù)比較接近或者說非常接近,。任一候選人得到的普選票數(shù)的最大百分比為50.7%而最小百分比為47.9% 如果1%的選民將手中的選票投向另外的候選人,那么選舉結(jié)果就會截然不同,。 實際上,,如果妥善加以引導與吸引,少部分選民就會轉(zhuǎn)換立場,。盡管這類選舉者占的比例較低,,但當候選人的選票接近時,這些人的立場無疑會對選舉結(jié)果產(chǎn)生非常大的影響,。如何找出這類選民,,以及如何在有限的預算下采取措施來吸引他們? 答案就是聚類(Clustering),。

那么,,具體如何實施呢?首先,,收集用戶的信息,,可以同時收集用戶滿意或不滿意的信息,這是因為任何對用戶重要的內(nèi)容都可能影響用戶的投票結(jié)果,。然后,,將這些信息輸入到某個聚類算法中。接著,,對聚類結(jié)果中的每一個簇(最好選擇最大簇 ),, 精心構(gòu)造能夠吸引該簇選民的消息,。最后, 開展競選活動并觀察上述做法是否有效,。

另一個例子就是產(chǎn)品部門的市場調(diào)研了,。為了更好的了解自己的用戶,產(chǎn)品部門可以采用聚類的方法得到不同特征的用戶群體,,然后針對不同的用戶群體可以對癥下藥,,為他們提供更加精準有效的服務。

k-means算法思想

先隨機選取K個對象作為初始的聚類中心,。然后計算每個對象與各個種子聚類中心之間的距離,,把每個對象分配給距離它最近的聚類中心。聚類中心以及分配給它們的對象就代表一個聚類,。一旦全部對象都被分配了,,每個聚類的聚類中心會根據(jù)聚類中現(xiàn)有的對象被重新計算。這個過程將不斷重復直到滿足某個終止條件,。終止條件可以是以下任何一個:

  • 沒有(或最小數(shù)目)對象被重新分配給不同的聚類,。

  • 沒有(或最小數(shù)目)聚類中心再發(fā)生變化。

  • 誤差平方和局部最小,。

得到相互分離的球狀聚類,,在這些聚類中,均值點趨向收斂于聚類中心,。 一般會希望得到的聚類大小大致相當,,這樣把每個觀測都分配到離它最近的聚類中心(即均值點)就是比較正確的分配方案。

k-means工作流程

創(chuàng)建 k 個點作為起始質(zhì)心(通常是隨機選擇)
當任意一個點的簇分配結(jié)果發(fā)生改變時(不改變時算法結(jié)束)
    對數(shù)據(jù)集中的每個數(shù)據(jù)點
        對每個質(zhì)心
            計算質(zhì)心與數(shù)據(jù)點之間的距離
        將數(shù)據(jù)點分配到距其最近的簇
    對每一個簇, 計算簇中所有點的均值并將均值作為質(zhì)心

k-means開發(fā)流程

收集數(shù)據(jù):使用任意方法
準備數(shù)據(jù):需要數(shù)值型數(shù)據(jù)類計算距離, 也可以將標稱型數(shù)據(jù)映射為二值型數(shù)據(jù)再用于距離計算
分析數(shù)據(jù):使用任意方法
訓練算法:不適用于無監(jiān)督學習,,即無監(jiān)督學習不需要訓練步驟
測試算法:應用聚類算法,、觀察結(jié)果.可以使用量化的誤差指標如誤差平方和(后面會介紹)來評價算法的結(jié)果.
使用算法:可以用于所希望的任何應用.通常情況下, 簇質(zhì)心可以代表整個簇的數(shù)據(jù)來做出決策.

k-means評價標準

k-means算法因為手動選取k值和初始化隨機質(zhì)心的緣故,每一次的結(jié)果不會完全一樣,,而且由于手動選取k值,,我們需要知道我們選取的k值是否合理,聚類效果好不好,,那么如何來評價某一次的聚類效果呢,?也許將它們畫在圖上直接觀察是最好的辦法,但現(xiàn)實是,,我們的數(shù)據(jù)不會僅僅只有兩個特征,,一般來說都有十幾個特征,而觀察十幾維的空間對我們來說是一個無法完成的任務,。因此,,我們需要一個公式來幫助我們判斷聚類的性能,這個公式就是SSE (Sum of Squared Error, 誤差平方和 ),,它其實就是每一個點到其簇內(nèi)質(zhì)心的距離的平方值的總和,,這個數(shù)值對應kmeans函數(shù)中clusterAssment矩陣的第一列之和,。 SSE值越小表示數(shù)據(jù)點越接近于它們的質(zhì)心,聚類效果也越好,。 因為對誤差取了平方,,因此更加重視那些遠離中心的點。一種肯定可以降低SSE值的方法是增加簇的個數(shù),,但這違背了聚類的目標,。聚類的目標是在保持簇數(shù)目不變的情況下提高簇的質(zhì)量,。

k-means優(yōu)缺點

  • 優(yōu)點:

    屬于無監(jiān)督學習,,無須準備訓練集
    原理簡單,實現(xiàn)起來較為容易
    結(jié)果可解釋性較好

  • 缺點:

    聚類數(shù)目k是一個輸入?yún)?shù),。選擇不恰當?shù)膋值可能會導致糟糕的聚類結(jié)果,。這也是為什么要進行特征檢查來決定數(shù)據(jù)集的聚類數(shù)目了。
    可能收斂到局部最小值, 在大規(guī)模數(shù)據(jù)集上收斂較慢
    對于異常點,、離群點敏感

使用數(shù)據(jù)類型 : 數(shù)值型數(shù)據(jù)


k-means聚類算法實現(xiàn)

案例描述

我們假設這樣的一個案例需求:某公司發(fā)布一批新型手機,,根據(jù)客戶熱衷度進行投放。公司市場人員收集其中四個地區(qū)用戶對手機的滿意程度(由兩個特征決定的),。分析哪個區(qū)域?qū)κ謾C產(chǎn)品比較熱衷,,對應的進行市場銷售工作。這里就用到k-means聚類算法,。

從文件加載數(shù)據(jù)集

上文中我們收集好四個地區(qū)用戶對產(chǎn)品滿意的特征數(shù)據(jù)值,,轉(zhuǎn)化為向量預先保存到文本中(關(guān)于詞向量轉(zhuǎn)化及其詞袋模型問題,參考:決策樹算法模型研究與案例分析一文),。我們加載文件并以數(shù)據(jù)矩陣形式返回數(shù)據(jù)集,,代碼實現(xiàn)如下:

'''加載數(shù)據(jù)集'''
def loadDataSet(fileName):
    dataSet = [] # 初始化一個空列表
    fr = open(fileName)
    for line in fr.readlines():
        # 切割每一行的數(shù)據(jù)
        curLine = line.strip().split('\t')
        # 將數(shù)據(jù)追加到dataMat,映射所有的元素為 float類型
        fltLine = list(map(float,curLine))    
        dataSet.append(fltLine)
    return mat(dataSet)

我們打印看下結(jié)果:


計算兩個向量的歐氏距離

上文在k均值算法思想和工作流程都提到過,,我們一個重要的方法就是隨機設置質(zhì)心,,然后比較每條數(shù)據(jù)(可以理解為單一客戶的特征數(shù)據(jù))與質(zhì)心之間的距離。這里距離公式包括很多,,本文采用的是歐式距離計算,,其代碼實現(xiàn)如下:

'''歐氏距離計算函數(shù)'''
def distEclud(vecA, vecB):
    return sqrt(sum(power(vecA - vecB, 2)))

構(gòu)建一個包含 K 個隨機質(zhì)心的集合

接下來,我們構(gòu)建隨機質(zhì)心(中心點),,這里的K值是經(jīng)過數(shù)據(jù)觀察隨機設置的值,,假如k=3,代表我們將數(shù)據(jù)集分為3個簇,,也就是說分為3個部分,。我們隨機質(zhì)心在整個數(shù)據(jù)集的邊界之內(nèi),這可以通過找到數(shù)據(jù)集每一維的最小和最大值來完成,然后生成0到1.0之間的隨機數(shù)并通過取值范圍和最小值,以便確保隨機點在數(shù)據(jù)的邊界之內(nèi)

'''
隨機質(zhì)心
'''
def randCent(dataMat, k):

    # 獲取樣本數(shù)與特征值
    m, n = shape(dataMat)
    # 初始化質(zhì)心,創(chuàng)建(k,n)個以零填充的矩陣
    centroids = mat(zeros((k, n)))
    # 循環(huán)遍歷特征值
    for j in range(n):
        # 計算每一列的最小值
        minJ = min(dataMat[:, j])
        # 計算每一列的范圍值
        rangeJ = float(max(dataMat[:, j]) - minJ)
        # 計算每一列的質(zhì)心,并將值賦給centroids
        centroids[:, j] = mat(minJ + rangeJ * random.rand(k, 1))
    # 返回質(zhì)心
    return centroids 

我們測試下k=3的隨機質(zhì)心結(jié)果:


K-Means 聚類算法

我們基于以上算法構(gòu)建k均值算法,,該算法會創(chuàng)建k個質(zhì)心,,然后將每個點分配到最近的質(zhì)心,,再重新計算質(zhì)心。這個過程重復數(shù)次,,直到數(shù)據(jù)點的簇分配結(jié)果不再改變位置,。返回類質(zhì)心與點分配結(jié)果(多次運行結(jié)果可能會不一樣,可以試試,,原因為隨機質(zhì)心的影響,,但總的結(jié)果是對的,因為數(shù)據(jù)足夠相似,,也可能會陷入局部最小值),,代碼實現(xiàn)如下:

'''
創(chuàng)建K個質(zhì)心,然后將每個點分配到最近的質(zhì)心,再重新計算質(zhì)心。
這個過程重復數(shù)次,直到數(shù)據(jù)點的簇分配結(jié)果不再改變?yōu)橹?'''
def kMeans(dataMat, k, distMeas=distEclud, createCent=randCent):
    # 獲取樣本數(shù)和特征數(shù)
    m, n = shape(dataMat)
    # 初始化一個矩陣來存儲每個點的簇分配結(jié)果
    # clusterAssment包含兩個列:一列記錄簇索引值,第二列存儲誤差(誤差是指當前點到簇質(zhì)心的距離,后面會使用該誤差來評價聚類的效果)
    clusterAssment = mat(zeros((m, 2)))
    # 創(chuàng)建質(zhì)心,隨機K個質(zhì)心
    centroids = createCent(dataMat, k)
    # 初始化標志變量,用于判斷迭代是否繼續(xù),如果True,則繼續(xù)迭代
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False
        # 遍歷所有數(shù)據(jù)找到距離每個點最近的質(zhì)心,
        # 可以通過對每個點遍歷所有質(zhì)心并計算點到每個質(zhì)心的距離來完成
        for i in range(m):
            minDist = inf # 正無窮
            minIndex = -1
            for j in range(k):
                # 計算數(shù)據(jù)點到質(zhì)心的距離
                # 計算距離是使用distMeas參數(shù)給出的距離公式,默認距離函數(shù)是distEclud
                distJI = distMeas(centroids[j, :], dataMat[i, :])
                # 如果距離比minDist(最小距離)還小,更新minDist(最小距離)和最小質(zhì)心的index(索引)
                if distJI < minDist:
                    minDist = distJI
                    minIndex = j
            # 如果任一點的簇分配結(jié)果發(fā)生改變,則更新clusterChanged標志
            if clusterAssment[i, 0] != minIndex:
                # print(clusterAssment[i, 0],minIndex)
                clusterChanged = True
            # 更新簇分配結(jié)果為最小質(zhì)心的index(索引),minDist(最小距離)的平方
            clusterAssment[i, :] = minIndex, minDist ** 2
        # print(centroids)
        # 遍歷所有質(zhì)心并更新它們的取值
        for cent in range(k):
            # 通過數(shù)據(jù)過濾來獲得給定簇的所有點
            ptsInClust = dataMat[nonzero(clusterAssment[:, 0].A == cent)[0]]
            # 計算所有點的均值,axis=0表示沿矩陣的列方向進行均值計算
            centroids[cent, :] = mean(ptsInClust, axis=0)# axis=0列方向
    # 返回所有的類質(zhì)心與點分配結(jié)果
    return centroids, clusterAssment

測試查看下運行結(jié)果:


分析數(shù)據(jù):聚類可視化

通過上文返回的數(shù)據(jù)結(jié)果,,似乎我們還不能直觀感受,,接下來我們采用可視化分析方法直觀感受下,代碼實現(xiàn)如下:

'''
可視化展示
'''
def kmeanShow(dataMat,centers,clusterAssment):
    plt.scatter(np.array(dataMat)[:, 0], np.array(dataMat)[:, 1], c=np.array(clusterAssment)[:, 0].T)
    plt.scatter(centers[:, 0].tolist(), centers[:, 1].tolist(), c="r")
    plt.show()

測試查看可視化結(jié)果:


結(jié)果討論與分析

局部最小值(局部最優(yōu)的結(jié)果,,但不是全局最優(yōu)的結(jié)果)

上文可視化結(jié)果顯示,,其中兩個簇聚集在一起,也就說說沒有達到我們預期的效果,。出現(xiàn)這個問題有很多原因,,可能是k值取的不合適,可能是距離函數(shù)不合適,,可能是最初隨機選取的質(zhì)心靠的太近,,也可能是數(shù)據(jù)本身分布的問題。

為了解決這個問題,,我們可以對生成的簇進行后處理,,一種方法是將具有最大SSE值的簇劃分成兩個簇。具體實現(xiàn)時可以將最大簇包含的點過濾出來并在這些點上運行K-均值算法,,令k設為2,。

為了保持簇總數(shù)不變,可以將某兩個簇進行合并,。從上圖中很明顯就可以看出,,應該將上圖下部兩個出錯的簇質(zhì)心進行合并。那么問題來了,,我們可以很容易對二維數(shù)據(jù)上的聚類進行可視化,, 但是如果遇到40維的數(shù)據(jù)應該如何去做?

有兩種可以量化的辦法:合并最近的質(zhì)心,,或者合并兩個使得SSE增幅最小的質(zhì)心,。 第一種思路通過計算所有質(zhì)心之間的距離, 然后合并距離最近的兩個點來實現(xiàn),。第二種方法需要合并兩個簇然后計算總SSE值,。必須在所有可能的兩個簇上重復上述處理過程,,直到找到合并最佳的兩個簇為止。

因為上述后處理過程實在是有些繁瑣,,所以有更厲害的大佬提出了另一個稱之為二分K-均值(bisecting K-Means)的算法.

二分 K-Means 聚類算法

算法描述

該算法首先將所有點作為一個簇,,然后將該簇一分為二。之后選擇其中一個簇繼續(xù)進行劃分,,選擇哪一個簇進行劃分取決于對其劃分時候可以最大程度降低 SSE(平方和誤差)的值,。上述基于 SSE 的劃分過程不斷重復,直到得到用戶指定的簇數(shù)目為止,。

二分 K-Means 聚類算法偽代碼

將所有點看成一個簇
當簇數(shù)目小于 k 時
對于每一個簇
    計算總誤差
    在給定的簇上面進行 KMeans 聚類(k=2)
    計算將該簇一分為二之后的總誤差
選擇使得誤差最小的那個簇進行劃分操作

另一種做法是選擇 SSE 最大的簇進行劃分,,直到簇數(shù)目達到用戶指定的數(shù)目位置。

二分 K-Means 聚類算法代碼

根據(jù)算法思想,,我們基于k均值算法做了少許的改動,,代碼實現(xiàn)如下:

'''在給定數(shù)據(jù)集,所期望的簇數(shù)目和距離計算方法的條件下,函數(shù)返回聚類結(jié)果'''
def biKmeans(dataMat, k, distMeas=distEclud):
    m, n = shape(dataMat)
    # 創(chuàng)建一個矩陣來存儲數(shù)據(jù)集中每個點的簇分配結(jié)果及平方誤差
    clusterAssment = mat(zeros((m, 2)))
    # 計算整個數(shù)據(jù)集的質(zhì)心,并使用一個列表來保留所有的質(zhì)心
    centroid0 = mean(dataMat, axis=0).tolist()[0]
    centList = [centroid0] # [-0.15772275000000002, 1.2253301166666664]
    # 遍歷數(shù)據(jù)集中所有點來計算每個點到質(zhì)心的誤差值
    for j in range(m):
        clusterAssment[j, 1] = distMeas(mat(centroid0), dataMat[j, :]) ** 2
    # 對簇不停的進行劃分,直到得到想要的簇數(shù)目為止
    while (len(centList) < k):
        # 初始化最小SSE為無窮大,用于比較劃分前后的SSE
        lowestSSE = inf
        # 通過考察簇列表中的值來獲得當前簇的數(shù)目,遍歷所有的簇來決定最佳的簇進行劃分
        for i in range(len(centList)):
            # 對每一個簇,將該簇中的所有點堪稱一個小的數(shù)據(jù)集
            ptsInCurrCluster = dataMat[nonzero(clusterAssment[:, 0].A == i)[0], :]
            # 將ptsInCurrCluster輸入到函數(shù)kMeans中進行處理,k=2,
            # kMeans會生成兩個質(zhì)心(簇),同時給出每個簇的誤差值
            centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas)
            # 將誤差值與剩余數(shù)據(jù)集的誤差之和作為本次劃分的誤差
            sseSplit = sum(splitClustAss[:, 1])
            sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:, 0].A != i)[0], 1])
            print('sseSplit, and notSplit: ', sseSplit, sseNotSplit)
            # 如果本次劃分的SSE值最小,則本次劃分被保存
            if (sseSplit + sseNotSplit) < lowestSSE:
                bestCentToSplit = i
                bestNewCents = centroidMat
                bestClustAss = splitClustAss.copy()
                lowestSSE = sseSplit + sseNotSplit
        # 找出最好的簇分配結(jié)果
        # 調(diào)用kmeans函數(shù)并且指定簇數(shù)為2時,會得到兩個編號分別為0和1的結(jié)果簇
        bestClustAss[nonzero(bestClustAss[:, 0].A == 1)[0], 0] = len(centList)
        # 更新為最佳質(zhì)心
        bestClustAss[nonzero(bestClustAss[:, 0].A == 0)[0], 0] = bestCentToSplit
        print('the bestCentToSplit is: ', bestCentToSplit)
        print('the len of bestClustAss is: ', len(bestClustAss))
        # 更新質(zhì)心列表
        # 更新原質(zhì)心list中的第i個質(zhì)心為使用二分kMeans后bestNewCents的第一個質(zhì)心
        centList[bestCentToSplit] = bestNewCents[0, :].tolist()[0]
        # 添加bestNewCents的第二個質(zhì)心
        centList.append(bestNewCents[1, :].tolist()[0])
        # 重新分配最好簇下的數(shù)據(jù)(質(zhì)心)以及SSE
        clusterAssment[nonzero(clusterAssment[:, 0].A == bestCentToSplit)[0], :] = bestClustAss
    return mat(centList), clusterAssment

測試二分 KMeans 聚類算法

經(jīng)過改進后,,我們運行biKmeans函數(shù)得到可視化結(jié)果如下:


總結(jié):如此我們得到預想的結(jié)果,,解決了局部最優(yōu)的問題,聚類會收斂到全局最小值,。而原始的 kMeans() 函數(shù)偶爾會陷入局部最小值,。

調(diào)用機器學習庫sklearn實現(xiàn)k-means 聚類

加載數(shù)據(jù)集

# 加載數(shù)據(jù)集
dataMat = []
fr = open("./testSet2.txt") # 注意,這個是相對路徑
for line in fr.readlines():
    curLine = line.strip().split('\t')
    fltLine = list(map(float,curLine))    # 映射所有的元素為 float(浮點數(shù))類型
    dataMat.append(fltLine)

訓練k-means算法模型

km = KMeans(n_clusters=3) # 初始化
km.fit(dataMat) # 擬合
km_pred = km.predict(dataMat) # 預測
centers = km.cluster_centers_ # 質(zhì)心

可視化結(jié)果

plt.scatter(np.array(dataMat)[:, 1], np.array(dataMat)[:, 0], c=km_pred)
plt.scatter(centers[:, 1], centers[:, 0], c="r")
plt.show()

聚類結(jié)果


參考文獻

  1. scikit中文社區(qū):http://sklearn./cn/0.19.0/

  2. 中文維基百科:https://zh./wiki/K-%E5%B9%B3%E5%9D%87%E7%AE%97%E6%B3%95

  3. GitHub:https://github.com/BaiNingchao/MachineLearning-1

  4. 圖書:《機器學習實戰(zhàn)》

  5. 圖書:《自然語言處理理論與實戰(zhàn)》

完整代碼下載

源碼請進【機器學習和自然語言QQ群:436303759】文件下載:


作者聲明

本文版權(quán)歸作者所有,,旨在技術(shù)交流使用,。未經(jīng)作者同意禁止轉(zhuǎn)載,轉(zhuǎn)載后需在文章頁面明顯位置給出原文連接,,否則相關(guān)責任自行承擔,。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多