详解DBSCAN聚类( 三 )


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

详解DBSCAN聚类

文章插图
 
在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 = https://www.isolves.com/it/cxkf/sf/2020-08-17/[trace]fig = go.Figure(data = data, layout = layout)fig.show()
详解DBSCAN聚类

文章插图
 
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()
详解DBSCAN聚类

文章插图
 
将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_# Number of clusters in labels, ignoring noise if present.n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)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))
详解DBSCAN聚类

文章插图
 
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 = https://www.isolves.com/it/cxkf/sf/2020-08-17/[trace]fig = go.Figure(data = data, layout = layout)fig.update_layout(title='DBSCAN clusters (53) Derived from PCA', font=dict(size=12,))fig.show()Image for post
详解DBSCAN聚类

文章插图
 
方法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 = []for p in pca_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


推荐阅读