日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

机器学习:Python实现聚类算法(二)之AP算法

發布時間:2023/12/8 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习:Python实现聚类算法(二)之AP算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.算法簡介

? ? ? ??AP(Affinity Propagation)通常被翻譯為近鄰傳播算法或者親和力傳播算法,是在2007年的Science雜志上提出的一種新的聚類算法。AP算法的基本思想是將全部數據點都當作潛在的聚類中心(稱之為exemplar),然后數據點兩兩之間連線構成一個網絡(相似度矩陣),再通過網絡中各條邊的消息(responsibility和availability)傳遞計算出各樣本的聚類中心。

?

2.相關概念(假如有數據點i和數據點j)

? ?? ?? ?

? ? ? ? ? ? ? ? ? ? ? ? ?(圖1) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (圖2) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (圖3)

? ? ?1)相似度: 點j作為點i的聚類中心的能力,記為S(i,j)。一般使用負的歐式距離,所以S(i,j)越大,表示兩個點距離越近,相似度也就越高。使用負的歐式距離,相似度是對稱的,如果采用其他算法,相似度可能就不是對稱的。

? ? ?2)相似度矩陣:N個點之間兩兩計算相似度,這些相似度就組成了相似度矩陣。如圖1所示的黃色區域,就是一個5*5的相似度矩陣(N=5)

? ? ?3) ?preference:指點i作為聚類中心的參考度(不能為0),取值為S對角線的值(圖1紅色標注部分),此值越大,最為聚類中心的可能性就越大。但是對角線的值為0,所以需要重新設置對角線的值,既可以根據實際情況設置不同的值,也可以設置成同一值。一般設置為S相似度值的中值。(有的說設置成S的最小值產生的聚類最少,但是在下面的算法中設置成中值產生的聚類是最少的)?

? ? ?4)Responsibility(吸引度):指點k適合作為數據點i的聚類中心的程度,記為r(i,k)。如圖2紅色箭頭所示,表示點i給點k發送信息,是一個點i選點k的過程。

? ? ?5)Availability(歸屬度):指點i選擇點k作為其聚類中心的適合程度,記為a(i,k)。如圖3紅色箭頭所示,表示點k給點i發送信息,是一個點k選diani的過程。

? ? ?6)exemplar:指的是聚類中心。

? ? ?7)r (i, k)加a (i, k)越大,則k點作為聚類中心的可能性就越大,并且i點隸屬于以k點為聚類中心的聚類的可能性也越大

?

3.數學公式

? ? 1)吸引度迭代公式:

? ? ? ? ?? ? (公式一)

? ? ? ? 說明1:Rt+1(i,k)表示新的R(i,k),Rt(i,k)表示舊的R(i,k),也許這樣說更容易理解。其中λ是阻尼系數,取值[0.5,1),用于算法的收斂

? ? ? ? 說明2:網上還有另外一種數學公式:

? ? ? ? ?? ? (公式二)

? ? ? ? ? sklearn官網的公式是:

? ? ? ? ??? ? ? ?(公式三)

? ? ? ? ? ? 我試了這兩種公式之后,發現還是公式一的聚類效果最好。同樣的數據都采取S的中值作為參考度,我自己寫的算法聚類中心是5個,sklearn提供的算法聚類中心是十三個,但是如果把參考度設置為p=-50,則我自己寫的算法聚類中心很多,sklearn提供的聚類算法產生標準的3個聚類中心(因為數據是圍繞三個中心點產生的),目前還不清楚這個p=-50是怎么得到的。

? ? 2)歸屬度迭代公式

? ? ??

? ? ? ?說明:At+1(i,k)表示新的A(i,k),At(i,k)表示舊的A(i,k)。其中λ是阻尼系數,取值[0.5,1),用于算法的收斂

?

4.詳細的算法流程

? ?1)設置實驗數據。使用sklearn包中提供的函數,隨機生成以[1, 1], [-1, -1], [1, -1]三個點為中心的150個數據。? ??

def init_sample():## 生成的測試數據的中心點centers = [[1, 1], [-1, -1], [1, -1]]##生成數據Xn, labels_true = make_blobs(n_samples=150, centers=centers, cluster_std=0.5,random_state=0)#3數據的長度,即:數據點的個數dataLen = len(Xn)return Xn,dataLen View Code

