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

相关推荐
updayday854几秒前
供应商补交资质文件时,采购难以核对缺件和新版本 - Ping64 文件收集
大数据·网络·数据库·安全·智能路由器
小飞象—木兮4 分钟前
经营分析核心思路:经营分析的六层执行框架、底层原则、 全行业通用经营分析方法论
大数据·人工智能·矩阵·数据分析·用户运营
星云低代码开发平台19 分钟前
AI 销售周报的数据契约:CRM 商机、ERP 订单与异常核对
大数据·人工智能·企业ai
数脉24 分钟前
让每一次提问都有据可答:我们的数据血缘平台 AI 助手功能预告
大数据·数据挖掘·数据分析
Light6026 分钟前
四款云端 Agent 的安全边界画在三个地方
大数据·数据库·安全·个人agent·安全边界·提示注入·grok bot
starzy199029 分钟前
Flink 任务调度 Graph 源码深度剖析:从 StreamGraph 到 ExecutionGraph 的三层演进
java·大数据·flink
徐礼昭|商派软件市场负责人1 小时前
如何打通2B与2C库存?如何破解“线上缺货、线下积压”的内耗?——OMS全渠道「库存一盘货」策略详解
大数据·库存管理·订单管理·商派oms·oms系统
Regentsoft丽晶软件1 小时前
全渠道一盘货驱动零售品牌DTC转型,破除传统零售割裂和库存冗余
大数据·人工智能·零售
jkyy20141 小时前
从手机原生相机到医疗机构:规模化膳食采集能力的多场景落地实践
大数据·数码相机·智能手机·健康医疗