机器学习之聚类算法K-means:原理、应用与实现

作者:JC2024.02.17 19:40浏览量:82

简介:本文将介绍聚类算法中的K-means,包括其工作原理、应用场景以及如何使用Python的sklearn库和手动实现K-means算法。

机器学习中,聚类是一种无监督学习方法,用于将数据点分组,使得同一组(或簇)内的数据点尽可能相似,而不同组之间的数据点尽可能不同。K-means算法是其中最著名的聚类算法之一。

一、K-means算法原理

K-means算法的核心思想是迭代地重新分配数据点到最近的簇中心,通过不断更新簇中心来优化聚类结果。具体步骤如下:

  1. 随机选择K个数据点作为初始簇中心。
  2. 将每个数据点分配给最近的簇中心,形成K个簇。
  3. 重新计算每个簇的中心,即簇中所有点的平均值。
  4. 重复步骤2和3,直到簇中心不再发生显著变化或达到预设的迭代次数。

二、K-means算法应用

K-means算法广泛应用于数据挖掘、图像处理、文本分析等领域。例如,在市场细分中,可以将客户按照购买行为和偏好分为不同的群体;在图像处理中,可以将像素点分为不同的区域;在文本分析中,可以将文档分为主题相似的组。

三、使用sklearn库实现K-means算法

Python的sklearn库提供了方便的接口来使用K-means算法。下面是一个简单的示例代码:

  1. from sklearn.cluster import KMeans
  2. import numpy as np
  3. # 生成随机数据
  4. data = np.random.rand(100, 2)
  5. # 创建KMeans实例,设置簇数量为3
  6. kmeans = KMeans(n_clusters=3)
  7. # 拟合数据并预测标签
  8. kmeans.fit(data)
  9. labels = kmeans.predict(data)
  10. # 输出聚类中心和标签
  11. print('Cluster centers:', kmeans.cluster_centers_)
  12. print('Labels:', labels)

这段代码首先生成了100个随机数据点,然后使用sklearn库中的KMeans类来拟合数据并预测标签。最后输出了聚类中心和每个数据点的标签。

四、手动实现K-means算法

虽然使用sklearn库实现K-means算法非常方便,但了解其手动实现过程对于深入理解聚类算法非常有帮助。下面是一个简单的K-means算法的手动实现:

  1. 初始化簇中心:随机选择K个数据点作为初始簇中心。
  2. 分配数据点到最近的簇中心:对于每个数据点,计算其到每个簇中心的距离,并将其分配给最近的簇中心。可以使用欧几里得距离作为距离度量。
  3. 重新计算簇中心:对于每个簇,重新计算其中心为簇内所有点的平均值。
  4. 重复步骤2和3,直到满足收敛条件(例如,簇中心不再发生显著变化或达到预设的迭代次数)。
  5. 输出聚类结果:包括每个数据点的标签和每个簇的中心。
    python,pythonpython
    import numpy as np
    from scipy.spatial import distance_matrix # 用于计算距离的库

def kmeans(data, n_clusters):

  1. # 初始化簇中心为随机选择的数据点
  2. centroids = data[np.random.choice(len(data), n_clusters, replace=False)]
  3. iterations = 0
  4. while True: # 循环直到满足收敛条件
  5. # 分配数据点到最近的簇中心
  6. labels = np.argmin(distance_matrix(data, centroids), axis=1)
  7. # 重新计算簇中心
  8. new_centroids = np.array([data[labels == i].mean(axis=0) for i in range(n_clusters)])
  9. # 检查收敛条件
  10. if np.allclose(centroids, new_centroids): # 如果簇中心不再发生显著变化,则跳出循环并返回结果
  11. break
  12. iterations += 1 # 迭代次数加一
  13. centroids = new_centroids # 更新簇中心为新的计算值
  14. return labels, centroids, iterations # 返回每个数据点的标签、每个簇的中心和迭代次数

```