激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python使用Numpy實現Kmeans算法的步驟詳解

Python使用Numpy實現Kmeans算法的步驟詳解

2022-02-28 13:00晴一千天 Python

將物理或抽象對象的集合分成由類似的對象組成的多個類的過程被稱為聚類。這篇文章主要介紹了Python使用Numpy實現Kmeans算法,需要的朋友可以參考下

Kmeans聚類算法介紹:

1.聚類概念:

將物理或抽象對象的集合分成由類似的對象組成的多個類的過程被稱為聚類。由聚類所生成的簇是一組數據對象的集合,這些對象與同一個簇中的對象彼此相似,與其他簇中的對象相異。

2.Kmeans算法:

定義:

kmeans算法又名k均值算法,K-means算法中的k表示的是聚類為k個簇,means代表取每一個聚類中數據值的均值作為該簇的中心,或者稱為質心,即用每一個的類的質心對該簇進行描述。

大概步驟:

  • 設置初始類別中心和類別數
  • 根據類別中心對全部數據進行類別劃分:每個點分到離自己距離最小的那個類
  • 重新計算當前類別劃分下每個類的中心:例如可以取每個類別里所有的點的平均值作為新的中心。如何求多個點的平均值? 分別計算X坐標的平均值,y坐標的平均值,從而得到新的點。注意:類的中心可以不是真實的點,虛擬的點也不影響。
  • 在新的類別中心下繼續進行類別劃分;
  • 如果連續兩次的類別劃分結果不變則停止算法; 否則循環2~5。例如當類的中心不再變化時,跳出循環。

Kmeans距離測定方式:

歐式距離:

Python使用Numpy實現Kmeans算法的步驟詳解

曼哈頓距離:

Python使用Numpy實現Kmeans算法的步驟詳解

余弦相似度:

A與B表示向量(x1,y1),(x2,y2)
分子為A與B的點乘,分母為二者各自的L2相乘,即將所有維度值的平方相加后開方。

Python使用Numpy實現Kmeans算法的步驟詳解

3.如何確定最佳的k值(類別數):

本文選取手肘法

手肘法:

對于每一個k值,計算它的誤差平方和(SSE):

Python使用Numpy實現Kmeans算法的步驟詳解

其中N是點的個數,Xi 是第i 個點,ciXi 對應的中心。

  • 隨著聚類數k的增大,樣本劃分會更加精細,每個簇的聚合程度會逐漸提高,那么誤差平方和SSE自然會逐漸變小。
  • 當k小于真實聚類數時,由于k的增大會大幅增加每個簇的聚合程度,故SSE的下降幅度會很大,而當k到達真實聚類數時,再增加k所得到的聚合程度回報會迅速變小,所以SSE的下降幅度會驟減,然后隨著k值的繼續增大而趨于平緩,也就是說SSE和k的關系圖是一個手肘的形狀,而這個肘部對應的k值就是數據的真實聚類數

 

python實現Kmeans算法:

1.代碼如下:

import numpy as np
import matplotlib.pyplot as plt
import math

k = eval(input("請輸入想要劃分的類別個數")) #規定類別數
n = eval(input("請輸入要循環的次數"))#規定循環次數
sw = eval(input("請輸入想要查詢的元素在數據中的位置"))

def readdata():#獲取data數據中坐標值
  data = np.loadtxt("E:\\Python\\Lab4\\Lab4.dat")#讀取dat數據
  x_data = data[:,0]#橫坐標
  y_data = data[:,1]#縱坐標
  return data,x_data,y_data

def init(k):#初始化生成k個隨機類別中心
  data,x_data,y_data = readdata()
  class_center = []
  for i in range(k):
      #在數據的最大值與最小值間給出隨機值
      x = np.random.randint(np.min(x_data),np.max(x_data))
      y = np.random.randint(np.min(y_data),np.max(y_data))
      class_center.append(np.array([x,y]))#以數組方式添加,方便后面計算距離
  return class_center

def dist(a,b):#計算兩個坐標間的歐氏距離
  dist = math.sqrt(math.pow((a[0] - b[0]),2) + math.pow((a[1] - b[1]),2))
  return dist

def dist_rank(center,data):#得到與類中心最小距離的類別位置索引
  tem = []
  for m in range(k):
      d = dist(data, center[m])
      tem.append(d)
  loc = tem.index(min(tem))
  return loc

def means(arr):#計算類的平均值當作類的新中心
  sum_x,sum_y =0,0
  for n in arr:
      sum_x += n[0]
      sum_y += n[1]
  mean_x = sum_x / len(arr)
  mean_y = sum_y / len(arr)
  return [mean_x,mean_y]

def divide(center,data):#將每一個二維坐標分到與之歐式距離最近的類里
  cla_arr = [[]]
  for i in range(k-1):#創建與k值相同維度的空數組存取坐標
      cla_arr.append([])
  for j in range(len(data)):
      loc = dist_rank(center,data[j])
      cla_arr[loc].append(list(data[j]))
  return cla_arr

def new_center(cla):#計算每類平均值更新類中心
  new_cen = []
  for g in range(k):
      new = means(cla[g])
      new_cen.append(new)
  return new_cen

