密度聚類 - DBSCAN算法


  參考資料:python機器學習庫sklearn——DBSCAN密度聚類,     Python實現DBScan

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
from sklearn.preprocessing import StandardScaler

# #############################################################################
# 產生樣本數據
centers = [[1, 1], [-1, -1], [1, -1]]  # 生成聚類中心點
X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4,random_state=0) # 生成樣本數據集

X = StandardScaler().fit_transform(X) # StandardScaler作用:去均值和方差歸一化。且是針對每一個特征維度來做的,而不是針對樣本。

# 參數設置
aa = []
for i in range(X.shape[0]-1):
    for j in range(i+1,X.shape[0]):
        aa.append(np.power(X[i]-X[j], 2).sum())
plt.hist(aa, bins=10, density=1, edgecolor ='k', facecolor='g', alpha=0.75) 

# 調參#############################################################################
t0 = time.time()
optimum_parameter = [0,0,0]
for r in np.linspace(0.1, 0.3, 5):
    for min_samples in range(5,12):
        db = DBSCAN(eps=r, min_samples=min_samples).fit(X)
        score = metrics.silhouette_score(X, db.labels_)
        print('(%0.2f, %d) 輪廓系數: %0.3f'%(r, min_samples, score))
        if score > optimum_parameter[2]: optimum_parameter=[r, min_samples, score]
print('最佳參數為:eps=%0.2f, min_samples=%d, 輪廓系數=%0.3f'%(optimum_parameter[0], optimum_parameter[1], optimum_parameter[2]))
print('調參耗時:', time.time()-t0)

# #############################################################################
# 調用密度聚類  DBSCAN
db = DBSCAN(eps=0.3, min_samples=9).fit(X)
# print(db.labels_)  # db.labels_為所有樣本的聚類索引,沒有聚類索引為-1
# print(db.core_sample_indices_) # 所有核心樣本的索引
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)  # 設置一個樣本個數長度的全false向量
core_samples_mask[db.core_sample_indices_] = True #將核心樣本部分設置為true
labels = db.labels_

# 獲取聚類個數。(聚類結果中-1表示沒有聚類為離散點)
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)

# 模型評估
print('估計的聚類個數為: %d' % n_clusters_)
print("同質性: %0.3f" % metrics.homogeneity_score(labels_true, labels))  # 每個群集只包含單個類的成員。
print("完整性: %0.3f" % metrics.completeness_score(labels_true, labels))  # 給定類的所有成員都分配給同一個群集。
print("V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels))  # 同質性和完整性的調和平均
print("調整蘭德指數: %0.3f" % metrics.adjusted_rand_score(labels_true, labels))
print("調整互信息: %0.3f" % metrics.adjusted_mutual_info_score(labels_true, labels))
print("輪廓系數: %0.3f" % metrics.silhouette_score(X, labels))

# #############################################################################
# Plot result
import matplotlib.pyplot as plt

# 使用黑色標注離散點
unique_labels = set(labels)
colors = [plt.cm.Spectral(each) for each in np.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
    if k == -1:  # 聚類結果為-1的樣本為離散點
        # 使用黑色繪制離散點
        col = [0, 0, 0, 1]

    class_member_mask = (labels == k)  # 將所有屬於該聚類的樣本位置置為true

    xy = X[class_member_mask & core_samples_mask]  # 將所有屬於該類的核心樣本取出,使用大圖標繪制
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),markeredgecolor='k', markersize=14)

    xy = X[class_member_mask & ~core_samples_mask]  # 將所有屬於該類的非核心樣本取出,使用小圖標繪制
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),markeredgecolor='k', markersize=6)

plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()

  

  

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM