最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python Kmeans算法原理深入解析

 更新時間:2019年08月23日 09:04:43   作者:zzzzMing  
這篇文章主要介紹了python Kmeans算法深入解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

一. 概述

首先需要先介紹一下無監(jiān)督學習,所謂無監(jiān)督學習,就是訓練樣本中的標記信息是位置的,目標是通過對無標記訓練樣本的學習來揭示數(shù)據(jù)的內(nèi)在性質(zhì)以及規(guī)律。通俗得說,就是根據(jù)數(shù)據(jù)的一些內(nèi)在性質(zhì),找出其內(nèi)在的規(guī)律。而這一類算法,應(yīng)用最為廣泛的就是“聚類”。

聚類算法可以對數(shù)據(jù)進行數(shù)據(jù)歸約,即在盡可能保證數(shù)據(jù)完整的前提下,減少數(shù)據(jù)的量級,以便后續(xù)處理。也可以對聚類數(shù)據(jù)結(jié)果直接應(yīng)用或分析。

而Kmeans 算法可以說是聚類算法里面較為基礎(chǔ)的一種算法。

二. 從樣例開始

我們現(xiàn)在在二維平面上有這樣一些點

   x         y
1.658985    4.285136
-3.453687    3.424321
4.838138    -1.151539
-5.379713    -3.362104
0.972564    2.924086
-3.567919    1.531611
0.450614    -3.302219
-3.487105    -1.724432
2.668759    1.594842
-3.156485    3.191137
3.165506    -3.999838
-2.786837    -3.099354
4.208187    2.984927
-2.123337    2.943366
0.704199    -0.479481
-0.392370    -3.963704
2.831667    1.574018
-0.790153    3.343144
2.943496    -3.357075
...

它在二維平面上的分布大概是這樣的:

好,這些點看起來隱約分成4個“簇”,那么我們可以假定它就是要分成4個“簇”。(雖然我們可以“看”出來是要分成4個“簇”,但實際上也可以分成其他個,比如說5個。)這里分成“4個簇“是我們看出來的。而在實際應(yīng)用中其實應(yīng)該由機器算得,下面也會有介紹的。

找出4個”簇”之后,就要找出每個“簇”的中心了,我們可以“看出”大概的中心點,但機器不知道啊。那么機器是如何知道的呢?答案是通過向量距離,也叫向量相似性。這個相似性計算有多種方法,比如歐式距離,曼哈頓距離,切比雪夫距離等等。

我們這里使用的是歐式距離,歐式距離其實就是反應(yīng)空間中兩點的直線距離。

知道這些后,我們就可以開始讓機器計算出4個“簇”了。

主要做法是這樣,先隨機生成4個點,假設(shè)這4個點就是4個“簇”的中心。計算平面中每個點到4個中心點的距離,平面中每個點選取距離最近的那個中心作為自己的中心。

此時我們就完成第一步,將平面中所有點分成4個”簇“。但是剛剛那幾個中心都是隨機的,這樣分成的4個簇明顯不是我們想要的結(jié)果。怎么辦呢?做法如下:

現(xiàn)在有4個簇,根據(jù)每個簇中所有點計算出每個簇的新中心點。這個新中心點就會比上一個舊的中心點更優(yōu),因為它更加中心。然后使用新中心點重復第一步的步驟。即再對平面中所有點算距離,然后分發(fā)到4個新簇中。不斷迭代,直到誤差較小。

這就是 Kmeans 算法的過程了。

三. 知識點淺析

3.1 確定“簇”的個數(shù)

上面所說的分成 4 個簇,這個 4 其實就是 Kmeans 中的K。要使用 Kmeans 首先就是要選取一個 K 作為聚類個數(shù)。而上面的例子其實是我們主觀”看“出來的,但多數(shù)情況下我們是無法直觀”看“出分多少個 K 比較好。那怎么辦呢?

我們可以從較低的 K 值開始。使用較簡單的 Kmeans 算法的結(jié)果(即較少的迭代次數(shù),不求最佳結(jié)果,但求最快)。計算每個點到其歸屬的“簇”的中心點的距離,然后求和,求和結(jié)果就是誤差值。

