機器學習之DBSCAN聚類
阿新 • • 發佈:2018-11-29
- 機器學習之DBSCAN聚類
# -*- coding: utf-8 -*- """ Created on Wed Nov 28 18:50:57 2018 @author: muli """ import numpy as np from sklearn.datasets.samples_generator import make_blobs from sklearn import cluster from sklearn.metrics import adjusted_rand_score import matplotlib.pyplot as plt def create_data(centers,num=100,std=0.7): ''' 生成用於聚類的資料集 :param centers: 聚類的中心點組成的陣列。如果中心點是二維的,則產生的每個樣本都是二維的。 :param num: 樣本數 :param std: 每個簇中樣本的標準差 :return: 用於聚類的資料集。是一個元組,第一個元素為樣本集,第二個元素為樣本集的真實簇分類標記 ''' X, labels_true = make_blobs(n_samples=num, centers=centers, cluster_std=std) return X,labels_true def test_DBSCAN(*data): ''' 測試 DBSCAN 的用法 :param data: 可變引數。 它是一個元組。元組元素依次為:第一個元素為樣本集,第二個元素為樣本集的真實簇分類標記 :return: None ''' X,labels_true=data print(X) print("*") print(len(labels_true)) print("--------------------------") clst=cluster.DBSCAN() # 訓練模型並預測每個樣本所屬的簇標記 predicted_labels=clst.fit_predict(X) # ARI 指數 print("ARI:%s"% adjusted_rand_score(labels_true,predicted_labels)) # 核心樣本在原始訓練集中的位置 print(clst.core_sample_indices_) print("--------------------------") # 將原始資料集劃分為 len(X) 個 簇 print("Core sample num:%d"%len(clst.core_sample_indices_)) def test_DBSCAN_epsilon(*data): ''' 測試 DBSCAN 的聚類結果隨 eps 引數的影響 :param data: 可變引數。它是一個元組。元組元素依次為:第一個元素為樣本集,第二個元素為樣本集的真實簇分類標記 :return: None ''' X,labels_true=data epsilons=np.logspace(-1,1.5) ARIs=[] Core_nums=[] for epsilon in epsilons: clst=cluster.DBSCAN(eps=epsilon) predicted_labels=clst.fit_predict(X) ARIs.append( adjusted_rand_score(labels_true,predicted_labels)) Core_nums.append(len(clst.core_sample_indices_)) ## 繪圖 fig=plt.figure() ax=fig.add_subplot(1,2,1) ax.plot(epsilons,ARIs,marker='+') ax.set_xscale('log') ax.set_xlabel(r"$\epsilon$") ax.set_ylim(0,1) ax.set_ylabel('ARI') ax=fig.add_subplot(1,2,2) ax.plot(epsilons,Core_nums,marker='o') ax.set_xscale('log') ax.set_xlabel(r"$\epsilon$") ax.set_ylabel('Core_Nums') fig.suptitle("DBSCAN") plt.show() def test_DBSCAN_min_samples(*data): ''' 測試 DBSCAN 的聚類結果隨 min_samples 引數的影響 :param data: 可變引數。它是一個元組。元組元素依次為:第一個元素為樣本集,第二個元素為樣本集的真實簇分類標記 :return: None ''' X,labels_true=data min_samples=range(1,100) ARIs=[] Core_nums=[] for num in min_samples: clst=cluster.DBSCAN(min_samples=num) predicted_labels=clst.fit_predict(X) ARIs.append( adjusted_rand_score(labels_true,predicted_labels)) Core_nums.append(len(clst.core_sample_indices_)) ## 繪圖 fig=plt.figure() ax=fig.add_subplot(1,2,1) ax.plot(min_samples,ARIs,marker='+') ax.set_xlabel( "min_samples") ax.set_ylim(0,1) ax.set_ylabel('ARI') ax=fig.add_subplot(1,2,2) ax.plot(min_samples,Core_nums,marker='*') ax.set_xlabel( "min_samples") ax.set_ylabel('Core_Nums') fig.suptitle("DBSCAN") plt.show() if __name__=='__main__': centers=[[1,1],[2,2],[1,2],[10,20]] # 用於產生聚類的中心點 X,labels_true=create_data(centers,1000,0.5) # 產生用於聚類的資料集 # test_DBSCAN(X,labels_true) # 呼叫 test_DBSCAN 函式 # test_DBSCAN_epsilon(X,labels_true) # 呼叫 test_DBSCAN_epsilon 函式 test_DBSCAN_min_samples(X,labels_true) # 呼叫 test_DBSCAN_min_samples 函式