100天搞定機器學習|day44 k均值聚類數學推導與python實現

[如何正確使用「K均值聚類」?html

一、k均值聚類模型給定樣本file,每一個樣本都是m爲特徵向量,模型目標是將n個樣本分到k個不停的類或簇中,每一個樣本到其所屬類的中心的距離最小,每一個樣本只能屬於一個類。用C表示劃分,他是一個多對一的函數,k均值聚類就是一個從樣本到類的函數。二、k均值聚類策略k均值聚類的策略是經過損失函數最小化選取最優的劃分或函數file。首先,計算樣本之間的距離,這裏選歐氏距離平方。file而後定義樣本與其所屬類的中心之間的距離的總和爲損失函數file其中file爲第l個類的均值或中心file,是指示函數,取值1或0.k均值聚類就是求解最優化問題:file三、k均值聚類算法k均值聚類的算法是一個迭代過程,首先:對於給定中心值file,求劃分C,是目標函數極小化:file即,類中心肯定的狀況下,將樣本分到一個類中,使樣本和其所屬類的中心之間的距離總和最小。而後:對於給定的劃分C,再求各個類的中心,是目標函數極小化。git

即,劃分C肯定的狀況下,使樣本和其所屬類的中心之間的距離總和最小。求解結果,對於每一個包含nl個樣本的類Gi,更新其均值ml:file重複以上兩個步驟,知道分化不在改變。github

from myUtil import *

def kMeans(dataSet, k):
    m = shape(dataSet)[0]  # 返回矩陣的行數

    # 本算法核心數據結構:行數與數據集相同
    # 列1:數據集對應的聚類中心,列2:數據集行向量到聚類中心的距離
    ClustDist = mat(zeros((m, 2)))

    # 隨機生成一個數據集的聚類中心:本例爲4*2的矩陣
    # 確保該聚類中心位於min(dataSet[:,j]),max(dataSet[:,j])之間
    clustercents = randCenters(dataSet, k)  # 隨機生成聚類中心

    flag = True  # 初始化標誌位,迭代開始
    counter = []  # 計數器

    # 循環迭代直至終止條件爲False
    # 算法中止的條件:dataSet的全部向量都能找到某個聚類中心,到此中心的距離均小於其餘k-1箇中心的距離
    while flag:
        flag = False  # 預置標誌位爲False

        # ---- 1. 構建ClustDist:遍歷DataSet數據集,計算DataSet每行與聚類的最小歐式距離 ----#
        # 將此結果賦值ClustDist=[minIndex,minDist]
        for i in xrange(m):

            # 遍歷k個聚類中心,獲取最短距離
            distlist = [distEclud(clustercents[j, :], dataSet[i, :]) for j in range(k)]
            minDist = min(distlist)
            minIndex = distlist.index(minDist)

            if ClustDist[i, 0] != minIndex:  # 找到了一個新聚類中心
                flag = True  # 重置標誌位爲True,繼續迭代

            # 將minIndex和minDist**2賦予ClustDist第i行
            # 含義是數據集i行對應的聚類中心爲minIndex,最短距離爲minDist
            ClustDist[i, :] = minIndex, minDist

        # ---- 2.若是執行到此處,說明還有須要更新clustercents值: 循環變量爲cent(0~k-1)----#
        # 1.用聚類中心cent切分爲ClustDist,返回dataSet的行索引
        # 並以此從dataSet中提取對應的行向量構成新的ptsInClust
        # 計算分隔後ptsInClust各列的均值,以此更新聚類中心clustercents的各項值
        for cent in xrange(k):
            # 從ClustDist的第一列中篩選出等於cent值的行下標
            dInx = nonzero(ClustDist[:, 0].A == cent)[0]
            # 從dataSet中提取行下標==dInx構成一個新數據集
            ptsInClust = dataSet[dInx]
            # 計算ptsInClust各列的均值: mean(ptsInClust, axis=0):axis=0 按列計算
            clustercents[cent, :] = mean(ptsInClust, axis=0)
    return clustercents, ClustDist複製代碼

參考:https://jakevdp.github.io/PythonDataScienceHandbookhttps://www.cnblogs.com/eczhou/p/7860424.html統計學習方法14.3file算法

首發於微信公衆號:機器學習與統計學
![歡迎掃碼關注,領取海量資料][1]微信

[1]: https://img2018.cnblogs.com/blog/743008/201907/743008-20190725101305454-1314391880.png數據結構

相關文章
相關標籤/搜索