然后再增加 K 值,再計算誤差值。比如上面的例子,我們可以從 K=2 開始,計算 K 值從 2 到 7 的 Kmeans 算法的誤差值。
這樣會得到類似這樣一張圖:

里面的 Error 可以理解未 Kmeans 的誤差,而當分成越多“簇”的適合,誤差肯定是越來越小。

但是不是“簇”越多越好呢?答案是否定的,有時候“簇”過多的話是不利于我們得到想要的結(jié)果或是做下一步操作的。

所以我們通常會選擇誤差減小速度比較平緩的那個臨界點,比如上圖中的 4。

可以發(fā)現(xiàn),在分成 4 個簇之后,再增加簇的數(shù)量,誤差也不會有很大的減少。而取 4 個簇也和我們所看到的相符。

3.2 歐式距離

歐氏距離是一個通常采用的距離定義,指在m維空間中兩個點之間的真實距離,計算公式如下:

而本例種的是在二維空間種,故而本例的計算公式如下:

四. 代碼和結(jié)果

加載數(shù)據(jù)的代碼,使用了 numpy ,先是將代碼加載成 matrix 類型。

import numpy as np

def loadDataSet(fileName):
  '''
  加載數(shù)據(jù)集
  :param fileName:
  :return:
  '''
  # 初始化一個空列表
  dataSet = []
  # 讀取文件
  fr = open(fileName)
  # 循環(huán)遍歷文件所有行
  for line in fr.readlines():
    # 切割每一行的數(shù)據(jù)
    curLine = line.strip().split('\t')
    # 將數(shù)據(jù)轉(zhuǎn)換為浮點類型,便于后面的計算
    # fltLine = [float(x) for x in curLine]
    # 將數(shù)據(jù)追加到dataMat
    fltLine = list(map(float,curLine))  # 映射所有的元素為 float(浮點數(shù))類型
    dataSet.append(fltLine)
  # 返回dataMat
  return np.matrix(dataSet)

接下來需要生成 K 個初始的質(zhì)點,即中心點。這里采用隨機生成的方法生成 k 個“簇”。

def randCent(dataMat, k):
  '''
  為給定數(shù)據(jù)集構(gòu)建一個包含K個隨機質(zhì)心的集合,
  隨機質(zhì)心必須要在整個數(shù)據(jù)集的邊界之內(nèi),這可以通過找到數(shù)據(jù)集每一維的最小和最大值來完成
  然后生成0到1.0之間的隨機數(shù)并通過取值范圍和最小值,以便確保隨機點在數(shù)據(jù)的邊界之內(nèi)
  :param dataMat:
  :param k:
  :return:
  '''
  # 獲取樣本數(shù)與特征值
  m, n = np.shape(dataMat)
  # 初始化質(zhì)心,創(chuàng)建(k,n)個以零填充的矩陣
  centroids = np.mat(np.zeros((k, n)))
  # 循環(huán)遍歷特征值
  for j in range(n):
    # 計算每一列的最小值
    minJ = min(dataMat[:, j])
    # 計算每一列的范圍值
    rangeJ = float(max(dataMat[:, j]) - minJ)
    # 計算每一列的質(zhì)心,并將值賦給centroids
    centroids[:, j] = np.mat(minJ + rangeJ * np.random.rand(k, 1))
  # 返回質(zhì)心
  return centroids

歐式距離計算

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

cost 方法將執(zhí)行一個簡化的 kMeans ,即較少次數(shù)的迭代,計算出其中的誤差(即當前點到簇質(zhì)心的距離,后面會使用該誤差來評價聚類的效果)