? ?2)計算相似度矩陣,并且設置參考度,這里使用相似度矩陣的中值

def cal_simi(Xn):##這個數據集的相似度矩陣,最終是二維數組simi = []for m in Xn:##每個數字與所有數字的相似度列表,即矩陣中的一行temp = []for n in Xn:##采用負的歐式距離計算相似度s =-np.sqrt((m[0]-n[0])**2 + (m[1]-n[1])**2)temp.append(s)simi.append(temp)##設置參考度,即對角線的值,一般為最小值或者中值#p = np.min(simi) ##11個中心#p = np.max(simi) ##14個中心p = np.median(simi) ##5個中心for i in range(dataLen):simi[i][i] = preturn simi View Code

? ?3)計算吸引度矩陣,即R值。

? ? ?如果有細心的同學會發現,在上述求R和求A的公式中,求R需要A,求A需要R,所以R或者A不是一開始就可以求解出的,需要先初始化,然后再更新。(我開始就陷入了這個誤區,總覺得公式有問題,囧)

##初始化R矩陣、A矩陣 def init_R(dataLen):R = [[0]*dataLen for j in range(dataLen)] return Rdef init_A(dataLen):A = [[0]*dataLen for j in range(dataLen)]return A##迭代更新R矩陣 def iter_update_R(dataLen,R,A,simi):old_r = 0 ##更新前的某個r值lam = 0.5 ##阻尼系數,用于算法收斂##此循環更新R矩陣for i in range(dataLen):for k in range(dataLen):old_r = R[i][k]if i != k:max1 = A[i][0] + R[i][0] ##注意初始值的設置for j in range(dataLen):if j != k:if A[i][j] + R[i][j] > max1 :max1 = A[i][j] + R[i][j]##更新后的R[i][k]值R[i][k] = simi[i][k] - max1##帶入阻尼系數重新更新R[i][k] = (1-lam)*R[i][k] +lam*old_relse:max2 = simi[i][0] ##注意初始值的設置for j in range(dataLen):if j != k:if simi[i][j] > max2:max2 = simi[i][j]##更新后的R[i][k]值R[i][k] = simi[i][k] - max2##帶入阻尼系數重新更新R[i][k] = (1-lam)*R[i][k] +lam*old_rprint("max_r:"+str(np.max(R)))#print(np.min(R))return R View Code

? 4)計算歸屬度矩陣,即A值

##迭代更新A矩陣 def iter_update_A(dataLen,R,A):old_a = 0 ##更新前的某個a值lam = 0.5 ##阻尼系數,用于算法收斂##此循環更新A矩陣for i in range(dataLen):for k in range(dataLen):old_a = A[i][k]if i ==k :max3 = R[0][k] ##注意初始值的設置for j in range(dataLen):if j != k:if R[j][k] > 0:max3 += R[j][k]else :max3 += 0A[i][k] = max3##帶入阻尼系數更新A值A[i][k] = (1-lam)*A[i][k] +lam*old_aelse :max4 = R[0][k] ##注意初始值的設置for j in range(dataLen):##上圖公式中的i!=k 的求和部分if j != k and j != i:if R[j][k] > 0:max4 += R[j][k]else :max4 += 0##上圖公式中的min部分if R[k][k] + max4 > 0:A[i][k] = 0else :A[i][k] = R[k][k] + max4##帶入阻尼系數更新A值A[i][k] = (1-lam)*A[i][k] +lam*old_aprint("max_a:"+str(np.max(A)))#print(np.min(A))return A View Code

?5)迭代更新R值和A值。終止條件是聚類中心在一定程度上不再更新或者達到最大迭代次數

##計算聚類中心 def cal_cls_center(dataLen,simi,R,A):##進行聚類,不斷迭代直到預設的迭代次數或者判斷comp_cnt次后聚類中心不再變化max_iter = 100 ##最大迭代次數curr_iter = 0 ##當前迭代次數max_comp = 30 ##最大比較次數curr_comp = 0 ##當前比較次數class_cen = [] ##聚類中心列表,存儲的是數據點在Xn中的索引while True:##計算R矩陣R = iter_update_R(dataLen,R,A,simi)##計算A矩陣A = iter_update_A(dataLen,R,A)##開始計算聚類中心for k in range(dataLen):if R[k][k] +A[k][k] > 0:if k not in class_cen:class_cen.append(k)else:curr_comp += 1curr_iter += 1print(curr_iter)if curr_iter >= max_iter or curr_comp > max_comp :breakreturn class_cen View Code

