详解DBSCAN聚类(下)

简介: 详解DBSCAN聚类

2. 特征降维

在一些算法如KMeans中,如果数据集的特征维度太大,就很难精确地构建聚类。高维数并不一定意味着成百上千维度的特征。甚至10个维度的特征也会造成准确性问题。

特征降维背后的理论是将原始特征集转换为更少的人工派生特征,这些特征仍然保留了原始特征中包含的大部分信息。

最流行的特征降维技术之一是主成分分析(PCA)。PCA将原始数据集缩减为指定数量的特征,并将这些特征称为主成分。我们必须选择我们希望看到的主成分的数量。我们在我关于KMeans集群的文章中讨论了减少特性,我强烈建议您看一看(链接)。

首先,我们需要确定适当的主成分数量。3个主成分似乎占了大约75%的方差。

pca=PCA(n_components=7)
pca.fit(df_scale)
variance=pca.explained_variance_ratio_var=np.cumsum(np.round(variance, 3)*100)
plt.figure(figsize=(12,6))
plt.ylabel('% Variance Explained')
plt.xlabel('# of Features')
plt.title('PCA Analysis')
plt.ylim(0,100.5)plt.plot(var)

640.png

现在我们知道了维持一个特定百分比的方差所需的主成分的数量,让我们对原始数据集应用一个3成分的主成分分析。请注意,第一个主成分占到与原始数据集方差的26%。在本文的其余部分中,我们将使用“pca_df”数据框架。

pca=PCA(n_components=3)
pca.fit(df_scale)
pca_scale=pca.transform(df_scale)pca_df=pd.DataFrame(pca_scale, columns=['pc1', 'pc2', 'pc3'])
print(pca.explained_variance_ratio_)

640.png

在3D空间中绘制数据,可以看到DBSCAN存在一些潜在的问题。DBSCAN的一个主要缺点就是它不能准确地对不同密度的数据进行聚类,从下面的图中,我们可以看到两个不同密度的单独集群。在应用DBSCAN算法时,我们可能能够在数据点较少的聚类结果中找到不错的聚类方式,但在数据点较多的聚类中的许多数据点可能被归类为离群值/噪声。这当然取决于我们对epsilon和最小点值的选择。

Scene=dict(xaxis=dict(title='PC1'),yaxis=dict(title='PC2'),zaxis=dict(title='PC3'))trace=go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(colorscale='Greys', opacity=0.3, size=10, ))
layout=go.Layout(margin=dict(l=0,r=0),scene=Scene, height=1000,width=1000)
data= [trace]
fig=go.Figure(data=data, layout=layout)
fig.show()

640.png

3.DBSCAN聚类

方法1

在应用聚类算法之前,我们必须使用前面讨论过的“肘形法”来确定合适的epsilon级别。看起来最佳的值在0.2左右。最后,由于我们的数据有3个主成分,我们将把最小点标准设置为6。

plt.figure(figsize=(10,5))
nn=NearestNeighbors(n_neighbors=5).fit(pca_df)
distances, idx=nn.kneighbors(pca_df)
distances=np.sort(distances, axis=0)
distances=distances[:,1]
plt.plot(distances)
plt.show()

640.png

将epsilon设置为0.2,将min_samples设置为6,得到了53个集群,影像分数为-0.521,以及超过1500个被认为是离群值/噪声的数据点。在某些研究领域,53个集群可能被认为是有用的,但我们有一个15000名员工的数据集。从业务的角度来看,我们需要一些可管理的集群(即3-5个),以便更好地分配工作场所。此外,剪影得分-0.521表明数据点是不正确的聚集。

看看下面的3D图,我们可以看到一个包含了大多数数据点的集群。出现了一个较小但很重要的聚类簇,但剩下52个聚类簇的规模要小得多。从业务角度来看,这些集群提供的信息不是很多,因为大多数员工只属于两个集群。组织希望看到几个大的集群,以确定它们的有效性,但也能够从事一些针对集群员工的组织主动性工作(例如。增加培训、薪酬变化等)。

db=DBSCAN(eps=0.2, min_samples=6).fit(pca_df)
labels=db.labels_#Numberofclustersinlabels, ignoringnoiseifpresent.
n_clusters_=len(set(labels)) - (1if-1inlabelselse0)
n_noise_=list(labels).count(-1)print('Estimated number of clusters: %d'%n_clusters_)
print('Estimated number of noise points: %d'%n_noise_)
print("Silhouette Coefficient: %0.3f"%metrics.silhouette_score(pca_df, labels))

640.png

Scene=dict(xaxis=dict(title='PC1'),yaxis=dict(title='PC2'),zaxis=dict(title='PC3'))labels=db.labels_trace=go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(color=labels, colorscale='Viridis', size=10, line=dict(color='gray',width=5)))
layout=go.Layout(scene=Scene, height=1000,width=1000)
data= [trace]
fig=go.Figure(data=data, layout=layout)fig.update_layout(title='DBSCAN clusters (53) Derived from PCA', font=dict(size=12,))
fig.show()
Imageforpost