def cost(dataMat, k, distMeas=distEclud, createCent=randCent,iterNum=300):
  '''
  計算誤差的多少,通過這個方法來確定 k 為多少比較合適,這個其實就是一個簡化版的 kMeans
  :param dataMat: 數(shù)據(jù)集
  :param k: 簇的數(shù)目
  :param distMeans: 計算距離
  :param createCent: 創(chuàng)建初始質(zhì)心
  :param iterNum:默認迭代次數(shù)
  :return:
  '''
  # 獲取樣本數(shù)和特征數(shù)
  m, n = np.shape(dataMat)
  # 初始化一個矩陣來存儲每個點的簇分配結(jié)果
  # clusterAssment包含兩個列:一列記錄簇索引值,第二列存儲誤差(誤差是指當前點到簇質(zhì)心的距離,后面會使用該誤差來評價聚類的效果)
  clusterAssment = np.mat(np.zeros((m, 2)))
  # 創(chuàng)建質(zhì)心,隨機K個質(zhì)心
  centroids = createCent(dataMat, k)
  clusterChanged = True
  while iterNum > 0:
    clusterChanged = False
    # 遍歷所有數(shù)據(jù)找到距離每個點最近的質(zhì)心,
    # 可以通過對每個點遍歷所有質(zhì)心并計算點到每個質(zhì)心的距離來完成
    for i in range(m):
      minDist = np.inf
      minIndex = -1
      for j in range(k):
        # 計算數(shù)據(jù)點到質(zhì)心的距離
        # 計算距離是使用distMeas參數(shù)給出的距離公式,默認距離函數(shù)是distEclud
        distJI = distMeas(centroids[j, :], dataMat[i, :])
        # print(distJI)
        # 如果距離比minDist(最小距離)還小,更新minDist(最小距離)和最小質(zhì)心的index(索引)
        if distJI < minDist:
          minDist = distJI
          minIndex = j
      # 更新簇分配結(jié)果為最小質(zhì)心的index(索引),minDist(最小距離)的平方
      clusterAssment[i, :] = minIndex, minDist ** 2
      iterNum -= 1;
    # print(centroids)
    # 遍歷所有質(zhì)心并更新它們的取值
    for cent in range(k):
      # 通過數(shù)據(jù)過濾來獲得給定簇的所有點
      ptsInClust = dataMat[np.nonzero(clusterAssment[:, 0].A == cent)[0]]
      # 計算所有點的均值,axis=0表示沿矩陣的列方向進行均值計算
      centroids[cent, :] = np.mean(ptsInClust, axis=0)
  # 返回給定迭代次數(shù)后誤差的值
  return np.mat(clusterAssment[:,1].sum(0))[0,0]

最后可以調(diào)用 Kmeans 算法來進行計算。

