基于 Python 的聚类分析实践:K-Means 与 DBSCAN
·
类分析是无监督学习的核心任务之一,本文将结合实际代码案例,介绍两种经典的聚类算法 ——K-Means 和 DBSCAN 的实现过程,并通过轮廓系数评估聚类效果。
数据准备
本文使用的数据集为data.txt,包含啤酒的calories(卡路里)、sodium(钠含量)、alcohol(酒精含量)、cost(成本)四个特征维度,首先通过 Pandas 读取数据:
import pandas as pd
# 读取数据集
beer = pd.read_table('data.txt', sep=' ', encoding='utf8', engine='python')
# 提取特征列
X = beer[['calories', 'sodium', 'alcohol', 'cost']]
K-Means 聚类
K-Means 是基于距离的划分式聚类算法,核心是通过迭代将数据划分为 k 个簇,使簇内数据距离最小、簇间距离最大。
1. 寻找最优 k 值
轮廓系数(Silhouette Coefficient)是评估聚类效果的重要指标,取值范围为 [-1,1],越接近 1 表示聚类效果越好。我们遍历 k 值(2-9),计算对应的轮廓系数:
from sklearn.cluster import KMeans
from sklearn import metrics
import matplotlib.pyplot as plt
# 存储不同k值的轮廓系数
scores = []
for k in range(2, 10): # 遍历2到9个簇
# 训练K-Means模型并获取聚类标签
labels = KMeans(n_clusters=k, random_state=42).fit(X).labels_
# 计算轮廓系数
score = metrics.silhouette_score(X, labels)
scores.append(score)
# 打印各k值对应的轮廓系数
print("不同k值的轮廓系数:", scores)
# 可视化轮廓系数变化
plt.plot(list(range(2, 10)), scores)
plt.xlabel('Number of Clusters (k)')
plt.ylabel('Silhouette Score')
plt.title('Silhouette Score vs Number of Clusters')
plt.show()
2. 确定 k 值后执行聚类
根据轮廓系数结果,选择最优 k 值(示例中选择 k=2)执行最终聚类,并将结果合并到原数据:
# 训练最终K-Means模型
km = KMeans(n_clusters=2, random_state=42).fit(X)
# 将聚类标签添加到原数据框
beer['cluster'] = km.labels_
# 计算最终聚类结果的轮廓系数
final_score = metrics.silhouette_score(X, beer.cluster)
print("K-Means聚类(k=2)的轮廓系数:", final_score)
DBSCAN 聚类
DBSCAN(密度基于噪声的应用空间聚类)是基于密度的聚类算法,无需预先指定簇的数量,能自动识别离群点(噪声),核心参数为eps(邻域半径)和min_samples(邻域内最小样本数)。
from sklearn.cluster import DBSCAN
from sklearn import metrics
# 训练DBSCAN模型
"""
eps: 邻域半径,控制聚类的“密度”范围
min_samples: 邻域内最小样本数,低于该值则为噪声点(标签为-1)
labels: 聚类结果标签,-1表示离群点
"""
db = DBSCAN(eps=20, min_samples=2).fit(X)
labels = db.labels_
# 将聚类结果添加到原数据框
beer['cluster_db'] = labels
# 按聚类标签排序
beer_sorted = beer.sort_values('cluster_db')
print("DBSCAN聚类结果(按标签排序):")
print(beer_sorted.head())
# 计算DBSCAN聚类的轮廓系数
db_score = metrics.silhouette_score(X, beer.cluster_db)
print("DBSCAN聚类的轮廓系数:", db_score)
算法对比与总结
| 特征 | K-Means | DBSCAN |
|---|---|---|
| 聚类类型 | 划分式(基于距离) | 密度式 |
| 需指定参数 | 簇数量 k | 邻域半径 eps、最小样本数 |
| 离群点处理 | 无(强制划分) | 自动识别(标签 - 1) |
| 适用数据分布 | 凸形簇 | 任意形状簇 |
注意事项
- K-Means 对初始聚类中心敏感,建议设置random_state保证结果可复现;
- DBSCAN 的eps参数需结合数据分布调整,过大易合并簇,过小易产生过多噪声;
- 轮廓系数仅适用于数值型特征,且对数据尺度敏感,实际应用中建议先对特征标准化。
通过以上代码,可快速实现 K-Means 和 DBSCAN 聚类,并评估其效果,根据数据特点选择合适的算法能显著提升聚类质量。
更多推荐



所有评论(0)