当前位置:   article > 正文

使用Python实现DBSCAN聚类算法及可视化_python dbscan

python dbscan

目录

实战过程

数据准备

DBSCAN模型

聚类结果评估

可视化展示

运行结果

总结


DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,可以发现任意形状的簇,并且能够在噪声数据的情况下不受干扰地识别出核心对象。本篇文章将介绍如何使用Python实现DBSCAN聚类算法及可视化。

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)聚类算法适用于以下情况

  1. 数据分布具有密度区别:对于密度高的数据点,会被分为一个簇;而对于密度低的数据点,会被认为是噪声点。

  2. 数据分布多样化:DBSCAN能够发现任意形状的簇,不需要预先知道簇的数量和形状。

  3. 噪声数据较多:DBSCAN能够正确区分噪声数据和有效数据,有效避免噪声数据对聚类结果的影响。

  4. 聚类效果需求较高:相对于传统的K-Means聚类算法,DBSCAN能够处理复杂的非球形簇,并且具有更好的鲁棒性。

因此,如果在聚类任务中,数据分布具有明显的密度区别,且需要发现任意形状和数量的簇,同时希望聚类结果具有更好的鲁棒性,那么就可以考虑使用DBSCAN聚类算法。然而,对于高维度和高斯分布的数据,DBSCAN表现不如传统的聚类算法,并且需要合理设置参数才能得到好的聚类效果。

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)聚类算法的主要步骤如下:

  1. 选择一个未访问的数据点作为起始点,找到该数据点的半径范围内的所有数据点。

  2. 如果半径范围内的数据点数量大于等于阈值min_samples,则认为这些数据点属于同一个簇,并进行标记。如果数量小于阈值,则将该数据点标记为噪声点。

  3. 对于半径范围内的所有数据点,递归地进行相同的操作,直到所有相邻的点都被访问。

  4. 将未被访问的数据点作为起点,重复执行上述步骤,直到所有数据点都被访问。

  5. 所有被标记为同一簇的数据点构成一个簇,所有未被标记的数据点构成噪声点。

  6. 最终得到若干个簇和若干个噪声点,可以通过可视化方法来展示聚类结果。

需要注意的是,DBSCAN算法中的核心参数是半径范围内数据点的数量阈值min_samples和邻域半径eps。这两个参数的设置对于聚类效果具有重要影响,需要根据实际情况进行调整。同时,在处理高维度数据时,可以使用降维算法来减少数据的维度,提高聚类效率。

优点:

(1)能够发现任意形状的簇,对异常值的鲁棒性较好。

(2)不需要预先设置簇的数量。

(3)能够正确区分噪声数据和有效数据。

(4)相对于其他聚类算法,计算复杂度较低,容易实现。

缺点

(1)结果可能受参数的选择影响,如eps和min_samples等。

(2)对于不同密度的簇效果并不完全一致,如高密度簇和低密度簇。

(3)在处理高维数据时,由于维数灾难的存在,可视化效果很差,且聚类效果不理想。

(4)对于高斯分布的数据,效果不如K-Means等传统聚类算法。

实战过程

数据准备

首先,需要准备一个数据集。本文以银行客户数据为例,根据客户的信息包括性别、年龄、信用分数、地理位置、是否有信用卡、账户余额等,将客户划分到不同的群组中。

部分数据样例 

DBSCAN模型

使用sklearn中的DBSCAN模型来实现DBSCAN聚类算法,需要调整两个参数:eps和min_samples。eps表示样本点的邻域半径,min_samples表示样本点在eps半径内的最小数量。代码如下:

  1. # 定义 DBSCAN 模型,设置 eps 和 min_samples 参数
  2. dbscan_model = DBSCAN(eps=0.6, min_samples=2)
  3. # 对数据进行拟合
  4. dbscan_model.fit(data)

聚类结果评估

聚类结果评估通常可以采用Silhouette score、Calinski-Harabasz score和Davies-Bouldin Index等指标来评估聚类效果。

  1. # 输出 Silhouette score
  2. print("Silhouette score:", silhouette_score(data, dbscan_model.labels_))
  3. # 输出 Calinski-Harabasz score
  4. print("Calinski-Harabasz score:", calinski_harabasz_score(data, dbscan_model.labels_))
  5. # 输出 Davies-Bouldin Index
  6. print("Davies-Bouldin Index:", davies_bouldin_score(data, dbscan_model.labels_))

可视化展示

