機器學習實戰(二) 聚類

2021-08-19 16:19:04 字數 4466 閱讀 7148

回想專案中遇到的,多商家資訊融合的場景。我們如何把多商家的資訊進行合理的匹配呢?首先想到的是人工匹配和程式匹配相結合。這樣也可以實現,但費心費力,且實際匹配效果很差,如果商家融合資訊呈指數級增長,這樣的方式就太low了。

那如何把這個流程做的智慧型化些呢?我們可以引入機器學習中的聚類,它可以將商家相關屬性進行聚集,並分類。

簇: 所有資料點點集合,簇中物件相似。

質心: 簇中所有點的中心(計算所有點的均值).

採用歐式距離,兩點間直線距離.也可採用其他距離計算(後期會做相應的介紹)

sse 值越小,表示越接近它們的質心.由於代價函式(sse)是非凸函式,所以在運用kmeans演算法時,不能保證收斂到乙個全域性的最優解,我們得到的一般是乙個區域性的最優解。

為了取得比較好的效果,用不同的初始質心執行,得到多個區域性最優解,比較它們的sse,選取sse最小的那個。

#載入資料

def loaddataset(filename):

datamat =

fr = open(filename)

for line in fr.readlines():

curline = line.strip().split('\t')

ftlline = map(float,curline) #資料初始化float型別

return datamat

#歐式距離

def disteclud(veca, vecb):

return sqrt(sum(power(veca -vecb,2)))

# power 樣本點平方((x1-x2)^2+(y1-y2)^2)

# sqrt 求和後開方

#構建k個隨機質心

def randcent(dataset, k):

n = shape(dataset)[1] #獲得列數

centroids = mat(zeros((k,n))) #k行n列的零階矩陣

for j in range(n):

minj = min(dataset[:,j])

rangej = float(max(dataset[:,j]) - minj)

centroids[:,j] = minj + rangej * random.rand(k,1)

return centroids

(1)k-均值

#kmeans

def kmeans(dataset, k, distmeas=disteclud, createcent=randcent):

m = shape(dataset)[0] #樣本數

clusterassment = mat(zeros((m,2))) #獲得m*2矩陣(一列簇分類結果,一列誤差)

centroids = createcent(dataset,k) #初始化k個質心

clusterchanged = true #簇更改標記

while clusterchanged:

clusterchanged = false

#樣本點加入到最近的簇

for i in range(m):

mindist = inf;

minindex = -1

for j in range(k):

distji = distmeas(centroids[j, :], dataset[i, :])

if distji < mindist:

mindist = distji; minindex = j

#該樣本劃分到距離最近的簇

if clusterassment[i,0] != minindex: clusterchanged = true

clusterassment[i,:] = minindex,mindist**2

#每輪結束後調整簇心

for cent in range(k):

if clusterassment[i, 0] != minindex: clusterchanged = true

clusterassment[i, :] = minindex, mindist ** 2 #計算每列平均值

return centroids, clusterassment

(2)二分k-均值

# k:簇個數   distmeas:距離生成器

def bikmeans(dataset, k, distmeas=disteclud):

m = shape(dataset)[0] #資料集矩陣的行數

clusterassment = mat(zeros((m,2)))

centroid0 = mean(dataset, axis=0).tolist()[0] # 建立乙個初始簇

centlist =[centroid0] #create a list with one centroid

for j in range(m): # 計算每個樣本點到初始簇的距離

clusterassment[j,1] = distmeas(mat(centroid0), dataset[j,:])**2

while (len(centlist) < k): # 迭代直到簇的數目等於k

lowestsse = inf

for i in range(len(centlist)):

# 嘗試劃分每一簇

ptsincurrcluster = dataset[nonzero(clusterassment[:,0].a==i)[0],:]

centroidmat, splitclustass = kmeans(ptsincurrcluster, 2, distmeas)

ssesplit = sum(splitclustass[:,1])

# 剩餘資料集的誤差

ssenotsplit = sum(clusterassment[nonzero(clusterassment[:,0].a!=i)[0],1])

# 記錄總誤差最小的那個簇

if (ssesplit + ssenotsplit) < lowestsse:

bestcenttosplit = i

bestnewcents = centroidmat

bestclustass = splitclustass.copy()

lowestsse = ssesplit + ssenotsplit

# 因為二分均值,所以結果簇編號只能是0或1,修改結果簇編號為:原簇號和新增簇號

bestclustass[nonzero(bestclustass[:,0].a == 1)[0],0] = len(centlist)

bestclustass[nonzero(bestclustass[:,0].a == 0)[0],0] = bestcenttosplit

# 更新簇列表centlist和樣本點分配簇結果矩陣clusterassment

centlist[bestcenttosplit] = bestnewcents[0,:].tolist()[0]

clusterassment[nonzero(clusterassment[:,0].a == bestcenttosplit)[0],:]= bestclustass

return mat(centlist), clusterassment;

if __name__=="__main__":

datamat = loaddataset('testset.txt')

randcent(mat(datamat), 3)

#kmeans(mat(datamat),3,disteclud,randcent)

#bikmeans(mat(datamat),3,disteclud)

優點: 容易實現

缺點:可能收斂到區域性最小值, 在大規模資料集上收斂較慢,高維空間有侷限

(1)分析資料

(2)基於變化的演算法:即定義乙個函式,隨著k的改變,認為在正確的k時會產生極值。

(3)基於結構的演算法:即比較類內距離、類間距離以確定k。

(4) 基於一致性矩陣的演算法:即認為在正確的k時,不同次聚類的結果會更加相似

(5)基於層次聚類:即基於合併或**的思想,在一定情況下停止從而獲得k

(6)基於取樣的演算法:即對樣本取樣,分別做聚類;根據這些結果的相似性確定k。

(7)使用canopy method演算法進行初始劃分

(8)使用bic演算法進行初始劃分

目前了解的還比較淺顯,後期將不斷地優化。

聚類演算法 KMeans 機器學習實戰

直接上 coding utf8 time 2018 4 12 下午05 33 author yjfiejd file k means 3.py from numpy import import time import matplotlib.pyplot as plt 1 先定義3個函式,第乙個函式為...

機器學習實戰 層次聚類演算法

層次聚類試圖在不同層次對資料集進行劃分,從而形成樹形的聚類結構。資料集的劃分可採用 自底向上 的聚合策略,也可採用 自頂向下 的分拆策略。層次聚類可以分為凝聚層次聚類和 層次聚類。層次聚類採用的就是 自頂而下 的思想,先將所有的樣本都看作是同乙個簇,然後通過迭代將簇劃分為更小的簇,直到每個簇中只有乙...

機器學習實戰之K Means聚類

俗話說的好 物以類聚,人以群分 今天我們要講的聚類演算法很大程度上可以印證此話。聚類是一種非監督學習,什麼是非監督學習?與之前學習的分類和回歸不同 監督學習 監督學習是有有label標籤的,而非監督學習沒有。我們再回到聚類上,聚類是把相似的物件歸到同一簇中,有點像全自動分類。聚類的應用場景有很多,例...