DBSCAN 聚类算法分析

DBSCAN 聚类算法分析

先附上python代码

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作用:去均值和方差归一化。且是针对每一个特征维度来做的,而不是针对样本。

# #############################################################################
# 调用密度聚类  DBSCAN
db = DBSCAN(eps=0.3, min_samples=10).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()

输出结果:
这里写图片描述

DBSCAN是基于密度的聚类算法,与K-means算法不一样,得到的是多个数据集合,不能得到中心点,若需要求得中心点,则对每一个簇用一次K-means(K=1)就可以了。

DBSCAN算法有两个关键参数,eps和min_samples,这两个参数表示数据的稠密性。当min_samples增加或者eps减小时,意味着一个簇分类有更大的密度要求。

算法的几个基本概念。
  • 核心点:eps半径距离内,至少有min_samples样本的点。
  • 非核心点:与核心点距离<=eps,但是在其eps半径内存在的样本(点)个数小于min_samples。非核心点也簇的一部分。
  • 异常点:不在核心点eps半径圆内且自身为中心eps半径圆内样本点个数小于min_samples的点。
算法原理

根据上述概念,可以想象算法工作的过程。算法首先找到一个核心点,核心点的eps半径内包含至少min_samples个样本点,这些被包含的样本点可能是非核心点或者核心点,找到核心点,继续对找到的核心点进行上述操作,不断递归寻找,直到找出所有核心点和非核心点。(了解过8皇后问题的同学会更容易理解)

所以上图中大圆表示核心点,小圆表示非核心点,黑点表示异常点。
(经过上述的讲解应该很好理解了)

猜你喜欢

转载自blog.csdn.net/HUXINY/article/details/81221681
今日推荐