def kMeans(dataMat, k, distMeas=distEclud, createCent=randCent):
  '''
  創(chuàng)建K個質(zhì)心,然后將每個店分配到最近的質(zhì)心,再重新計算質(zhì)心。
  這個過程重復數(shù)次,直到數(shù)據(jù)點的簇分配結(jié)果不再改變?yōu)橹?
  :param dataMat: 數(shù)據(jù)集
  :param k: 簇的數(shù)目
  :param distMeans: 計算距離
  :param createCent: 創(chuàng)建初始質(zhì)心
  :return:
  '''
  # 獲取樣本數(shù)和特征數(shù)
  m, n = np.shape(dataMat)
  # 初始化一個矩陣來存儲每個點的簇分配結(jié)果
  # clusterAssment包含兩個列:一列記錄簇索引值,第二列存儲誤差(誤差是指當前點到簇質(zhì)心的距離,后面會使用該誤差來評價聚類的效果)
  clusterAssment = np.mat(np.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 = np.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: clusterChanged = True
      # 更新簇分配結(jié)果為最小質(zhì)心的index(索引),minDist(最小距離)的平方
      clusterAssment[i, :] = minIndex, minDist ** 2
    # print(centroids)
    # 遍歷所有質(zhì)心并更新它們的取值
    for cent in range(k):
      # 通過數(shù)據(jù)過濾來獲得給定簇的所有點
      ptsInClust = dataMat[np.nonzero(clusterAssment[:, 0].A == cent)[0]]
      # 計算所有點的均值,axis=0表示沿矩陣的列方向進行均值計算
      centroids[cent, :] = np.mean(ptsInClust, axis=0)
  # 返回所有的類質(zhì)心與點分配結(jié)果
  return centroids, clusterAssment

選取不同的 k 值對結(jié)果影響有多大呢?我們來看看就知道了,下面給出的是 k 值為 2 到 6 的效果。
圖中紅色方塊即為“簇”的中心點,每個“簇”所屬的點用不同的顏色表示。

K = 2

K = 3

K = 4

K = 5

K = 6

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python語言實現(xiàn)機器學習的K-近鄰算法

    Python語言實現(xiàn)機器學習的K-近鄰算法

    今天學習的算法是KNN近鄰算法。KNN算法是一個監(jiān)督學習分類器類別的算法。下面我們來詳細的探討下
    2015-06-06
  • Python CSV模塊使用實例

    Python CSV模塊使用實例

    這篇文章主要介紹了Python CSV模塊使用實例,本文將舉幾個例子來介紹一下Python的CSV模塊的使用方法,包括reader、writer、DictReader、DictWriter.register_dialect等,需要的朋友可以參考下
    2015-04-04
  • Python驗證的50個常見正則表達式

    Python驗證的50個常見正則表達式

    這篇文章主要給大家介紹了關(guān)于利用Python驗證的50個常見正則表達式的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Python numpy ndarray屬性,索引,切片

    Python numpy ndarray屬性,索引,切片

    這篇文章主要介紹了Python numpy ndarray屬性,索引,切片,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • python翻譯軟件實現(xiàn)代碼(使用google api完成)

    python翻譯軟件實現(xiàn)代碼(使用google api完成)

    這篇文章主要介紹了python結(jié)合google api完成的翻譯軟件實現(xiàn)代碼,大家參考使用
    2013-11-11
  • PyCharm第一次安裝及使用教程

    PyCharm第一次安裝及使用教程

    本文通過圖文并茂的形式給大家介紹PyCharm第一次安裝及使用教程,分步驟通過實際案例給大家操作演示,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • Python3中類、模塊、錯誤與異常、文件的簡易教程

    Python3中類、模塊、錯誤與異常、文件的簡易教程

    這篇文章主要給大家介紹了關(guān)于Python3中類、模塊、錯誤與異常、文件的相關(guān)教程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-11-11
  • python將html轉(zhuǎn)成PDF的實現(xiàn)代碼(包含中文)

    python將html轉(zhuǎn)成PDF的實現(xiàn)代碼(包含中文)

    python將html轉(zhuǎn)成PDF的實現(xiàn)代碼,需要用到xhtml2pdf和微軟雅黑字體,需要的朋友可以參考下
    2013-03-03
  • 完美解決TensorFlow和Keras大數(shù)據(jù)量內(nèi)存溢出的問題

    完美解決TensorFlow和Keras大數(shù)據(jù)量內(nèi)存溢出的問題

    這篇文章主要介紹了完美解決TensorFlow和Keras大數(shù)據(jù)量內(nèi)存溢出的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • Python中使用moviepy進行視頻分割的實現(xiàn)方法

    Python中使用moviepy進行視頻分割的實現(xiàn)方法

    MoviePy是一個關(guān)于視頻編輯的python庫,主要包括:剪輯,嵌入拼接,標題插入,視頻合成(又名非線性編輯),視頻處理,和自定制效果。本文重點給大家介紹Python中使用moviepy進行視頻分割的實現(xiàn)方法,需要的朋友一起看看吧
    2021-12-12

最新評論

石棉县| 甘南县| 英山县| 威海市| 永宁县| 新平| 毕节市| 富阳市| 蒲城县| 乐业县| 雅安市| 定日县| 西丰县| 佛坪县| 泰和县| 肥乡县| 桂东县| 宣武区| 西华县| 黄陵县| 钟山县| 永福县| 柳江县| 剑河县| 班戈县| 揭西县| 微山县| 大竹县| 余江县| 册亨县| 青浦区| 健康| 延吉市| 泗洪县| 正镶白旗| 阳曲县| 花莲县| 沙湾县| 定安县| 梁山县| 宜阳县|