当前位置: 首页 > news >正文

【字节跳动】数据挖掘面试题0007:Kmeans原理,何时停止迭代

文章大纲

      • K-means 原理与迭代停止条件
      • ⚙️ 一、K-Means核心思想
      • 🔁 二、迭代步骤详解
        • 关键数学操作
      • ⏹️ 三、何时停止迭代?
        • Kmeans 算法实现代码
      • ⚠️ 四、面试常见扩展问题
        • 1. K值如何选择?
        • 2. 初始质心影响结果吗?
        • 3. 算法缺陷与改进
      • 💎 五、总结与面试回答要点

K-means 原理与迭代停止条件

以下是针对数据挖掘面试题中K-Means原理及迭代停止条件的清晰解析,结合算法本质与面试考点整理,便于你快速掌握核心要点。


⚙️ 一、K-Means核心思想

K-Means是无监督聚类算法,目标是将n个数据点划分为k个簇(cluster),使得簇内距离最小化,簇间距离最大化。其迭代过程是EM(Expectation-Maximization)算法的特例,分两步交替进行:

    1. E步(分配点):固定质心,将每个点分配到最近的质心所属簇。
    1. M步(更新质心):固定簇分配,根据簇内点重新计算质心位置。

💡 通俗比喻
假设有k个班主任(质心)在教室随机站位,学生(数据点)选择最近的班主任排队。
班主任随后走到队伍中心点,学生重新排队。重复此过程直到班主任不再移动。
在这里插入图片描述


🔁 二、迭代步骤详解

以下流程图展示单次迭代过程:
在这里插入图片描述

关键数学操作
  • 距离计算:常用欧式距离 ∥ x i − μ j ∥ 2 \|x_i - \mu_j\|^2 xiμj2,决定点所属簇。
  • 质心更新:质心 μ j \mu_j μj = 1 ∣ C j ∣ ∑ x i ∈ C j x i \frac{1}{|C_j|} \sum_{x_i \in C_j} x_i Cj1xiCjxi,即簇内所有点的均值。

⏹️ 三、何时停止迭代?

停止条件决定算法收敛时机,常见以下四类

停止条件类型判断标准应用场景代码参数示例
1. 质心变化量≤阈值新旧质心距离 < ε(如 ε=1e-4)精确收敛要求高时tol=0.0001
2. 簇分配不再变化无点改变所属簇需稳定分类结果时无显式参数,自动检测
3. 目标函数收敛SSE(簇内平方和)下降量 < δ(如 δ=0.01)关注聚类质量优化时通过SSE监控
4. 达到最大迭代次数迭代次数 ≥ max_iter(如 300)防止无限循环/耗时敏感场景max_iter=100
  • Kmeans 算法停止迭代的条件通常有以下几种:
    • 质心不再变化:新计算的质心与上一次的质心完全相同(或差异小于某个极小阈值),说明聚类已经收敛。
    • 达到最大迭代次数:设置一个最大迭代次数(如 100 次),避免算法陷入无限循环。
    • 簇分配不再变化:所有数据点的簇分配在两次迭代之间没有改变。

📌 注意

  • 条件1~3满足任一即停止,条件4是 强制终止 的保底策略
  • 条件1与2不等价:质心微小移动可能不引起重新分配,但SSE仍在优化。
Kmeans 算法实现代码
import numpy as np
import matplotlib.pyplot as pltdef kmeans(X, K, max_iterations=100):"""K-means聚类算法实现参数:X: 输入数据,形状为(n_samples, n_features)K: 聚类的数量max_iterations: 最大迭代次数返回:centroids: 最终的质心坐标,形状为(K, n_features)labels: 每个数据点的聚类标签,形状为(n_samples,)"""# 1. 随机初始化质心:从输入数据中随机选择K个点作为初始质心# replace=False# 表示抽样时不允许重复选择同一个元素,确保每次选择的索引都是唯一的。centroids = X[np.random.choice(len(X), K, replace=False)]for iteration in range(max_iterations):# 2. 分配数据点到最近的质心# 计算每个数据点到每个质心的欧氏距离# np.linalg.norm:计算向量的范数(默认是欧氏范数,即平方和开根号)distances = np.array([np.linalg.norm(X - centroid, axis=1) for centroid in centroids])# 为每个数据点分配最近质心的索引作为聚类标签# NumPy 中用于查找数组中最小值索引的函数调用,在 Kmeans 算法中用于将每个数据点分配到最近的质心。labels = np.argmin(distances, axis=0)# 3. 更新质心:计算每个簇内所有点的平均值作为新质心new_centroids = np.array([X[labels == k].mean(axis=0) for k in range(K)])# 检查停止条件:如果新旧质心之间的差异小于阈值,则认为算法收敛# np.allclose(centroids, new_centroids) 是 NumPy 中用于比较两个数组是否几乎相等的函数,在 Kmeans 算法中用于判断聚类是否收敛。if np.allclose(centroids, new_centroids):print(f"Converged after {iteration+1} iterations")breakcentroids = new_centroidsreturn centroids, labels# 生成示例数据:创建3个不同的高斯分布数据集
np.random.seed(42)  # 设置随机种子,确保结果可重现
X = np.vstack([np.random.normal([0, 0], 1, size=(100, 2)),    # 第一个簇:均值[0,0],标准差1np.random.normal([5, 5], 1, size=(100, 2)),    # 第二个簇:均值[5,5],标准差1np.random.normal([10, 0], 1, size=(100, 2))    # 第三个簇:均值[10,0],标准差1
])# 运行Kmeans算法,将数据聚为3类
K = 3
centroids, labels = kmeans(X, K)# 可视化聚类结果
plt.figure(figsize=(8, 6))
# 绘制数据点,使用不同颜色表示不同的簇
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.6)
# 绘制最终的质心位置,使用红色X标记
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=200, marker='X')
plt.title('Kmeans Clustering Results')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()

