您現在的位置是:首頁 > 網路遊戲首頁網路遊戲
python之kmeans資料聚類演算法
- 2023-01-02
歐式距離怎麼計算方法
一 Kmeans原理
kmeans是屬於無監督學習的資料聚類演算法,根據點與點之間的距離推測每個點屬於哪個中心,常用計算距離的方式有:餘弦距離、歐式距離、曼哈頓距離等,本文以歐式距離為例。圖1假設每個點的維度是n,即每個點有n個特徵維度,計算這些點資料到資料中心A、B、C的距離,從而將每個資料歸類到A或B或C。
圖1
歐式距離公式:
圖2
假設1點的資料為:
A中心資料為:
歐式公式計算為:
圖3
kmeans實現邏輯:
需要輸入待聚類的資料和欲聚類簇數k
1。隨機生成k個初始點作為質心
2。將資料集中的資料按照距離質心的遠近分到各個簇中
3。對每個簇的資料求平均值,作為新的質心,重複上一步,直到所有的簇不再改變
k是聚類個數,可以根據我們的經驗給數值,也可以透過程式初步預測k設定為多少對聚類最準確。本章透過變化k的個數,計算k取不同值時,最後的誤差多少,誤差越小,則k最準確。
二 資料準備
對資料進行聚類,要對測試資料進行清洗。一般程式碼都是對數值型資料進行計算,所以如果測試資料是漢字或其他型別的資訊,我們要對其進行量化。本案例透過鏈家資料進行測試,透過學習,可以學習python機器學習的一般步驟和整個過程。圖4是初始資料,其中面積特徵、格局特徵、裝修特徵都需要量化成數值型,大家可以根據實際情況進行量化。比如精裝對應80,簡裝對應30,毛坯對應10等,本文對這些數值進行如下量化,同時將面積的單位平米去掉,最終訓練資料見圖5。
簡裝:0 精裝:1 毛坯:3
東:0 西:1 南:2 北:3
圖4
圖5
三 程式
1、對初始k進行預測
# 歐氏距離計算
def distEclud(x,y):
return np。sqrt(np。sum((x-y)**2)) # 計算歐氏距離
# 為給定資料集構建一個包含K個隨機質心的集合
def randCent(dataSet,k):
m,n = dataSet。shape
centroids = np。zeros((k,n))
for i in range(k):
index = int(np。random。uniform(0,m))
centroids[i,:] = dataSet[index,:]
return centroids
def cost(dataMat, k, distMeas=distEclud, createCent=randCent,iterNum=300):
# 獲取樣本數和特徵數
m, n = np。shape(dataMat)
# 初始化一個矩陣來儲存每個點的簇分配結果
# clusterAssment包含兩個列:一列記錄簇索引值,第二列儲存誤差(誤差是指當前點到簇質心的距離,後面會使用該誤差來評價聚類的效果)
clusterAssment = np。mat(np。zeros((m, 2)))
# 建立質心,隨機K個質心
centroids = createCent(dataMat, k)
clusterChanged = True
while iterNum > 0:
clusterChanged = False
# 遍歷所有資料找到距離每個點最近的質心,
# 可以透過對每個點遍歷所有質心並計算點到每個質心的距離來完成
for i in range(m):
minDist = np。inf
minIndex = -1
for j in range(k):
# 計算資料點到質心的距離
distJI = distMeas(centroids[j, :], dataMat[i, :])
# 如果距離比minDist(最小距離)還小,更新minDist(最小距離)和最小質心的index(索引)
if distJI < minDist:
minDist = distJI
minIndex = j
# 更新簇分配結果為最小質心的index(索引),minDist(最小距離)的平方
clusterAssment[i, :] = minIndex, minDist ** 2
iterNum -= 1;
# print(centroids)
# 遍歷所有質心並更新它們的取值
for cent in range(k):
# 透過資料過濾來獲得給定簇的所有點
ptsInClust = dataMat[np。nonzero(clusterAssment[:, 0]。A == cent)[0]]
# 計算所有點的均值,axis=0表示沿矩陣的列方向進行均值計算
centroids[cent, :] = np。mean(ptsInClust, axis=0)
# 返回給定迭代次數後誤差的值
return np。mat(clusterAssment[:,1]。sum(0))[0,0]
呼叫上述方法預測k,見圖6,所以k可以取值:2、3、5等,可以結合實際需要進行選取。本文資料可能比較不典型,正常情況下,曲線應該是單一方向的上升或下降趨勢,我們取轉折點作為k的值。
dataSet = loadDataSet(“test。txt”)
allcost=[]
x=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
k=1
while k <19:
a=cost(dataSet, 2, distMeas=distEclud, createCent=randCent,iterNum=300)
allcost。append(a)
k = k+1
圖6
2 kmean演算法程式
圖7
3、繪製資料點
本文資料不是二維資料,而是5維資料,我們需要安裝plotly來實現多維資料的繪製,從繪製的資料點我們可以形象的看出資料都聚集在2大塊,所以聚類K應該取2比較合適。
圖8
x:面積,y:朝向,z:總價,實現三維圖形,格局特徵我們透過點大小描繪,裝修特徵我們透過點顏色標誌,透過如此,5維資料都可以在圖上展示出來了。
import pandas as pd
import plotly
import plotly。graph_objs as go
dataPath = ‘C:/Users/xzx/Desktop/linkHomeData。xlsx’
data = pd。read_excel(dataPath,sheet_name=‘Sheet2’)
#Set marker properties
markersize = data[‘geju’]/3
markercolor = data[‘zhuangxiu’]
#Make Plotly figure
fig1 = go。Scatter3d(x=data[‘mianji’],
y=data[‘chaoxiang’],
z=data[‘price’],
marker=dict(size=markersize,
color=markercolor,
opacity=0。9,
reversescale=True,
colorscale=‘Blues’),
line=dict (width=0。02),
mode=‘markers’)
#Make Plot。ly Layout
mylayout = go。Layout(scene=dict(xaxis=dict( title=“面積”),
yaxis=dict( title=“朝向”),
zaxis=dict(title=“總價”)),)
#Plot and save html
plotly。offline。plot({“data”: [fig1],
“layout”: mylayout},
auto_open=True,
filename=(“5D Plot。html”))
圖9
四 總結
本文講述了kmeans演算法的原理,聚類中心K個數的選取,kmeans演算法的一般步驟,以及如何繪製多維圖形。