?6)根據求出的聚類中心,對數據進行分類

? ? ?這個步驟產生的是一個歸類列表,列表中的每個數字對應著樣本數據中對應位置的數據的分類

##根據聚類中心劃分數據c_list = []for m in Xn:temp = []for j in class_cen:n = Xn[j]d = -np.sqrt((m[0]-n[0])**2 + (m[1]-n[1])**2)temp.append(d)##按照是第幾個數字作為聚類中心進行分類標識c = class_cen[temp.index(np.max(temp))]c_list.append(c) View Code

? 7)完整代碼及效果圖

from sklearn.datasets.samples_generator import make_blobs import numpy as np import matplotlib.pyplot as plt ''' 第一步:生成測試數據1.生成實際中心為centers的測試樣本300個,2.Xn是包含150個(x,y)點的二維數組3.labels_true為其對應的真是類別標簽 '''def init_sample():## 生成的測試數據的中心點centers = [[1, 1], [-1, -1], [1, -1]]##生成數據Xn, labels_true = make_blobs(n_samples=150, centers=centers, cluster_std=0.5,random_state=0)#3數據的長度,即:數據點的個數dataLen = len(Xn)return Xn,dataLen''' 第二步:計算相似度矩陣 ''' def cal_simi(Xn):##這個數據集的相似度矩陣,最終是二維數組simi = []for m in Xn:##每個數字與所有數字的相似度列表,即矩陣中的一行temp = []for n in Xn:##采用負的歐式距離計算相似度s =-np.sqrt((m[0]-n[0])**2 + (m[1]-n[1])**2)temp.append(s)simi.append(temp)##設置參考度,即對角線的值,一般為最小值或者中值#p = np.min(simi) ##11個中心#p = np.max(simi) ##14個中心p = np.median(simi) ##5個中心for i in range(dataLen):simi[i][i] = preturn simi''' 第三步:計算吸引度矩陣,即R公式1:r(n+1) =s(n)-(s(n)+a(n))-->簡化寫法,具體參見上圖公式公式2:r(n+1)=(1-λ)*r(n+1)+λ*r(n) '''##初始化R矩陣、A矩陣 def init_R(dataLen):R = [[0]*dataLen for j in range(dataLen)] return Rdef init_A(dataLen):A = [[0]*dataLen for j in range(dataLen)]return A##迭代更新R矩陣 def iter_update_R(dataLen,R,A,simi):old_r = 0 ##更新前的某個r值lam = 0.5 ##阻尼系數,用于算法收斂##此循環更新R矩陣for i in range(dataLen):for k in range(dataLen):old_r = R[i][k]if i != k:max1 = A[i][0] + R[i][0] ##注意初始值的設置for j in range(dataLen):if j != k:if A[i][j] + R[i][j] > max1 :max1 = A[i][j] + R[i][j]##更新后的R[i][k]值R[i][k] = simi[i][k] - max1##帶入阻尼系數重新更新R[i][k] = (1-lam)*R[i][k] +lam*old_relse:max2 = simi[i][0] ##注意初始值的設置for j in range(dataLen):if j != k:if simi[i][j] > max2:max2 = simi[i][j]##更新后的R[i][k]值R[i][k] = simi[i][k] - max2##帶入阻尼系數重新更新R[i][k] = (1-lam)*R[i][k] +lam*old_rprint("max_r:"+str(np.max(R)))#print(np.min(R))return R '''第四步:計算歸屬度矩陣,即A ''' ##迭代更新A矩陣 def iter_update_A(dataLen,R,A):old_a = 0 ##更新前的某個a值lam = 0.5 ##阻尼系數,用于算法收斂##此循環更新A矩陣for i in range(dataLen):for k in range(dataLen):old_a = A[i][k]if i ==k :max3 = R[0][k] ##注意初始值的設置for j in range(dataLen):if j != k:if R[j][k] > 0:max3 += R[j][k]else :max3 += 0A[i][k] = max3##帶入阻尼系數更新A值A[i][k] = (1-lam)*A[i][k] +lam*old_aelse :max4 = R[0][k] ##注意初始值的設置for j in range(dataLen):##上圖公式中的i!=k 的求和部分if j != k and j != i:if R[j][k] > 0:max4 += R[j][k]else :max4 += 0##上圖公式中的min部分if R[k][k] + max4 > 0:A[i][k] = 0else :A[i][k] = R[k][k] + max4##帶入阻尼系數更新A值A[i][k] = (1-lam)*A[i][k] +lam*old_aprint("max_a:"+str(np.max(A)))#print(np.min(A))return A'''第5步:計算聚類中心 '''##計算聚類中心 def cal_cls_center(dataLen,simi,R,A):##進行聚類,不斷迭代直到預設的迭代次數或者判斷comp_cnt次后聚類中心不再變化max_iter = 100 ##最大迭代次數curr_iter = 0 ##當前迭代次數max_comp = 30 ##最大比較次數curr_comp = 0 ##當前比較次數class_cen = [] ##聚類中心列表,存儲的是數據點在Xn中的索引while True:##計算R矩陣R = iter_update_R(dataLen,R,A,simi)##計算A矩陣A = iter_update_A(dataLen,R,A)##開始計算聚類中心for k in range(dataLen):if R[k][k] +A[k][k] > 0:if k not in class_cen:class_cen.append(k)else:curr_comp += 1curr_iter += 1print(curr_iter)if curr_iter >= max_iter or curr_comp > max_comp :breakreturn class_cenif __name__=='__main__':##初始化數據Xn,dataLen = init_sample()##初始化R、A矩陣R = init_R(dataLen)A = init_A(dataLen)##計算相似度simi = cal_simi(Xn) ##輸出聚類中心class_cen = cal_cls_center(dataLen,simi,R,A)#for i in class_cen:# print(str(i)+":"+str(Xn[i]))#print(class_cen)##根據聚類中心劃分數據c_list = []for m in Xn:temp = []for j in class_cen:n = Xn[j]d = -np.sqrt((m[0]-n[0])**2 + (m[1]-n[1])**2)temp.append(d)##按照是第幾個數字作為聚類中心進行分類標識c = class_cen[temp.index(np.max(temp))]c_list.append(c)##畫圖colors = ['red','blue','black','green','yellow']plt.figure(figsize=(8,6))plt.xlim([-3,3])plt.ylim([-3,3])for i in range(dataLen):d1 = Xn[i]d2 = Xn[c_list[i]]c = class_cen.index(c_list[i])plt.plot([d2[0],d1[0]],[d2[1],d1[1]],color=colors[c],linewidth=1)#if i == c_list[i] :# plt.scatter(d1[0],d1[1],color=colors[c],linewidth=3)#else :# plt.scatter(d1[0],d1[1],color=colors[c],linewidth=1)plt.show() View Code

