版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mr_muli/article/details/84590561
- 机器学习之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 函数