def index_element(arr,data,sw):#索引第sw個元素對應的類別
  index = []
  for i in range(len(data)):#遍歷每一個數據
      for j in range(k):#遍歷每一個類別
          tem = arr[j]
          for d in range(len(tem)):#遍歷類別內的每一個數據
              if data[i][0] == tem[d][0] and data[i][1] == tem[d][1]:#如果橫縱坐標數值都相等
                  index.append((j + 1))#歸為j+1類
              else:
                  continue
  return index[sw]

def Kmeans(n,sw):#獲取n次更新后類別中心以及第sw個元素對應的類別
  data, x_data, y_data = readdata()#讀取數據
  center = init(k)  # 獲取初始類別中心
  while n > 0:
      cla_arr = divide(center,data)# 將數據分到隨機選取的類中心的里
      center = new_center(cla_arr)#更新類別中心
      n -= 1
  sse1 = 0
  for j in range(k):
      for i in range(len(cla_arr[j])):  # 計算每個類里的誤差平方
          # 計算每個類里每個元素與元素中心的誤差平方
          dist1 = math.pow(dist(cla_arr[j][i], center[j]), 2)
          sse1 += dist1
  sse1 = sse1 / len(data)
  index = index_element(cla_arr,data,sw)
  return center,index,sse1,cla_arr
center_l, index,sse1, cla_arr = Kmeans(n,sw)
print("類別中心為:",center_l)
print("所查元素屬于類別:",index)
print('k值為{0}時的誤差平方和為{1}'.format(k,sse1))#format格式化占位輸出誤差平方和

def visualization(cla):#聚類可視化展現
  cla_x = [[]]
  cla_y = [[]]
  for m in range(k-1):#創建與k值相同維度的空數組存取x坐標和y坐標
      cla_x.append([])
      cla_y.append([])
  for i in range(k):#遍歷k次讀取k個類別
      for j in cla[i]:#遍歷每一類存取橫縱坐標
          cla_x[i].append(j[0])
          cla_y[i].append(j[1])
  plt.rcParams['axes.unicode_minus'] = False
  plt.rcParams['font.sans-serif']=['SimHei']#解決中文不能顯示的問題
  plt.figure()
  plt.xlabel("x")
  plt.ylabel("y")
  plt.title("聚類圖")
  plt.scatter(cla_x[0],cla_y[0],c = 'r',marker = 'h')
  plt.scatter(cla_x[1], cla_y[1], c='y', marker='.')
  plt.scatter(cla_x[2], cla_y[2], c='g', marker='o')
  plt.scatter(cla_x[3], cla_y[3], c='b', marker=',')
  plt.scatter(cla_x[4], cla_y[4], c='k', marker='p')
  plt.show()

visualization(cla_arr)

def hand():#畫出手肘圖
  #sse列表是循環次數為3,改變k從2到8一個一個人工測得存入
  sse = [17.840272113687078,12.116153021227769,8.563862232332205,4.092534331364449,3.573312882789776,3.42794767600246,3.2880646083752185]
  x = np.linspace(2,8,7)#創建等間距大小為7的數組
  plt.xlabel("k值")#橫坐標名稱
  plt.ylabel("誤差平方和")#縱坐標名稱
  plt.title("手肘圖")#曲線名
  plt.plot(x,sse)#畫出曲線
  plt.show()
hand()

2.代碼結果展示:

聚類可視化圖:

Python使用Numpy實現Kmeans算法的步驟詳解

手肘圖:

Python使用Numpy實現Kmeans算法的步驟詳解

運行結果:

Python使用Numpy實現Kmeans算法的步驟詳解

 

文章參考:

手肘法:K-means聚類最優k值的選取_qq_15738501的博客-CSDN博客_kmeans聚類k的選取

matplotpb.pyplot.scatter散點圖的畫法:

PYthon——plt.scatter各參數詳解_yuanCruise-CSDN博客_plt.scatter

到此這篇關于Python使用Numpy實現Kmeans算法的文章就介紹到這了,更多相關Python Kmeans算法內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_51461613/article/details/121276822

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 视频精品二区 | 久久99国产精品久久 | 免费一级欧美大片视频 | 亚洲卡通动漫在线观看 | 国产成人精品一区二区三区电影 | 久久精品黄 | 天天黄色片| 国产精品91久久久 | 九九精品在线观看 | 免费午夜视频在线观看 | 日本成人一二三区 | 麻豆视频在线播放 | 国产羞羞网站 | 800av凹凸| 羞羞视频入口 | 日韩黄色免费电影 | 97精品视频在线观看 | a黄在线观看| 毛片免费大全短视频 | 国产亚洲精品视频中文字幕 | 日本高清视频网站www | 激情久久一区二区 | 天天舔夜夜操 | 美女黄视频在线观看 | 成人毛片视频免费 | 久久久久久久免费看 | 日韩黄色精品 | 精品亚洲夜色av98在线观看 | 斗罗破苍穹在线观看免费完整观看 | 操网 | 午夜精品区 | 欧美一区二区黄色 | 亚洲日本韩国精品 | 欧美黄成人免费网站大全 | 视频一区二区视频 | 2019天天干夜夜操 | 牛牛热这里只有精品 | 国内毛片视频 | 精品一区二区三区在线观看视频 | 99久久精约久久久久久清纯 | 精品中文字幕视频 |