在这里插入图片描述

在这里插入图片描述


⚠️ 四、面试常见扩展问题

1. K值如何选择?
  • 肘部法则(Elbow Method):绘制K-SSE曲线,选SSE骤降点。
  • 轮廓系数(Silhouette Score):衡量簇内紧密度与簇间分离度,接近1表示聚类合理。
2. 初始质心影响结果吗?
  • 随机初始化可能导致局部最优。
  • 改进方案:K-Means++,通过概率分布选择分散的初始质心。
3. 算法缺陷与改进
  • 缺陷对异常值敏感、假设簇为球形分布、依赖K值预设
  • 改进
    • 异常值处理:离群点检测(如DBSCAN)
    • 非球形簇:谱聚类或核K-Means。

💎 五、总结与面试回答要点

  • 原理EM框架下的交替优化(分配点 → 更新质心)
  • 停止条件质心稳定/簇分配不变/SSE收敛/达到最大迭代次数
  • 考点延伸
    • 结合RFM模型解释K-Means应用(用户分层场景)。
    • 时间复杂度: O ( K ⋅ n ⋅ d ) O(K \cdot n \cdot d) O(Knd)(n样本数,d特征数,K簇数)。
http://www.lryc.cn/news/579635.html

相关文章:

  • 深度解析:Java内部类与外部类的交互机制
  • BitsAndBytesConfig量化及注意事项
  • Mysql锁机制与优化实践以及MVCC底层原理剖析
  • Unity单元测试框架在keil环境下的移植教程
  • Unity3D 文件夹注释工具
  • CTF Web的数组巧用
  • 互联网大厂Java面试实录:Spring Boot与微服务在电商场景中的应用
  • STM32-第二节-GPIO输入(按键,传感器)
  • Linux基本指令(下)
  • 建设工程停工损失从哪些方面取证,如何取证?
  • 经典灰狼算法+编码器+双向长短期记忆神经网络,GWO-Transformer-BiLSTM多变量回归预测,作者:机器学习之心!
  • 在鸿蒙(HarmonyOS)中安装 .app 格式的应用包(即 HAP 或 APP 文件),可以通过以下方法实现
  • 服务器如何配置SSH密钥登录提高安全性?
  • 基于Anything LLM的本地知识库系统远程访问实现路径
  • vue2+elementui使用compressorjs压缩上传的图片
  • 机器人“触摸”水果成熟度突破:SwishFormer模型与DIGIT视触觉传感器在HelloRobot上的水果检测应用
  • 从0到1解锁Element-Plus组件二次封装El-Dialog动态调用
  • Unity-Shader-几何着色器
  • 学习设计模式《十六》——策略模式
  • Linux 73 LAMP4
  • 离线迁移 Conda 环境到 Windows 服务器:用 conda-pack 摆脱硬路径限制
  • 从0开始学习R语言--Day37--CMH检验
  • VR 果蔬运输开启农业物流新变革
  • AI无标记动捕如何结合VR大空间技术打造沉浸式游戏体验
  • 从0到1实战!用Docker部署Qwerty Learner输入法的完整实践过程
  • https如何利用工具ssl证书;使用自己生成的证书
  • 创建 TransactionStatus
  • rabbitmq 与 Erlang 的版本对照表 win10 安装方法
  • Debian-10-standard用`networking`服务的`/etc/network/interfaces`配置文件设置多网卡多IPv6
  • 贝叶斯深度学习:赋予AI不确定性感知的认知革命