Flink ML K-Means 离线聚类 + 在线增量聚类(mini-batch + decayFactor)

一、K-Means(离线版):有限数据上的迭代聚类

1)输入列(Input Columns)

参数名 类型 默认值 说明
featuresCol Vector "features" 特征向量

2)输出列(Output Columns)

参数名 类型 默认值 说明
predictionCol Integer "prediction" 预测所属簇 ID(簇中心编号)

3)参数(Parameters)详解

KMeansModel(预测侧)参数
Key 默认值 类型 说明
distanceMeasure EuclideanDistanceMeasure.NAME String 距离度量(当前支持欧式距离)
featuresCol "features" String 特征列名
predictionCol "prediction" String 输出列名
k 2 Integer 簇数量(最大聚类数)
KMeans(训练侧)额外参数
Key 默认值 类型 说明
initMode "random" String 初始化方式(当前支持 random)
seed null Long 随机种子(保证可复现)
maxIter 20 Integer 最大迭代次数

4)Java 示例代码解读(离线 KMeans)

示例流程很标准:

  1. 构造输入数据(DenseVector 流)
  2. DataStream → Table,并命名为 features
  3. kmeans.fit(table) 训练得到 KMeansModel
  4. model.transform(table) 输出每条数据的簇 ID
  5. collect 打印 features + clusterId

关键代码片段:

java 复制代码
DataStream<DenseVector> inputStream =
        env.fromElements(
                Vectors.dense(0.0, 0.0),
                Vectors.dense(0.0, 0.3),
                Vectors.dense(0.3, 0.0),
                Vectors.dense(9.0, 0.0),
                Vectors.dense(9.0, 0.6),
                Vectors.dense(9.6, 0.0));
Table inputTable = tEnv.fromDataStream(inputStream).as("features");

KMeans kmeans = new KMeans().setK(2).setSeed(1L);
KMeansModel kmeansModel = kmeans.fit(inputTable);
Table outputTable = kmeansModel.transform(inputTable)[0];

输出打印(预测列是 Integer):

java 复制代码
DenseVector features = (DenseVector) row.getField(kmeans.getFeaturesCol());
int clusterId = (Integer) row.getField(kmeans.getPredictionCol());

二、Online K-Means:无界流上的持续聚类(mini-batch + 遗忘)

1)为什么需要 Online K-Means?

离线 KMeans 训练出来的中心是"固定"的。

但很多业务数据分布会随时间变化,例如:

  • 用户行为习惯变了
  • 商品/内容热点变化
  • 流量来源变化

这时你希望模型能"持续学习",让聚类中心跟着数据漂移而更新,就需要 Online K-Means。

2)Online K-Means 的核心思想(mini-batch + decayFactor)

Online K-Means 基于"mini-batch KMeans"的更新规则,并加入遗忘机制(decay):

  • 每次从训练流中积累一个 mini-batch
  • 基于这个 batch 计算临时中心(estimated centroids)
  • 用加权平均更新旧中心(original centroids):

decayFactor 解释(非常关键)

  • decayFactor = 1:历史与新数据同等重要(几乎不遗忘)
  • decayFactor = 0:完全由最新数据决定中心(强遗忘)
  • 值越小 → 遗忘越强 → 模型越"跟新"
  • 值越大 → 趋于稳定 → 变化越慢

3)输入输出列(Online)

输入列同离线:

参数名 类型 默认值 说明
featuresCol Vector "features" 特征向量

输出列同离线:

参数名 类型 默认值 说明
predictionCol Integer "prediction" 所属簇 ID

4)参数(OnlineKMeans)详解

OnlineKMeansModel(预测侧)
Key 默认值 类型 说明
distanceMeasure EuclideanDistanceMeasure.NAME String 距离度量(欧式距离)
featuresCol "features" String 特征列名
predictionCol "prediction" String 输出列名
k 2 Integer 簇数量
OnlineKMeans(训练侧)额外参数
Key 默认值 类型 说明
batchStrategy COUNT_STRATEGY String mini-batch 构造策略
globalBatchSize 32 Integer 全局 batch 大小
decayFactor 0.0 Double 遗忘系数(历史中心贡献缩放)
seed null Long 随机种子

5)Java 示例代码解读(OnlineKMeans)

示例里做了非常"演示型"的设计:训练数据分两段周期性出现,观察聚类结果如何随时间变化。