使用t-SNE算法将数据降维到三维,并将DBSCAN聚类结果与降维后的数据合并。最终使用matplotlib绘制3D散点图,不同颜色的点表示不同的簇。

  1. # 使用 PCA 进行降维和映射
  2. # 使用 t-SNE 进行降维
  3. tsne = TSNE(n_components=3, random_state=42)
  4. reduced_data = tsne.fit_transform(data)
  5. # 将 DBSCAN 结果与降维后的数据合并
  6. clustered_data_df = pd.DataFrame(reduced_data, columns=['Dimension 1', 'Dimension 2', 'Dimension 3'])
  7. clustered_data_df['Cluster'] = dbscan_model.labels_
  8. from mpl_toolkits.mplot3d import Axes3D
  9. # 创建三维坐标轴
  10. fig = plt.figure(figsize=(10, 10))
  11. ax = fig.add_subplot(111, projection='3d')
  12. # 根据聚类标签绘制散点图
  13. colors = ['red', 'green', 'blue', 'purple', 'orange', 'brown', 'pink', 'gray', 'olive']
  14. for label in set(dbscan_model.labels_):
  15. if label == -1:
  16. cidx = -1
  17. else:
  18. cidx = label % len(colors)
  19. ax.scatter(clustered_data_df.loc[clustered_data_df['Cluster']==label, 'Dimension 1'],
  20. clustered_data_df.loc[clustered_data_df['Cluster']==label, 'Dimension 2'],
  21. clustered_data_df.loc[clustered_data_df['Cluster']==label, 'Dimension 3'],
  22. c=colors[cidx], marker='.', label='Cluster '+str(label))
  23. # 添加坐标轴标签和图例
  24. ax.set_xlabel('Dimension 1')
  25. ax.set_ylabel('Dimension 2')
  26. ax.set_zlabel('Dimension 3')
  27. ax.set_title('DBSCAN Clustering (TSNE)')
  28. plt.legend()
  29. plt.show()

运行结果

从 Silhouette score、Calinski-Harabasz score和Davies-Bouldin Index等指标,以及可视化图可以看出DBSCAN的聚类效果较好。

总结

本文介绍了如何使用Python实现DBSCAN聚类算法及其可视化展示。DBSCAN算法是一种基于密度的聚类算法,相对于传统的聚类算法具有更强的可扩展性和适应性。通过实现这个过程,读者可以更好地理解聚类算法的工作原理,为实际项目提供参考。

完整代码

  1. # -*- coding = utf-8 -*-
  2. # @Time : 2023/5/18 16:48
  3. # @Author : xx
  4. # @File : .py
  5. # @Software: PyCharm
  6. import pandas as pd
  7. import numpy as np
  8. from sklearn.cluster import DBSCAN
  9. from sklearn.manifold import TSNE
  10. from sklearn.metrics import silhouette_score, calinski_harabasz_score, davies_bouldin_score
  11. import matplotlib.pyplot as plt
  12. df = pd.read_csv("select-data.csv")
  13. data = []
  14. for i in range(0, len(df["EstimatedSalary"])):
  15. mid = []
  16. mid.append(df["Geography"][i])
  17. mid.append(df["Gender"][i])
  18. mid.append(df["EB"][i])
  19. mid.append(df["Age"][i])
  20. mid.append(df["EstimatedSalary"][i])
  21. mid.append(df["NumOfProducts"][i])
  22. mid.append(df["CreditScore"][i])
  23. mid.append(df["Tenure"][i])
  24. mid.append(df["HasCrCard"][i])
  25. data.append(mid)
  26. data = np.array(data)
  27. # 定义 DBSCAN 模型,设置 eps 和 min_samples 参数
  28. dbscan_model = DBSCAN(eps=0.6, min_samples=2)
  29. # 对数据进行拟合
  30. dbscan_model.fit(data)
  31. # 输出模型估算的聚类数量
  32. print("Estimated number of clusters:", len(set(dbscan_model.labels_)) - (1 if -1 in dbscan_model.labels_ else 0))
  33. # 注意需要排除噪音点
  34. # 输出 Silhouette score
  35. print("Silhouette score:", silhouette_score(data, dbscan_model.labels_))
  36. # 输出 Calinski-Harabasz score
  37. print("Calinski-Harabasz score:", calinski_harabasz_score(data, dbscan_model.labels_))
  38. # 输出 Davies-Bouldin Index
  39. print("Davies-Bouldin Index:", davies_bouldin_score(data, dbscan_model.labels_))
  40. # 使用 PCA 进行降维和映射
  41. # 使用 t-SNE 进行降维
  42. tsne = TSNE(n_components=3, random_state=42)
  43. reduced_data = tsne.fit_transform(data)
  44. # 将 DBSCAN 结果与降维后的数据合并
  45. clustered_data_df = pd.DataFrame(reduced_data, columns=['Dimension 1', 'Dimension 2', 'Dimension 3'])
  46. clustered_data_df['Cluster'] = dbscan_model.labels_
  47. from mpl_toolkits.mplot3d import Axes3D
  48. # 创建三维坐标轴
  49. fig = plt.figure(figsize=(10, 10))
  50. ax = fig.add_subplot(111, projection='3d')
  51. # 根据聚类标签绘制散点图
  52. colors = ['red', 'green', 'blue', 'purple', 'orange', 'brown', 'pink', 'gray', 'olive']
  53. for label in set(dbscan_model.labels_):
  54. if label == -1:
  55. cidx = -1
  56. else:
  57. cidx = label % len(colors)
  58. ax.scatter(clustered_data_df.loc[clustered_data_df['Cluster']==label, 'Dimension 1'],
  59. clustered_data_df.loc[clustered_data_df['Cluster']==label, 'Dimension 2'],
  60. clustered_data_df.loc[clustered_data_df['Cluster']==label, 'Dimension 3'],
  61. c=colors[cidx], marker='.', label='Cluster '+str(label))
  62. # 添加坐标轴标签和图例
  63. ax.set_xlabel('Dimension 1')
  64. ax.set_ylabel('Dimension 2')
  65. ax.set_zlabel('Dimension 3')
  66. ax.set_title('DBSCAN Clustering (TSNE)')
  67. plt.legend()
  68. plt.show()

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号