AP聚类算法入门指南:从原理到Python实战

1次阅读
没有评论

共计 2495 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

为什么需要 AP 聚类?

刚接触聚类分析时,大家往往从 K -means 开始学习。但实践中会发现两个头疼的问题:

AP 聚类算法入门指南:从原理到 Python 实战

  • 必须预先指定聚类数量 K 值
  • 对初始中心点敏感,容易陷入局部最优

AP 聚类(Affinity Propagation)完美解决了这些痛点。它通过消息传递自动确定最佳聚类数量,且不需要随机初始化。我第一次用它分析用户行为数据时,仅用三行代码就得到了比 K -means 更合理的分组结果。

算法原理大白话

AP 聚类的核心思想很形象:假设数据点是一群参会者,每个人通过『喊话』决定谁当会议主持人(聚类中心)。整个过程依赖两个关键矩阵:

  • 相似度矩阵 (S):就像座位表,记录每两人之间的『亲密度』(负欧式距离)
  • 偏好参数 (preference):相当于每个人的『领导力』,值越大越可能成为中心

算法通过两种消息反复传递:

  1. 责任度 (responsibility):点 i 告诉点 k『你有多适合当我的代表』
  2. 可用度 (availability):点 k 回应点 i『我有多适合当大家的代表』

经过多次『讨论』后,最靠谱的中心点会脱颖而出。这个自组织过程让我联想到蚂蚁觅食时的群体智能。

手把手代码实战

下面用 Python 实现 AP 聚类完整流程,数据集使用经典的鸢尾花:

# 环境准备
import numpy as np
from sklearn.cluster import AffinityPropagation
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

# 数据加载与预处理
iris = datasets.load_iris()
X = iris.data[:, :2]  # 只取前两个特征方便可视化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)  # 重要!必须标准化数据

# 模型训练
af = AffinityPropagation(preference=-50, random_state=0).fit(X_scaled)
cluster_centers_indices = af.cluster_centers_indices_
labels = af.labels_
n_clusters = len(cluster_centers_indices)

print(f'自动识别的聚类数:{n_clusters}')

可视化结果时,我习惯用不同颜色标记聚类,并突出显示中心点:

# 结果可视化
plt.figure(figsize=(10, 6))
colors = ['#4EACC5', '#FF9C34', '#4E9A06', '#FF3300']

for k in range(n_clusters):
    class_members = labels == k
    cluster_center = X_scaled[cluster_centers_indices[k]]
    plt.scatter(X_scaled[class_members, 0], X_scaled[class_members, 1], 
                c=colors[k], s=20, alpha=0.5)
    plt.scatter(cluster_center[0], cluster_center[1], 
                c=colors[k], s=200, marker='*', edgecolor='k')

plt.title('AP 聚类结果(鸢尾花数据集)')
plt.xlabel('标准化后的花萼长度')
plt.ylabel('标准化后的花萼宽度')
plt.show()

参数调优实战技巧

preference 是最关键的参数,它控制聚类数量。通过实验发现:

  • 值越小 → 聚类数越少(领导力门槛高)
  • 值越大 → 聚类数越多(人人都能当领导)

我常用的调优方法是结合轮廓系数:

from sklearn.metrics import silhouette_score

preferences = range(-100, -10, 10)
silhouette_scores = []

for p in preferences:
    af = AffinityPropagation(preference=p, random_state=0).fit(X_scaled)
    if len(np.unique(af.labels_)) >= 2:  # 至少需要 2 个聚类才能计算
        score = silhouette_score(X_scaled, af.labels_)
        silhouette_scores.append(score)

plt.plot(preferences[:len(silhouette_scores)], silhouette_scores, 'bo-')
plt.xlabel('Preference 参数值')
plt.ylabel('轮廓系数')
plt.title('参数选择与聚类质量关系')
plt.grid(True)
plt.show()

新手避坑指南

根据我踩过的坑,总结这些经验:

  • 数据未标准化 :AP 聚类对尺度敏感,一定要用 StandardScaler 或 MinMaxScaler
  • 相似度计算不当 :默认使用负欧式距离,对于文本数据建议改用余弦相似度
  • preference 设置不合理 :可以先取相似度矩阵的中位数作为初始值
  • 内存溢出问题 :数据量 >1 万时建议换用 FastAP 等改进算法
  • 迭代不收敛 :适当调大 max_iter 参数(默认 200 次)

算法性能与适用场景

AP 聚类的时间复杂度是 O(N²T),其中 N 是样本数,T 是迭代次数。实测发现:

  • 1000 个样本:约 3 秒
  • 5000 个样本:约 2 分钟
  • 10000 个样本:内存可能溢出

与 K -means 对比:

特性 AP 聚类 K-means
需指定 K 值 不需要 必须指定
中心点初始化 自动确定 随机初始化
计算效率 O(N²) O(NKT)
最佳场景 中小规模数据 大规模数据

思考与延伸

当处理百万级数据时,AP 聚类会遇到严重性能瓶颈。业界常用的优化思路包括:

  1. 使用稀疏矩阵存储相似度
  2. 采用层次化 AP(先粗聚类再细化)
  3. 基于 GPU 加速的消息传递

你认为哪种方法最适合电商用户分群场景?欢迎在评论区分享见解。

正文完
 0
评论(没有评论)