640.png

方法2

我们不使用“肘部方法”和最小值启发式方法,而是使用迭代方法来微调我们的DBSCAN模型。在对数据应用DBSCAN算法时,我们将迭代一系列的epsilon和最小点值。

在我们的例子中,我们将迭代0.5到1.5之间的epsilon值和2-7之间的minPts。for循环将使用这组值运行DBSCAN算法,并为每次迭代生成集群数量和影像分数。请记住,您需要根据数据调整参数。您可能会在一组参数上运行此代码,并发现产生的最佳影像分数是0.30。为了将更多的点包含到一个集群中,您可能需要增加值。

pca_eps_values=np.arange(0.2,1.5,0.1)
pca_min_samples=np.arange(2,5)
pca_dbscan_params=list(product(pca_eps_values, pca_min_samples))pca_no_of_clusters= []
pca_sil_score= []
pca_epsvalues= []
pca_min_samp= []forpinpca_dbscan_params:
pca_dbscan_cluster=DBSCAN(eps=p[0], min_samples=p[1]).fit(pca_df)
pca_epsvalues.append(p[0])
pca_min_samp.append(p[1])pca_no_of_clusters.append(
len(np.unique(pca_dbscan_cluster.labels_)))
pca_sil_score.append(silhouette_score(pca_df, pca_dbscan_cluster.labels_))pca_eps_min=list(zip(pca_no_of_clusters, pca_sil_score, pca_epsvalues, pca_min_samp))pca_eps_min_df=pd.DataFrame(pca_eps_min, columns=['no_of_clusters', 'silhouette_score', 'epsilon_values', 'minimum_points'])pca_ep_min_df

640.png

我们可以看到,通过我们的epsilon和minPts的迭代,我们已经获得了很大范围的簇数和影像分数。0.9到1.1之间的epsilon分数开始产生可管理的集群数量。将epsilon增加到1.2或更高会导致集群数量太少,无法在商业上发挥作用。此外,其中一些集群可能只是噪音。我们稍后会讲到。

增加的epsilon会减少集群的数量,但每个集群也会开始包含更多的离群点/噪声数据点,这一点也可以理解为有一定程度的收益递减。

为了简单起见,让我们选择7个集群并检查集群分布情况。(epsilon: 1.0和minPts: 4)。

同样重要的是,运行此代码串时肯定会遇到的一个常见错误。有时,当你设置的参数不合适,for循环最终会变成eps_values和min_samples的组合,这只会产生一个集群。但是,silhouette ette_score函数至少需要定义两个集群。您需要限制参数以避免此问题。

在上面的示例中,如果我们将epsilon参数的范围设置为0.2到2.5,那么很可能会生成一个集群并最终导致错误。

640.png

你可能会问自己“我们不是应该获得7个集群吗?”答案是肯定的,如果我们看一下独特的标签/集群,我们看到每个数据点有7个标签。根据Sklearn文档,标签“-1”等同于一个“嘈杂的”数据点,它还没有被聚集到6个高密度的集群中。我们自然不希望将任何“-1”标签考虑为一个集群,因此,它们将从计算中删除。

db=DBSCAN(eps=1.0, min_samples=4).fit(pca_df)
labels=db.labels_#Numberofclustersinlabels, ignoringnoiseifpresent.
n_clusters_=len(set(labels)) - (1if-1inlabelselse0)
n_noise_=list(labels).count(-1)print('Estimated number of clusters: %d'%n_clusters_)
print('Estimated number of noise points: %d'%n_noise_)
print("Silhouette Coefficient: %0.3f"%silhouette_score(pca_df, labels))

640.png

set(labels)

640.png

从6个DBSCAN派生集群的3D图中可以看出,尽管密度较小,但位于图顶端的密度较小的集群对DBSCAN并没有造成太大影响。如果您还记得的话,DBSCAN很难正确地集群各种密度的数据。顶部的集群和更大的底部集群之间的距离很可能大于1.0的epsilon值。

也就是说,数据集包含额外的高密度集群,但是我们的epsilon和minPts太大了。底部的聚类簇包含至少两个高密度的聚类簇,然而,由于底部聚类簇的高密度降低了epsilon和minPts,只会产生许多更小的聚类簇。这也是DBSCAN的主要缺点。我一直认为DBSCAN需要第三个参数“min_core”,它将确定一个集群可以被视为有效集群之前的最小核心点数量。

640.png

