scikit-learn之聚类算法之DBSCAN

算法流程

DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)算法将聚类视为被低密度区域分隔的高密度区域。
核心样本:数据集中的一个样本,至少存在 min_samples 个其他样本在 eps 距离范围内,这些样本被定为核心样本的邻居 neighbors;

1、计算出所有的核心样本;
2、在核心样本集合中随机选择一个核心样本,查找它所有的 neighbors (邻居样本) 中的核心样本,然后查找他们(新获取的核心样本)的 neighbors (邻居样本)中的核心样本,递归这个过程;
3、经过步骤 2,就得到了一个聚类,这个聚类包含一组核心样本和一组接近核心样本的非核心样本(核心样本的邻居样本);
重复步骤 2、3,直到所有的核心样本都属于某个类簇;

根据定义,任何核心样本都是聚类的一部分,任何不是核心样本并且和任意一个核心样本距离都大于 eps 的样本将被视为异常值

算法优缺点

优点:
1、可以对任意形状的稠密数据集进行聚类,相对的,K-Means之类的聚类算法一般只适用于凸数据集;
2、可以在聚类的同时发现异常点,对数据集中的异常点不敏感;
缺点:
1、如果样本集的密度不均匀,聚类质量较差;
2、如果样本集较大时,聚类收敛时间较长,此时可以对搜索最近邻时建立的 KD 树或者球树进行规模限制来改进;
3、调参相对于传统的 K-Means 之类的聚类算法稍复杂,主要需要对距离阈值 eps,邻域样本数阈值 min_samples 联合调参,不同的参数组合对最后的聚类效果有较大影响;

sklearn中的参数

[class sklearn.cluster.DBSCAN]
eps=0.5: float,ϵ-邻域的距离阈值;
min_samples=5: int,样本点要成为核心对象所需要的 ϵ-邻域的样本数阈值;
以上两个参数要联合调参;

metric=’euclidean’: string, or callable,最近邻距离度量参数,可以使用的距离度量

metric_params=None: dict,距离度量的参数;

algorithm=’auto’:{‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’},最近邻搜索算法参数,‘brute’ 是蛮力实现,‘kd_tree’ 是KD 树实现,‘ball_tree’ 是球树实现, ‘auto’ 则会在上面三种算法中做权衡,选择一个拟合最好的最优算法;如果输入样本特征是稀疏的时候,无论我们选择哪种算法,最后 scikit-learn 都会去用蛮力实现 ‘brute’,一般情况使用默认的 ‘auto’ 就够了, 如果数据量很大或者特征也很多,可以尝试使用 ‘kd_tree’ 或 ‘ball_tree’;

leaf_size=30: int,最近邻搜索算法参数,为使用 KD 树或球树时,停止建子树的叶子节点数量的阈值。这个值越小,则生成的 KD 树或者球树就越大,层数越深,建树时间越长,反之,则生成的 KD 树或者球树会小,层数较浅,建树时间较短。因为这个值一般只影响算法的运行速度和使用内存大小,因此一般情况下可以不管它;

p=None: float,最近邻距离度量参数,只用于闵可夫斯基距离和带权重闵可夫斯基距离中 p 值的选择,p=1为曼哈顿距离, p=2为欧式距离,如果使用默认的欧式距离不需要管这个参数;

n_jobs=1: int,多线程;
                   -1:使用所有的cpu;
                    1:不使用多线程;
                  -2:如果 n_jobs<0,(n_cpus + 1 + n_jobs)个cpu被使用,所以 n_jobs=-2 时,所有的cpu中只有一块不被使用;

示例代码

Demo of DBSCAN clustering algorithm

print(__doc__)

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


# #############################################################################
# Generate sample data
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)

# #############################################################################
# Compute DBSCAN
db = DBSCAN(eps=0.3, min_samples=10).fit(X)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_

# Number of clusters in labels, ignoring noise if present.
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)

print('Estimated number of clusters: %d' % n_clusters_)
print("Homogeneity: %0.3f" % metrics.homogeneity_score(labels_true, labels))
print("Completeness: %0.3f" % metrics.completeness_score(labels_true, labels))
print("V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels))
print("Adjusted Rand Index: %0.3f"
      % metrics.adjusted_rand_score(labels_true, labels))
print("Adjusted Mutual Information: %0.3f"
      % metrics.adjusted_mutual_info_score(labels_true, labels))
print("Silhouette Coefficient: %0.3f"
      % metrics.silhouette_score(X, labels))

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

# Black removed and is used for noise instead.
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:
        # Black used for noise.
        col = [0, 0, 0, 1]

    class_member_mask = (labels == k)

    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()

猜你喜欢

转载自blog.csdn.net/xiaoleiniu1314/article/details/80046668