(1)训练流是无限流,周期性吐两批不同分布的数据
  • trainData1:大致在 (0~10) 附近
  • trainData2:分布跳到了 (10,100) 与 (-10,-100) 两块

这等于让数据分布发生"漂移",你就能看到在线聚类中心被新数据影响。

(2)predict 也是周期性吐同一组预测点
java 复制代码
List<Row> predictData =
        Arrays.asList(
                Row.of(Vectors.dense(10.0, 10.0)),
                Row.of(Vectors.dense(-10.0, 10.0)));

输出里会不停打印:

  • 两个点是否被分到同一个簇
    因为随着训练数据改变、中心改变,聚类结果可能随时间变化。
(3)初始化模型数据 initialModelData

在线聚类必须有初始中心,否则没法开始迭代。示例使用:

java 复制代码
.setInitialModelData(
    KMeansModelData.generateRandomModelData(tEnv, 2, 2, 0.0, 0)
)

含义是:

  • k=2 个中心
  • 每个中心 2 维
  • 随机生成初始中心
(4)globalBatchSize=6:每 6 条数据更新一次中心
java 复制代码
.setGlobalBatchSize(6)

这与训练数据每批 6 条刚好对应,便于演示"每批更新一次"的效果。

三、离线 KMeans vs 在线 OnlineKMeans:怎么选?

选离线 KMeans 的典型场景

  • 你有明确的历史数据窗口(按天、按周)
  • 模型周期性训练发布,追求稳定可控
  • 线上只是推理(transform),不希望训练影响延迟

选 OnlineKMeans 的典型场景

  • 数据持续流入且分布变化快
  • 你希望模型能持续适应新模式(概念漂移)
  • 你可以接受聚类结果随时间变化

四、实战建议(非常重要)

1)KMeans 之前强烈建议做标准化

KMeans 基于距离(欧式距离),特征尺度不同会导致"某个维度支配聚类"。典型做法:

  • VectorAssembler(拼特征)
  • StandardScaler(标准化)
  • KMeans / OnlineKMeans

2)k 的选择不要拍脑袋

常见方法:

  • 肘部法(Elbow)
  • 轮廓系数(Silhouette)
  • 结合业务可解释性(比如用户分群常选 5/8/10)

3)OnlineKMeans 的 decayFactor 是控制"跟新程度"的旋钮

简单经验:

  • 数据分布很稳定:decayFactor 接近 1
  • 数据漂移明显:decayFactor 取 0.1~0.5 让模型更灵活
  • 想快速跟随热点:decayFactor 更小

4)batch size 与更新频率要结合吞吐与稳定性

  • batch 小:更新快但抖动大
  • batch 大:更稳定但响应慢

五、小结

Flink ML 的 KMeans 家族可以覆盖绝大多数"聚类/分群"需求:

  • KMeans(离线):有限数据、迭代训练、中心稳定
  • OnlineKMeans(在线):无界流、mini-batch 更新、支持遗忘机制

掌握了 k / maxIter / globalBatchSize / decayFactor 这些关键参数,你就能把聚类从"demo"落到"线上可用"。

相关推荐
发哥来了16 小时前
AI视频生成企业级方案选型指南:2025年核心能力与成本维度深度对比
大数据·人工智能
北邮刘老师16 小时前
智能体治理:人工智能时代信息化系统的全新挑战与课题
大数据·人工智能·算法·机器学习·智能体互联网
诗词在线16 小时前
中国古代诗词名句按主题分类有哪些?(爱国 / 思乡 / 送别)
人工智能·python·分类·数据挖掘
geneculture17 小时前
融智学形式本体论:一种基于子全域与超子域的统一认知架构
大数据·人工智能·哲学与科学统一性·信息融智学·融智时代(杂志)
xiaobaishuoAI18 小时前
分布式事务实战(Seata 版):解决分布式系统数据一致性问题(含代码教学)
大数据·人工智能·分布式·深度学习·wpf·geo
edisao19 小时前
一。星舰到底改变了什么?
大数据·开发语言·人工智能·科技·php
昨夜见军贴061619 小时前
AI审核的自我进化之路:IACheck AI审核如何通过自主学习持续提升检测报告审核能力
大数据·人工智能
冬至喵喵20 小时前
二进制编码、base64
大数据
duyinbi751720 小时前
YOLOv8-SEG齿轮缺陷检测与分类系统实现_LAWDS
yolo·分类·数据挖掘
coding-fun20 小时前
电子发票批量提取导出合并助手
大数据·数据库