?迭代11次出結果:

? ? ? ?補充說明:這個算法重點在講解實現過程,執行效率不是特別高,有優化的空間。以后我會補充進來

?

5.sklearn包中的AP算法

? ? 1)函數:sklearn.cluster.AffinityPropagation

? ? 2)主要參數:

? ? ? ? ?damping : 阻尼系數,取值[0.5,1)

? ? ? ? ?convergence_iter :比較多少次聚類中心不變之后停止迭代,默認15

? ? ? ? ?max_iter :最大迭代次數

? ? ? ? ?preference :參考度

? ? 3)主要屬性

? ? ? ??cluster_centers_indices_ : 存放聚類中心的數組

? ? ? ??labels_ :存放每個點的分類的數組

? ? ? ??n_iter_ : 迭代次數

? ? 4)示例? ? ?

? ? ? ??preference(即p值)取不同值時的聚類中心的數目在代碼中注明了。

from sklearn.cluster import AffinityPropagation from sklearn import metrics from sklearn.datasets.samples_generator import make_blobs import numpy as np## 生成的測試數據的中心點 centers = [[1, 1], [-1, -1], [1, -1]] ##生成數據 Xn, labels_true = make_blobs(n_samples=150, centers=centers, cluster_std=0.5,random_state=0)simi = [] for m in Xn:##每個數字與所有數字的相似度列表,即矩陣中的一行temp = []for n in Xn:##采用負的歐式距離計算相似度s =-np.sqrt((m[0]-n[0])**2 + (m[1]-n[1])**2)temp.append(s)simi.append(temp)p=-50 ##3個中心 #p = np.min(simi) ##9個中心, #p = np.median(simi) ##13個中心 ap = AffinityPropagation(damping=0.5,max_iter=500,convergence_iter=30,preference=p).fit(Xn) cluster_centers_indices = ap.cluster_centers_indices_for idx in cluster_centers_indices:print(Xn[idx]) View Code

