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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

证据积累聚类集成算法(Evidence Accumulation Clustering)代码复现与实验

發布時間:2023/12/9 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 证据积累聚类集成算法(Evidence Accumulation Clustering)代码复现与实验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 基本環境

運行環境: - Python 3.7 + - Jupyter NoteBook - 處理器:2.6 GHz 六核Intel Core i7

2. 聚類集成代碼

# 導入包 import pandas as pd import numpy as np import math import random import matplotlib.pyplot as plt from sklearn.cluster import KMeans, AgglomerativeClustering from sklearn import datasets from scipy.cluster.hierarchy import dendrogram, linkage, fcluster from sklearn import metrics import scipy.spatial.distance as dist # Kmeans-聚類算法 def kmeans_cluster(data, **kwargs): # K-meansif kwargs is None:kwargs = {'k': 8}kmean = KMeans(n_clusters=kwargs['k'])return kmean.fit_predict(data) # 更新鄰近度矩陣 # similar_mat: 原鄰近度矩陣 # cluster_ind: 類群的樣本序號列表 def update_similar_mat(similar_mat, cluster_ind):if len(cluster_ind) <= 1:return similar_matfor ind, no_i in enumerate(cluster_ind): # ind 是下標, no_i 是值if no_i == cluster_ind[-1]:return similar_matfor no_j in cluster_ind[ind+1:]:similar_mat[no_i, no_j] += 1similar_mat[no_j, no_i] += 1 # 單聚類算法 def single_fit(para_list, data):k = random.randint(0, len(para_list)-1)cluster_result = kmeans_cluster(data, k=para_list[k])return cluster_result # number 聚類次數 # X 原始數據 # result_dict 聚類結果 def ensemble_SL(number, X, result_dict):threshold = 0 # 閾值similar_mat = np.zeros((X.shape[0], X.shape[0]))for single_result in result_dict:k_num = list(set(single_result)) # set(single_result) 取出單個聚類結果中不重復的元素形成一個set集合, 然后再轉化為list列表threshold += len(k_num)for k_i in k_num:index_same_ki = np.where(single_result == k_i)[0] # 存儲相同類簇的樣本序號update_similar_mat(similar_mat, index_same_ki) # 根據樣本序號更新鄰近度矩陣# [number] * X.shape[0] 構成長度為總樣本數,且每個值為聚類分區數目的一維數組# np.diag([number] * X.shape[0]) 輸出一個以 [number] * X.shape[0] 一維數組為對角線元素的矩陣# 更新相似度矩陣的主對角線元素值為聚類分區數similar_mat += np.diag([number] * X.shape[0])# 鄰近度矩陣變換為距離矩陣# similar_mat / number 構成投票后的鄰近度矩陣, 值越大,兩者出現在不同聚類分區中同一類簇的次數越多# 1 - similar_mat / number 值越小,兩者出現在不同聚類分區中同一類簇的次數越多,如此才能層次聚類distance_mat = 1 - similar_mat / numberdistance = dist.squareform(distance_mat)# linkage SL 層次聚類Z = linkage(distance, 'single')# Z矩陣,第一個和第二個元素是每一步合并的兩個簇,# 第三個元素是這些簇之間的距離,# 第四個元素是新簇的大小——包含的原始數據點的數量.# dendrogram(Z)# plt.show()# 挑選生存時間最長簇個數# group_distance = Z[:-min_cluster, 2] # 類間距離向量, 取出Z從-min_cluster行開始的每一維度的第三列元素,各元素之間的簇。group_distance = Z[:, 2] # 類間距離向量, 取出Z第三列所有的類簇lifetime = group_distance[1:] - group_distance[:-1] # 計算生命周期max_lifetime_index = np.argmax(lifetime)threshold = Z[max_lifetime_index, 2] # 對應的類間距離cluster_result = fcluster(Z, threshold, 'distance')return cluster_result EAC-SL 或 EAC-AL 的區別在于采用“Single”或是“Average”的層次聚類算法。 def ensemble_AL(number, X, result_dict):threshold = 0 # 閾值similar_mat = np.zeros((X.shape[0], X.shape[0]))for single_result in result_dict:k_num = list(set(single_result)) # set(single_result) 取出單個聚類結果中不重復的元素形成一個set集合, 然后再轉化為list列表threshold += len(k_num)for k_i in k_num:index_same_ki = np.where(single_result == k_i)[0] # 存儲相同類簇的樣本序號update_similar_mat(similar_mat, index_same_ki) # 根據樣本序號更新鄰近度矩陣# [number] * X.shape[0] 構成長度為總樣本數,且每個值為聚類分區數目的一維數組# np.diag([number] * X.shape[0]) 輸出一個以 [number] * X.shape[0] 一維數組為對角線元素的矩陣# 更新相似度矩陣的主對角線元素值為聚類分區數similar_mat += np.diag([number] * X.shape[0])# 鄰近度矩陣變換為距離矩陣# similar_mat / number 構成投票后的鄰近度矩陣, 值越大,兩者出現在不同聚類分區中同一類簇的次數越多# 1 - similar_mat / number 值越小,兩者出現在不同聚類分區中同一類簇的次數越多,如此才能層次聚類distance_mat = 1 - similar_mat / numberdistance = dist.squareform(distance_mat)# linkage SL 層次聚類Z = linkage(distance, 'average')# Z矩陣,第一個和第二個元素是每一步合并的兩個簇,# 第三個元素是這些簇之間的距離,# 第四個元素是新簇的大小——包含的原始數據點的數量.# dendrogram(Z)# plt.show()# 挑選生存時間最長簇個數# group_distance = Z[:-min_cluster, 2] # 類間距離向量, 取出Z從-min_cluster行開始的每一維度的第三列元素,各元素之間的簇。group_distance = Z[:, 2] # 類間距離向量, 取出Z第三列所有的類簇lifetime = group_distance[1:] - group_distance[:-1] # 計算生命周期max_lifetime_index = np.argmax(lifetime)threshold = Z[max_lifetime_index, 2] # 對應的類間距離cluster_result = fcluster(Z, t=2, criterion='maxclust')return cluster_result

