K-means聚类算法--原理及代码

目录

 一、K-means 算法的基本原理

二、算法流程

 三、目标函数(损失函数)

四、优缺点

五、应用场景

六、仿真

七、K-means的python实现代码


         K-means 聚类算法是一种经典的无监督学习算法,主要用于对数据进行聚类分析(clustering)。它的目标是将数据划分为 K 个簇(cluster),使得每个簇内的数据点尽可能相似,而不同簇之间的数据点尽可能不同。

 一、K-means 算法的基本原理

K-means 的核心思想是:

  • 通过迭代优化,最小化类内平方误差(Within-Cluster Sum of Squares, WCSS)

  • 每个簇有一个中心点(质心,centroid)

  • 每个样本属于与其最近的簇中心。

二、算法流程

假设我们要将数据划分为 K 个簇,数据集为

第一步:初始化

随机选择 K 个样本作为初始簇中心

第二步:分配样本

将每个样本分配到与之欧几里得距离最近的簇中心对应的簇中:

第三步:更新簇中心

重新计算每个簇的中心(所有属于该簇样本的均值):

第四步:重复迭代

重复步骤 2 和 3,直到:

  • 簇中心不再变化,或者

  • 达到最大迭代次数,或者

  • 分配结果不再变化(收敛)

 三、目标函数(损失函数)

K-means 的优化目标是最小化总的簇内平方误差:

这个目标函数衡量了所有点到其所属簇中心的距离平方和。

四、优缺点

 优点:

  • 简单高效,计算速度快

  • 对大数据集效果较好

  • 易于实现

缺点:

  • 需要预先指定 K 值

  • 对初始簇中心敏感(可用 K-means++ 改进)

  • 只能发现球形簇结构,对非凸簇或不同密度的数据效果差

  • 对离群点敏感

五、应用场景

  • 图像压缩

  • 文本聚类(如新闻自动分类)

  • 客户分群(用户行为分析)

  • 异常检测

六、仿真

生成模拟数据,300个样本,分成3个中心,利用K-means算法分类离散数据。

仿真代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

# 生成模拟数据:300个样本,分成3个中心
X, y_true = make_blobs(n_samples=300, centers=3, cluster_std=0.60, random_state=0)

# 设置中文字体(以Windows为例)
plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体为黑体
plt.rcParams['axes.unicode_minus'] = False    # 解决负号显示问题


# 绘制原始数据
plt.figure(figsize=(6, 6))
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.title('原始数据分布')
plt.xlabel("X1")
plt.ylabel("X2")
plt.grid(True)
plt.show()



# 应用K-means聚类
kmeans = KMeans(n_clusters=3, random_state=0)
kmeans.fit(X)
y_kmeans = kmeans.predict(X)

# 可视化聚类结果
plt.figure(figsize=(6, 6))
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')  # 不同颜色表示不同的簇
centers = kmeans.cluster_centers_  # 提取簇中心
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='X', label='Centroids')
plt.title("K-means 聚类结果")
plt.xlabel("X1")
plt.ylabel("X2")
plt.legend()
plt.grid(True)
plt.show()

原始数据:

分类结果:

七、K-means的python实现代码

通过阅读理解代码,才能理解算法。

import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs

# 生成测试数据
X, _ = make_blobs(n_samples=300, centers=3, cluster_std=0.6, random_state=42)

# 设置超参数
K = 3  # 簇数
max_iters = 100  # 最大迭代次数
tolerance = 1e-4  # 收敛阈值

# Step 1: 随机初始化簇中心
np.random.seed(42)
initial_indices = np.random.choice(len(X), K, replace=False)
centroids = X[initial_indices]

def compute_distances(X, centroids):
    """计算每个点到每个中心的距离,返回[n_samples, K]矩阵"""
    distances = np.zeros((X.shape[0], K))
    for k in range(K):
        distances[:, k] = np.linalg.norm(X - centroids[k], axis=1)
    return distances

# K-means 主循环
for i in range(max_iters):
    # Step 2: 分配每个样本到最近的簇
    distances = compute_distances(X, centroids)
    labels = np.argmin(distances, axis=1)

    # Step 3: 更新簇中心
    new_centroids = np.array([X[labels == k].mean(axis=0) for k in range(K)])

    # Step 4: 检查是否收敛
    if np.linalg.norm(new_centroids - centroids) < tolerance:
        print(f"Converged at iteration {i}")
        break

    centroids = new_centroids

# 可视化聚类结果
plt.figure(figsize=(6, 6))
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', s=50)
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=200, marker='X', label='Centroids')
plt.title("K-means 手动实现聚类结果")
plt.legend()
plt.grid(True)
plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值