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

相关推荐
武子康1 天前
大数据-236 离线数仓 - 会员指标验证、DataX 导出与广告业务 ODS/DWD/ADS 全流程
大数据·后端·apache hive
武子康2 天前
大数据-235 离线数仓 - 实战:Flume+HDFS+Hive 搭建 ODS/DWD/DWS/ADS 会员分析链路
大数据·后端·apache hive
DianSan_ERP3 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
够快云库3 天前
能源行业非结构化数据治理实战:从数据沼泽到智能资产
大数据·人工智能·机器学习·企业文件安全
AI周红伟3 天前
周红伟:智能体全栈构建实操:OpenClaw部署+Agent Skills+Seedance+RAG从入门到实战
大数据·人工智能·大模型·智能体
B站计算机毕业设计超人3 天前
计算机毕业设计Django+Vue.js高考推荐系统 高考可视化 大数据毕业设计(源码+LW文档+PPT+详细讲解)
大数据·vue.js·hadoop·django·毕业设计·课程设计·推荐算法
计算机程序猿学长3 天前
大数据毕业设计-基于django的音乐网站数据分析管理系统的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)
大数据·django·课程设计
B站计算机毕业设计超人3 天前
计算机毕业设计Django+Vue.js音乐推荐系统 音乐可视化 大数据毕业设计 (源码+文档+PPT+讲解)
大数据·vue.js·hadoop·python·spark·django·课程设计
十月南城3 天前
数据湖技术对比——Iceberg、Hudi、Delta的表格格式与维护策略
大数据·数据库·数据仓库·hive·hadoop·spark
中烟创新3 天前
灯塔AI智能体获评“2025-2026中国数智科技年度十大创新力产品”
大数据·人工智能·科技