3. 聚類集成的測試

3.1 兩個同心圓測試

3.1.1 生成同心圓數據

data,y = datasets.make_circles(600, noise=0) labels_true = y plt.scatter(data[:, 0], data[:, 1],s=40, c = y, cmap=plt.cm.Spectral) plt.show()

3.1.2 進行50次K-Means聚類,并計算平均 ARI 得分

# 進行 50 次 K-Means 聚類,并計算平均 ARI 得分 fig = plt.figure(figsize=(50,50)) ARI = 0 for i in range(50):result = kmeans_cluster(data,k=2)plt.subplot(10,5,i+1)plt.title(i+1)plt.scatter(data[:, 0], data[:, 1],s=40, c = result, cmap=plt.cm.Spectral)labels_pred = resultARI += metrics.adjusted_rand_score(labels_true, labels_pred) plt.show() print("Average - ARI: \n", ARI / 50)

運行結果

運行時間 6.9s

3.1.3 進行50次 EAC-SL 聚類集成,并計算平均 ARI 得分

# EAC-SL ARI = 0 fig = plt.figure(figsize=(30,30)) number = 200 # 參與集成的數據分區數 para_list = np.arange(2, 2 * int(math.sqrt(len(data))), 1) # K-Means的超參列表 for i in range(50):result_dict = []for k in range(number):result_dict.append(single_fit(para_list,data)) result = ensemble_SL(number, data, result_dict) # 使用EAC-SL聚類集成labels_pred = resultplt.subplot(10,5,i+1)plt.scatter(data[:, 0], data[:, 1],s=40, c = result, cmap=plt.cm.Spectral)ARI += metrics.adjusted_rand_score(labels_true, labels_pred) # 累加 50 輪 ARI 得分 plt.show() print("Average - ARI: \n", ARI / 50)

運行結果

運行時間 15m 25.4s

3.1.3 進行50次 EAC-AL 聚類集成,并計算平均 ARI 得分

# EAC-AL ARI = 0 fig = plt.figure(figsize=(50,50)) number = 200 para_list = np.arange(2, 2 * int(math.sqrt(len(data))), 1) for i in range(50):result_dict = []for k in range(number):result_dict.append(single_fit(para_list,data)) result = ensemble_AL(number, data, result_dict)labels_pred = resultplt.subplot(10,5,i+1)plt.scatter(data[:, 0], data[:, 1],s=40, c = result, cmap=plt.cm.Spectral)ARI += metrics.adjusted_rand_score(labels_true, labels_pred)plt.show() print("Average - ARI: \n", ARI / 50)

運行結果

運行時間 16m51.7s

3.1.4 進行50次單鏈接層次聚類,并計算平均 ARI 得分

fig = plt.figure(figsize=(50,50)) ARI = 0 for i in range(50):result = AgglomerativeClustering(linkage='single').fit(data)plt.subplot(10,5,i+1)plt.title(i+1)plt.scatter(data[:, 0], data[:, 1],s=40, c = result.labels_, cmap=plt.cm.Spectral)labels_pred = result.labels_ARI += metrics.adjusted_rand_score(labels_true, labels_pred) plt.show() print("Average - ARI:",ARI / 50)

運行結果

運行時間 6.7s

3.1 小結

對于分離干凈的類簇, EAC-SL 和 單鏈接層次聚類效果很好,但是 EAC-SL 的時間復雜度很高,運行時間遠遠大于單鏈接層次聚類。但讓我覺得詫異的是,原論文(Combining Multiple Clusterings Using Evidence Accumulation)中 EAC-AL 解決此數據集的錯誤率是0,也就是應當完美聚成兩類,但是復現的結果很垃圾,希望看到此篇文章的朋友們能指點迷津

3.2 接下來要做的事情

明日更新,給數據集加噪聲,繼續做對比測試。

總結

以上是生活随笔為你收集整理的证据积累聚类集成算法(Evidence Accumulation Clustering)代码复现与实验的全部內容,希望文章能夠幫你解決所遇到的問題。

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