KMeans 适合围绕中心、需要预设簇数且要给新样本分组的场景;DBSCAN 适合按密度连接样本,并把部分低密度点标为噪声。选择时应同时看分布、距离尺度和上线预测需求,不能只比较跑出的簇数量。
环境与运行方法
本文代码在 Windows、Python 3.11 的本地独立环境执行通过。以下数据全部为人为构造的教学样本,不是客户数据,也不是业务效果测试。

新建一个空目录,在终端执行安装命令,把后面的完整代码保存为 demo.py,再执行 python demo.py。文件输出均保存在运行目录,请先在空目录练习。
python -m pip install numpy==2.4.6 scikit-learn==1.9.1
同一组样本上的三个差异
KMeans 需要指定 n_clusters,并把本次拟合中的每个样本分配给一个中心,即使那个点离主群很远。DBSCAN 使用 eps 邻域半径和 min_samples 邻域点数门槛,噪声标签为 -1,簇数由连接结果产生。
scikit-learn KMeans 提供 predict,可以把新样本分给已有中心;这里的 DBSCAN 没有标准 predict 接口。对新数据重新 fit 可能改变簇结构和编号,不能当作旧模型的稳定预测。
用离群点演示,再按任务决定
下面构造两个紧密三点群和一个远点,KMeans 设置两个中心,DBSCAN 设置 eps=0.3、min_samples=3。样本使用同样的二维单位,不额外缩放;在真实混合单位数据上,距离度量与尺度必须先处理。
如果必须将每条新记录映射到既定簇且分布近似中心团,可先验证 KMeans。若希望保留噪声且群形状不围绕球形中心,可验证 DBSCAN,但要检查密度变化和参数敏感性。高维或不同密度群不保证适合这两个默认方案。
可复制的完整代码
import numpy as np
from sklearn.cluster import KMeans, DBSCAN
X = np.array([[0, 0], [0.1, 0], [0, 0.1], [3, 3], [3.1, 3], [3, 3.1], [10, 10]])
km = KMeans(n_clusters=2, n_init=10, random_state=0).fit(X)
db = DBSCAN(eps=0.3, min_samples=3).fit(X)
print("kmeans_labels", km.labels_.tolist())
print("dbscan_labels", db.labels_.tolist())
print("dbscan_noise_indices", np.flatnonzero(db.labels_ == -1).tolist())
print("new_point_kmeans_cluster", km.predict([[0.05, 0.05]]).tolist())
print("dbscan_has_predict", hasattr(db, "predict"))
assert set(np.flatnonzero(db.labels_ == -1)) == {6}
assert (km.labels_ >= 0).all()
assert not hasattr(db, "predict")
运行结果与核对方法
下面是本文教学代码在上述本地环境中的实际输出。浮点数末位可能随依赖版本变化。
kmeans_labels [0, 0, 0, 0, 0, 0, 1]
dbscan_labels [0, 0, 0, 1, 1, 1, -1]
dbscan_noise_indices [6]
new_point_kmeans_cluster [0]
dbscan_has_predict False
核对 DBSCAN 将编号6的远点标为 -1,KMeans 所有标签都非负;新点有 KMeans 预测标签,而 dbscan_has_predict 为 False。不要比较0、1编号是否相同,簇编号没有跨模型语义。换距离尺度和参数后检查成员、噪声比例与业务含义,再作选择。
使用边界与常见问题
本例是七点教学对照,没有证明真实客户数据适合某算法,也没有提供普遍最佳参数。DBSCAN 在高维或密度差异很大的数据上需要额外评估,KMeans 的两个中心也可能被远点明显拉动。
噪声点是不是错误数据?
不一定。-1 只表示按本次参数没有进入密度簇,可能是罕见但合法样本。应回到原记录检查,而不是自动删除。
官方资料
接口与参数依据以下官方资料核对(2026年10月1日)。示例验证只覆盖本文输入和步骤。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30743.html