?

?6.AP算法的優點

? ? 1) 不需要制定最終聚類族的個數?

? ? 2) 已有的數據點作為最終的聚類中心,而不是新生成一個族中心。?

? ? 3)模型對數據的初始值不敏感。?

? ??4)對初始相似度矩陣數據的對稱性沒有要求。?

? ??5).相比與k-centers聚類方法,其結果的平方差誤差較小。

?

7.AP算法的不足

? ??1)AP算法需要事先計算每對數據對象之間的相似度,如果數據對象太多的話,內存放不下,若存在數據庫,頻繁訪問數據庫也需要時間。

? ? 2)AP算法的時間復雜度較高,一次迭代大概O(N3)

? ? 3)聚類的好壞受到參考度和阻尼系數的影響。

?

轉載于:https://www.cnblogs.com/lc1217/p/6908031.html

總結

以上是生活随笔為你收集整理的机器学习:Python实现聚类算法(二)之AP算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 色图自拍偷拍 | www.污网站 | 黄瓜视频成人 | 啪啪一级片 | 亚洲偷拍一区 | 成人免费网站视频 | 性欢交69国产精品 | 国产不卡一区二区视频 | 午夜影院日本 | 亚洲国产精品成人综合在线 | 麻豆国产一区二区三区四区 | 欧美亚洲国产精品 | 男女无遮挡免费视频 | 日韩无马 | 国产一区99| 浴室里强摁做开腿呻吟男男 | 毛片88| 免费久久 | 中文字幕乱码中文乱码b站 国产一区二区三区在线观看视频 | 亚洲综合大片69999 | 男女视频在线免费观看 | 精彩视频一区二区三区 | 日韩欧美网| 人人人草 | 校园春色 亚洲色图 | 国产又粗又猛视频 | 男人天堂av网 | 国产精品成人av性教育 | 亚洲精品中文字幕乱码三区 | 欧美另类videosbestsex | a级黄视频| 永久精品网站 | 天天看夜夜| 国产精品98 | 在线a视频| 免费黄色网址在线 | 日韩成人av一区二区 | 青青草免费公开视频 | 国产啊啊啊啊 | 亚洲福利视频一区二区三区 | 久久久久久久蜜桃 | 色图综合网 | 久久久久久一级片 | 成年人免费在线观看视频网站 | 黄色一级片在线免费观看 | 三级av网 | 韩国成人在线视频 | 岛国免费视频 | 在线观看不卡av | 国产色一区 | 亚洲一区免费观看 | 日韩av中文字幕在线免费观看 | 在线观看精品视频 | 精品一区二区在线看 | 日韩不卡在线观看 | 丰满人妻一区二区三区免费视频 | 中日韩黄色大片 | 欧美拍拍视频 | 色黄视频在线观看 | 国产综合在线视频 | 欧美视频在线免费 | 成人小视频免费观看 | 99re6这里只有精品 | 成人av入口 | 亚洲国产免费av | 不卡在线一区 | 亚洲免费播放 | 伊人三级 | 无码人妻精品一区二区三区99v | 夜夜精品一区二区无码 | 日韩精品中文字幕一区二区 | 久久亚洲一区二区三区四区五区 | 久久久久久国产精品一区 | 久久一视频 | 91av在线视频观看 | 一区二区视频网站 | 玩弄白嫩少妇xxxxx性 | 欧美性猛交乱大交xxxx | 亚洲午夜18毛片在线看 | 欧美成人精品一区二区 | 涩涩视频免费在线观看 | 亚洲欧美精品在线观看 | 久久免费观看视频 | 午夜影院网站 | 永久免费未满蜜桃 | 精品自拍视频 | 美国免费高清电影在线观看 | 国产乱码一区二区三区播放 | 一区二区三区人妻 | 国产酒店自拍 | 日韩手机在线观看 | 国产黄色一级 | 国产极品视频 | 在线一区二区三区 | 激情婷婷久久 | 日韩乱码人妻无码中文字幕 | 国产免费一区二区三区网站免费 | 国产成人一区二区三区免费看 | 99在线观看视频 |