机器学习实战(7):聚类算法——发现数据中的隐藏模式

第7集:聚类算法------发现数据中的隐藏模式

在机器学习中,聚类(Clustering) 是一种无监督学习方法,用于发现数据中的隐藏模式或分组。与分类任务不同,聚类不需要标签,而是根据数据的相似性将其划分为不同的簇。今天我们将深入探讨 K-Means 聚类 的原理,并通过实践部分使用 顾客消费行为数据 进行分组。


K-Means 聚类的原理

什么是 K-Means?

K-Means 是一种基于距离的聚类算法,其目标是将数据划分为 K 个簇,使得每个样本点与其所属簇的中心(质心)的距离最小化。算法步骤如下:

  1. 随机选择 K 个初始质心。
  2. 将每个样本分配到最近的质心所在的簇。
  3. 更新质心为当前簇内所有样本的均值。
  4. 重复步骤 2 和 3,直到质心不再变化或达到最大迭代次数。

图1:K-Means 聚类过程

(图片描述:二维平面上展示了 K-Means 算法的迭代过程,初始随机质心逐渐调整位置,最终收敛到稳定状态。)


如何选择最佳的 K 值(肘部法则)

选择合适的 K 值是 K-Means 聚类的关键问题之一。常用的 肘部法则(Elbow Method) 通过绘制簇内误差平方和(SSE, Sum of Squared Errors)随 K$ 值的变化曲线来确定最佳 K 值。当 SSE 下降速度明显减缓时,对应的 K 值即为最佳值。

公式如下:
SSE = ∑ i = 1 K ∑ x ∈ C i ∣ ∣ x − μ i ∣ ∣ 2 \text{SSE} = \sum_{i=1}^{K} \sum_{x \in C_i} ||x - \mu_i||^2 SSE=i=1∑Kx∈Ci∑∣∣x−μi∣∣2

其中:
C i 是第 i 个簇。 C_i 是第 i 个簇。 Ci是第i个簇。
μ i 是第 i 个簇的质心。 \mu_i 是第 i 个簇的质心。 μi是第i个簇的质心。

图2:肘部法则示意图

(图片描述:折线图展示了 SSE 随 K 值的变化,随着 K 增加,SSE 逐渐减小,但在某个 K 值后下降趋于平缓,形成"肘部"。图中 K = 3 时形成"肘部"。)


层次聚类与 DBSCAN 简介

1. 层次聚类

层次聚类是一种基于树形结构的聚类方法,分为两种类型:

  • 凝聚式(Agglomerative):从单个样本开始,逐步合并最相似的簇。
  • 分裂式(Divisive):从整个数据集开始,逐步分裂成更小的簇。

优点:无需指定 K 值;缺点:计算复杂度较高。

2. DBSCAN(Density-Based Spatial Clustering of Applications with Noise)

DBSCAN 是一种基于密度的聚类算法,能够发现任意形状的簇,并对噪声点具有鲁棒性。其核心思想是:

  • 核心点:在某半径范围内有足够多的邻居点。
  • 边界点:在核心点的邻域内,但自身不是核心点。
  • 噪声点:既不是核心点也不是边界点。

优点:无需指定 K 值;缺点:对参数敏感。


聚类结果的可视化

聚类结果通常通过散点图进行可视化,不同簇用不同颜色表示。对于高维数据,可以使用降维技术(如 PCA 或 t-SNE)将其投影到二维或三维空间。


实践部分:使用 K-Means 对顾客消费行为数据进行分组

数据集简介

我们使用一个模拟的顾客消费行为数据集,包含以下特征:

  • Annual Income:年收入(单位:千美元)。
  • Spending Score:消费评分(范围 1-100,越高表示消费能力越强)。

目标是对顾客进行分组,以便制定个性化的营销策略。

完整代码

python 复制代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# 加载数据
url = "https://raw.githubusercontent.com/DennisKimt/datasets/main/Mall_Customers.csv"
data = pd.read_csv(url)

# 提取特征
X = data[['Annual Income (k$)', 'Spending Score (1-100)']]

# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 使用肘部法则选择最佳 K 值
sse = []
K_range = range(1, 11)
for k in K_range:
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans.fit(X_scaled)
    sse.append(kmeans.inertia_)

# 绘制肘部法则图
plt.figure(figsize=(8, 5))
plt.plot(K_range, sse, marker='o')
plt.title('Elbow Method for Optimal K', fontsize=16)
plt.xlabel('Number of Clusters (K)', fontsize=12)
plt.ylabel('Sum of Squared Errors (SSE)', fontsize=12)
plt.grid()
plt.show()

# 选择 K=5 构建 K-Means 模型
kmeans = KMeans(n_clusters=5, random_state=42)
clusters = kmeans.fit_predict(X_scaled)

# 可视化聚类结果
plt.figure(figsize=(10, 6))
plt.scatter(X.iloc[:, 0], X.iloc[:, 1], c=clusters, cmap='viridis', s=100, edgecolor='k')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red', label='Centroids', marker='X')
plt.title('Customer Segmentation using K-Means', fontsize=16)
plt.xlabel('Annual Income (k$)', fontsize=12)
plt.ylabel('Spending Score (1-100)', fontsize=12)
plt.legend()
plt.show()

运行结果

肘部法则图

图3:肘部法则图

(图片描述:折线图展示了 SSE 随 $ K $ 值的变化,当 $ K=5 $ 时,曲线出现明显的"肘部",表明这是最佳的簇数。)

聚类结果可视化

图4:K-Means 聚类结果

(图片描述:二维散点图展示了顾客的年收入与消费评分分布,不同簇用不同颜色表示,红色叉号标记了各簇的质心位置。)


总结

本文介绍了 K-Means 聚类的基本原理及其应用,并通过实践部分展示了如何使用 K-Means 对顾客消费行为数据进行分组。希望这篇文章能帮助你更好地理解聚类算法!


参考资料

相关推荐
@心都1 分钟前
机器学习数学基础:29.t检验
人工智能·机器学习
Dizzy.5176 分钟前
数据结构(查找)
数据结构·学习·算法
倒霉蛋小马3 小时前
【YOLOv8】损失函数
深度学习·yolo·机器学习
分别努力读书3 小时前
acm培训 part 7
算法·图论
武乐乐~3 小时前
欢乐力扣:赎金信
算法·leetcode·职场和发展
'Debug3 小时前
算法从0到100之【专题一】- 双指针第一练(数组划分、数组分块)
算法
补三补四3 小时前
金融时间序列【量化理论】
机器学习·金融·数据分析·时间序列
Fansv5873 小时前
深度学习-2.机械学习基础
人工智能·经验分享·python·深度学习·算法·机器学习
yatingliu20195 小时前
代码随想录算法训练营第六天| 242.有效的字母异位词 、349. 两个数组的交集、202. 快乐数 、1. 两数之和
c++·算法
uhakadotcom5 小时前
Google DeepMind最近发布了SigLIP 2
人工智能·算法·架构