【K-Means】

K-Means是一种经典的聚类算法,常用于数据挖掘、机器学习等领域,以下是关于它的详细介绍:

基本原理

  • K-Means算法的目标是将给定的数据集划分成K个不同的簇(cluster),使得同一簇内的数据点相似度较高,而不同簇之间的数据点相似度较低。
  • 这里的相似度通常是通过计算数据点之间的距离来衡量的,常见的距离度量方式有欧几里得距离等。

算法步骤

  1. 确定聚类的数量K:这通常需要根据具体问题的领域知识、数据的特点或者通过一些经验法则来预先设定。
  2. 初始化聚类中心:随机从数据集中选取K个数据点作为初始的聚类中心,也可以采用其他的初始化方法来尽量避免得到局部最优解。
  3. 分配数据点到最近的聚类中心:对于数据集中的每个数据点,计算它到各个聚类中心的距离,然后将该数据点分配到距离它最近的那个聚类中心所对应的簇中。
  4. 更新聚类中心:在将所有数据点都分配到相应的簇之后,重新计算每个簇的中心位置,通常是计算该簇内所有数据点的均值作为新的聚类中心。
  5. 重复步骤3和4:不断重复分配数据点和更新聚类中心的操作,直到聚类中心的位置不再发生明显变化(达到预设的收敛条件,比如前后两次迭代中聚类中心的移动距离小于某个阈值)或者达到了预设的最大迭代次数。

特点

  • 优点
    • 原理简单,容易理解和实现,计算复杂度相对较低,在处理大规模数据时也能有较好的表现。
    • 对于具有明显球形分布的数据聚类效果较好。
  • 缺点
    • 需要事先确定聚类的数量K,而K值的选择往往并不容易,如果K值选择不当,可能会得到不合理的聚类结果。
    • 对初始聚类中心的选取比较敏感,不同的初始中心可能会导致不同的聚类结果,有可能陷入局部最优解而错过全局最优解。
    • 只能处理数值型数据,对于非数值型数据需要进行适当的转换才能应用该算法。

应用场景

  • 在市场细分中,根据客户的消费行为、人口统计学特征等数据将客户划分成不同的群体,以便企业制定针对性的营销策略。

  • 在图像识别领域,对图像中的像素点进行聚类,从而实现图像分割等任务。

  • 在文本挖掘中,对文档向量进行聚类,将相似的文档归为一类,便于信息的整理和分析。

以下是使用Python实现K-Means聚类算法的示例代码

一、代码实现

python 复制代码
import numpy as np
import random


def kmeans(data, k, max_iterations=100):
    """
    K-Means聚类算法实现

    :param data: 输入的数据集,形状为 (n_samples, n_features),
                n_samples为数据点个数,n_features为每个数据点的特征数
    :param k: 要聚类的簇的数量
    :param max_iterations: 最大迭代次数,默认为100
    :return: centroids(聚类中心)和 labels(每个数据点所属的簇的标签)
    """

    # 随机选择k个数据点作为初始聚类中心
    n_samples, _ = data.shape
    centroids = data[random.sample(range(n_samples), k)]

    for _ in range(max_iterations):
        # 计算每个数据点到聚类中心的距离,并分配到最近的聚类中心对应的簇
        labels = []
        for point in data:
            distances = [np.linalg.norm(point - centroid) for centroid in centroids]
            label = np.argmin(distances)
            labels.append(label)
        labels = np.array(labels)

        # 更新聚类中心
        new_centroids = []
        for i in range(k):
            cluster_points = data[labels == i]
            new_centroid = np.mean(cluster_points, axis=0)
            new_centroids.append(new_centroid)
        new_centroids = np.array(new_centroids)

        # 如果聚类中心不再变化,就提前结束迭代
        if np.all(centroids == new_centroids):
            break

        centroids = new_centroids

    return centroids, labels

二、函数调用示例

python 复制代码
# 生成一些示例数据,这里假设数据是二维的,你可以根据实际情况替换
data = np.random.rand(100, 2)

# 设置聚类的簇数量
k = 3

# 调用kmeans函数进行聚类
centroids, labels = kmeans(data, k)

print("聚类中心:", centroids)
print("每个数据点所属的簇的标签:", labels)

三、代码注释说明

  1. kmeans函数

    • 这个函数实现了K-Means聚类算法的核心步骤。
    • 参数
      • data:传入的数据集,是一个二维数组,其中第一维表示数据点的数量,第二维表示每个数据点的特征数量。例如,data可以是一个形状为(100, 2)的数组,表示有100个数据点,每个数据点有2个特征。
      • k:指定要将数据集聚类成的簇的数量。
      • max_iterations:算法的最大迭代次数,默认设置为100次。如果在达到这个次数之前聚类中心不再变化,算法会提前结束迭代。
    • 返回值 :返回两个结果,centroids是聚类中心的数组,形状为(k, n_features),即有k个聚类中心,每个聚类中心的维度与数据点的特征维度相同;labels是一个一维数组,其长度等于数据点的数量,每个元素表示对应的数据点所属的簇的标签(从0到k - 1)。
  2. 初始化聚类中心

    • 在函数内部,首先通过n_samples, _ = data.shape获取数据集的行数(即数据点个数)。
    • 然后使用centroids = data[random.sample(range(n_samples), k)]随机从数据集中选取k个数据点作为初始的聚类中心。
  3. 迭代过程

    • 在每次迭代中:
      • 分配数据点到簇
        • 对于数据集中的每个数据点,通过循环计算它到各个聚类中心的距离。这里使用distances = [np.linalg.norm(point - centroid) for centroid in centroids]计算距离,其中np.linalg.norm是计算欧几里得距离的函数。然后通过label = np.argmin(distances)找到距离最近的聚类中心对应的簇标签,并将其添加到labels列表中。最后将labels列表转换为数组形式。
      • 更新聚类中心
        • 对于每个簇(从0到k - 1),通过cluster_points = data[labels == i]获取属于该簇的所有数据点。然后使用new_centroid = np.mean(cluster_points, axis=0)计算这些数据点的均值作为新的聚类中心,并将其添加到new_centroids列表中。最后将new_centroids列表转换为数组形式。
      • 检查收敛条件
        • 通过if np.all(centroids == new_centroids):检查当前迭代得到的聚类中心和上一次迭代的聚类中心是否完全相同。如果相同,说明聚类中心已经不再变化,算法提前结束迭代。否则,继续下一次迭代,并更新聚类中心为新得到的聚类中心。
  4. 函数调用示例部分

    • 首先使用data = np.random.rand(100, 2)生成了一些随机的二维数据作为示例数据集。这里你可以根据实际情况替换为真实的数据集。
    • 接着通过k = 3设置了聚类的簇数量为3。
    • 最后调用kmeans函数进行聚类,并通过print("聚类中心:", centroids)print("每个数据点所属的簇的标签:", labels)输出聚类中心和每个数据点所属的簇的标签。
相关推荐
ChoSeitaku1 小时前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
Fuxiao___1 小时前
不使用递归的决策树生成算法
算法
我爱工作&工作love我1 小时前
1435:【例题3】曲线 一本通 代替三分
c++·算法
行然梦实1 小时前
学习日记_20241110_聚类方法(K-Means)
学习·kmeans·聚类
秀儿还能再秀1 小时前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
学术搬运工1 小时前
【珠海科技学院主办,暨南大学协办 | IEEE出版 | EI检索稳定 】2024年健康大数据与智能医疗国际会议(ICHIH 2024)
大数据·图像处理·人工智能·科技·机器学习·自然语言处理
白-胖-子2 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower2 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯2 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui12 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展