Scene=dict(xaxis=dict(title='PC1'),yaxis=dict(title='PC2'),zaxis=dict(title='PC3'))#model.labels_isnothingbutthepredictedclustersi.ey_clusterslabels=db.labels_trace=go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(color=labels, colorscale='Viridis', size=10, line=dict(color='gray',width=5)))
layout=go.Layout(scene=Scene, height=1000,width=1000)
data= [trace]
fig=go.Figure(data=data, layout=layout)fig.update_layout(title="'DBSCAN Clusters (6) Derived from PCA'", font=dict(size=12,))
fig.show()

在我们开始之前,让我们快速了解一下每个集群中的员工数量。似乎cluster 0包含了大部分信息不太丰富的数据点。事实上,如果我们使用0.5的epsilon值和5的minPts运行算法,就会产生63个集群,集群0仍然会包含99%的员工人口。

np.unique(labels, return_counts=True)

小结

DBSCAN,一种密度聚类算法,常用于非线性或非球面数据集。epsilon和minPts是两个必需的参数。epsilon是附近数据点的半径,这些数据点需要被认为是足够“相似”才能开始聚类。最后,minPts是需要在半径内的数据点的最小数目。

在我们的示例中,我们试图根据工作特征对包含15,000名员工的数据集进行聚类。我们首先标准化了数据集以缩放特征。接下来,我们应用主成分分析将维度/特征的数量减少到3个主成分。使用“肘部法”,我们估计了0.2的epsilon值和6的minPts。使用这些参数,我们能够获得53个集群,1500个离群值和-0.52的影响分数。不用说,结果并不是很理想。

接下来,我们尝试了一种迭代的方法来微调epsilon和minPts。我们已经确定了epsilon值为1.0和minPts值为4。该算法返回6个有效的集群(一个-1集群),只有7个异常值,以及0.46的可观影像分数。然而,在绘制派生集群时,发现第一个集群包含99%的员工。从业务的角度来看,我们希望我们的集群能够更加均衡地分布,从而为我们提供关于员工的良好见解。

DBSCAN似乎不是这个特定数据集的最佳聚类算法。


目录
相关文章
|
1月前
|
机器学习/深度学习 数据采集 算法
KMeans+DBSCAN密度聚类+层次聚类的使用(附案例实战)
KMeans+DBSCAN密度聚类+层次聚类的使用(附案例实战)
276 0
|
15天前
|
数据采集 机器学习/深度学习 算法
聚类算法
【6月更文挑战第6天】聚类算法是无监督学习方法,用于将数据集划分成相似样本的类别。常见的聚类算法有K均值、层次聚类和DBSCAN等。在分析时,涉及数据预处理、选择算法、确定聚类数目、执行聚类及评估结果。层次聚类分为自底向上和自顶向下两种,而K-Means是基于质心的聚类算法。评估指标如轮廓系数可衡量聚类效果。聚类过程包括初始化中心、计算样本与中心距离、分配类别和更新中心,直到收敛。
24 2
|
22天前
|
算法 数据挖掘 Python
k均值聚类算法
【6月更文挑战第6天】k均值聚类算法。
12 1
|
6月前
|
算法 数据可视化 数据挖掘
C# | DBSCAN聚类算法实现 —— 对直角坐标系中临近点的点进行聚类
聚类算法是一种常见的数据分析技术,用于将相似的数据对象归类到同一组或簇中。其中,DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,能够有效地识别出不同形状和大小的簇,同时还能标识出噪声数据。本篇博客将介绍聚类算法的概念、DBSCAN算法的原理,并通过提供的C#代码逐步解析DBSCAN算法的实现过程。
155 0
C# | DBSCAN聚类算法实现 —— 对直角坐标系中临近点的点进行聚类
|
1月前
|
机器学习/深度学习 算法 数据可视化
K均值聚类、层次聚类
K均值聚类、层次聚类
|
1月前
|
算法 搜索推荐 数据挖掘
C# | KMeans聚类算法的实现,轻松将数据点分组成具有相似特征的簇
聚类是将数据点根据其相似性分组的过程,它有很多的应用场景,比如:图像分割、文本分类、推荐系统等等。在这些应用场景里面我们需要将数据点分成多个簇,每个簇内的数据点具有相似的特征,以便于我们能够更简单的处理数据。 KMeans算法是一种常用的聚类算法,它可以将数据点分组成具有相似特征的簇。
100 0
C# | KMeans聚类算法的实现,轻松将数据点分组成具有相似特征的簇
|
9月前
|
机器学习/深度学习 算法 数据挖掘
K-均值聚类算法
K-均值聚类算法
|
机器学习/深度学习 算法 数据挖掘
Kmeans聚类算法详解
Kmeans聚类算法详解
590 0
|
机器学习/深度学习 传感器 人工智能
【聚类】基于PCA+kmeans实现数据聚类附matlab代码
【聚类】基于PCA+kmeans实现数据聚类附matlab代码
|
算法 数据可视化 数据挖掘
详解DBSCAN聚类(上)
详解DBSCAN聚类
328 1
详解DBSCAN聚类(上)