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"落到"线上可用"。

相关推荐
TDengine (老段)1 小时前
TDengine 线程模型 — 网络、调度、执行
大数据·数据库·物联网·制造·时序数据库·tdengine·涛思数据
智购科技自动贩卖机4 小时前
自动售货机嵌入式状态机设计实战:从45个事件源到层次型状态机的工程重构
大数据·人工智能·stm32·物联网·重构·硬件架构
乐迪信息4 小时前
智慧港口船舶AI算法实现在线状态监测
大数据·人工智能·深度学习·算法·计算机视觉
Raas1004 小时前
MAI Gateway(魔芋企业级AI网关)对比分析:AI网关和API网关区别?企业级能力差距一览
大数据·人工智能·数据挖掘·mai gateway·企业级产品
Neighbor_OldY4 小时前
云上安全配置审计与误配置修复实战:从安全组、OSS、RAM到数据库的全栈排查复盘
大数据·运维·安全·云计算
工业甲酰苯胺5 小时前
AI低代码破局:制造业数智转型落地实战
大数据·人工智能·低代码·制造
头茬韭菜5 小时前
第 01 篇:「架构鸟瞰与进程启动链路」—— JobManager / TaskManager 从零长出来的完整调用链
架构·flink
大大大大晴天6 小时前
每天认识一个组件:流式存储Apache Fluss
大数据
熊野君6 小时前
第 4 章 技术产品经理核心能力模型
大数据·人工智能·产品经理
财复视界6 小时前
光智科技从“光学元件”到“稀散金属材料平台”的进化逻辑
大数据·人工智能·科技