在数据科学和机器学习中,我们会遇到非常多没有标签的数据,要对这些数据进行分析,就需要用到无监督学习中非常常见的方法——聚类。通过聚类,可以把具有相同特质的数据归并在一起,聚类算法中最常见的就是KMeans和DBSCAN。
KMeans 是一种基于距离的聚类算法,将距离比较近的数据点看作相似的点,将它们归为一类。
KMeans 具体过程如下:
1、比如下面是随机的一些点,我们想将这些点分成三类,聚类中用簇(cluster)表示,那么离得比较近的点肯定归为一个簇,最理想的情况就是如下所示,不同簇用不同的颜色表示。
2、我们当然可以通过眼睛看来决定哪些点为一个簇,但是计算机不能,那么我们需要先进行初始化,即随机选三个点分别作为三个簇的中心,也就是质心,如下图的五角星。然后计算每个点到这三个质心的距离,将这些点分配给离它最近的质心。
3、现在每个点都有所属的簇了,然后根据每个簇中的所有点重新计算簇的质心(一般是计算平均值),可以看到三个五角星的位置发生了变化。
4、然后又计算每个点到三个新的质心的距离,又将这些点和离它最近的质心归为一类,这些点的所属类别就发生了变化。不断迭代这个过程,直到质心的位置基本不变。
最终的结果就可能如下图所示:
最刚开始的中心点是随机指定的,而中心点不同的指定方法,会使得聚类算法运行的最终结果有很大的不同。我们通常是进行多次初始化,多次运行聚类算法,取最好的那个结果。
KMeans 聚类算法有三个缺点:
对于 KMeans 聚类的这些缺点,有没有什么更好的算法呢?都这么问了,肯定是有的,那就是 DBSCAN 聚类算法。
DBSCAN 全称为 Density-Based Spatial Clustering Algorithm with Noise,基于密度的噪声空间聚类算法。
DBSCAN 算法是基于密度对数据点进行处理的,主要是将特征空间中足够密集的点划分为同一个簇,簇的形状可以是任意的,而且数据点中有噪声点的话,不会将这些点划分给某个簇。
这个算法有几个值得一提的地方:
1、不需要我们指定数据集中簇的个数K。
2、前面说K均值聚类通常只在球形分布的数据集上分类效果比较好,而 DBSCAN 聚类则可以用于各种复杂形状的数据集。
3、可以识别出不属于任何簇的离群点,非常适合用来检测离群点。
DBSCAN 算法是基于密度的算法,所以它将密集区域内的点看作核心点(核心样本)。主要有两个参数:min_samples
和eps
。
eps
表示数据点的邻域半径,如果某个数据点的邻域内至少有min_sample
个数据点,则将该数据点看作为核心点。
如果某个核心点的邻域内有其他核心点,则将它们看作属于同一个簇。
如果将eps
设置得非常小,则有可能没有点成为核心点,并且可能导致所有点都被标记为噪声。如果将eps
设置为非常大,则将导致所有点都被划分到同一个簇。
如果min_samples
设置地太大,那么意味着更少的点会成为核心点,而更多的点将被标记为噪声。
DBSCAN 算法也不是万能的,它也有一些缺点:
我们来看 DBSCAN 算法的一个例子:
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# cluster the data into five clusters
dbscan = DBSCAN(eps=0.123, min_samples = 2)
clusters = dbscan.fit_predict(X_scaled)
# plot the cluster assignments
plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap="plasma")
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
输出结果图为:
通过调整min_samples
和eps
两个参数,可以将上面的点分为五类,蓝色的点表示离群点。
还可以通过对数据的各个特征进行归一化,使其具有相似的范围,从而更容易找到合适的eps
。
参考:
Data distributions where Kmeans clustering fails Can DBSCAN be a solution?
DBSCAN: What is it? When to Use it? How to use it.
Visualizing DBSCAN Clustering