news 2026/6/10 15:45:13

Flink ML KNN 入门基于 Table API 的近邻分类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flink ML KNN 入门基于 Table API 的近邻分类

1. 输入列与输出列

输入列(Input Columns)

参数名类型默认值含义
featuresColVector"features"特征向量列
labelColInteger"label"标签列(训练/评估用,也可用于对比)

输出列(Output Columns)

参数名类型默认值含义
predictionColInteger"prediction"预测标签列

说明:Flink ML 的Vector通常是DenseVectorSparseVector(特征列必须是向量类型)。

2. 参数(Parameters)

KnnModel 需要的参数

Key默认值类型必填含义
k5Integer选择最近邻的数量
featuresCol"features"String特征列名
predictionCol"prediction"String输出预测列名

Knn 额外需要的参数

Key默认值类型必填含义
labelCol"label"String标签列名

3. Java 示例代码(原理 + 流程)

下面是你贴的示例逻辑做一个“工程化解读”:

  1. 构造训练集trainTable(features, label)
  2. 构造待预测集predictTable(features, label)(这里 label 是“期望值/对照值”,不是必须列,但方便打印对比)
  3. knn.fit(trainTable)生成knnModel
  4. knnModel.transform(predictTable)输出结果表,新增prediction
  5. collect 输出并打印 features、expected、prediction

需要注意的一个坑:label 类型

文档说labelColInteger,但你贴的代码训练数据里是1.0/2.0/3.0这种Double。示例里又用:

doubleexpectedResult=(Double)row.getField(knn.getLabelCol());doublepredictionResult=(Double)row.getField(knn.getPredictionCol());

这会让人误以为 prediction 也是 Double。为了更“规范且不踩坑”,建议你在自己项目里统一 label 为Integer(或至少保持 train/predict/输出一致)。

下面我给一个“更规范版本”的示例(仅改了 label 为 Integer,并显式设置列名,逻辑不变)。

更规范的示例(建议用这个)

importorg.apache.flink.ml.classification.knn.Knn;importorg.apache.flink.ml.classification.knn.KnnModel;importorg.apache.flink.ml.linalg.DenseVector;importorg.apache.flink.ml.linalg.Vectors;importorg.apache.flink.streaming.api.datastream.DataStream;importorg.apache.flink.streaming.api.environment.StreamExecutionEnvironment;importorg.apache.flink.table.api.Table;importorg.apache.flink.table.api.bridge.java.StreamTableEnvironment;importorg.apache.flink.types.Row;importorg.apache.flink.util.CloseableIterator;publicclassKnnExample{publicstaticvoidmain(String[]args)throwsException{StreamExecutionEnvironmentenv=StreamExecutionEnvironment.getExecutionEnvironment();StreamTableEnvironmenttEnv=StreamTableEnvironment.create(env);// 训练数据:features(Vector) + label(Integer)DataStream<Row>trainStream=env.fromElements(Row.of(Vectors.dense(2.0,3.0),1),Row.of(Vectors.dense(2.1,3.1),1),Row.of(Vectors.dense(200.1,300.1),2),Row.of(Vectors.dense(200.2,300.2),2),Row.of(Vectors.dense(200.3,300.3),2),Row.of(Vectors.dense(2.8,3.2),3),Row.of(Vectors.dense(300.0,3.2),4),Row.of(Vectors.dense(2.4,3.2),5),Row.of(Vectors.dense(2.5,3.2),5));TabletrainTable=tEnv.fromDataStream(trainStream).as("features","label");// 待预测数据:这里保留 label 作为期望值/对照值(可选)DataStream<Row>predictStream=env.fromElements(Row.of(Vectors.dense(4.0,4.1),5),Row.of(Vectors.dense(300.0,42.0),2));TablepredictTable=tEnv.fromDataStream(predictStream).as("features","label");// 创建 Knn,并设置关键参数Knnknn=newKnn().setK(4).setFeaturesCol("features").setLabelCol("label").setPredictionCol("prediction");// 训练模型KnnModelknnModel=knn.fit(trainTable);// 预测TableoutputTable=knnModel.transform(predictTable)[0];// 打印结果:features + expected(label) + predictionfor(CloseableIterator<Row>it=outputTable.execute().collect();it.hasNext();){Rowrow=it.next();DenseVectorfeatures=(DenseVector)row.getField(knn.getFeaturesCol());Integerexpected=(Integer)row.getField(knn.getLabelCol());Integerprediction=(Integer)row.getField(knn.getPredictionCol());System.out.printf("Features: %-15s \tExpected: %s \tPrediction: %s\n",features,expected,prediction);}}}

4. 输出结果怎么看?

输出表一般会包含:

  • 原始输入列:features、(可选)label
  • 新增输出列:prediction

你打印时就能看到:

  • Features:待预测样本的向量
  • Expected:样本原本的标签(如果你在 predictTable 里带了 label)
  • Prediction:KNN 预测出来的标签

5. 实战建议(很关键)

1)特征缩放非常重要

KNN 完全依赖“距离”。如果你的特征尺度差异很大(比如一个特征是 0~1,另一个是 0~10000),距离会被大尺度特征主导,结果很容易失真。常见做法是:

  • 先用StandardScaler标准化
  • 或做 MinMax 归一化

2)k 的选择是个“偏差-方差”平衡

  • k 小:更敏感,容易受噪声影响(方差大)
  • k 大:更平滑,但可能把边界抹平(偏差大)

工程上建议从 3/5/7/9 这类奇数开始试(减少投票平局的概率)。

3)训练数据量大时的性能与资源

KNN 的预测开销通常和训练集规模相关(需要找近邻)。训练集很大时:

  • 可能需要索引/近似近邻(ANN)思路(具体要看 Flink ML 当前实现能力)
  • 或对数据做分桶、预聚类、抽样
  • 或考虑换更适合大规模在线推理的模型(线性模型、树模型等)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 15:38:34

YOLOv8 vs YOLOv9:精度与速度的博弈,谁更适合工业部署?

YOLOv8 vs YOLOv9&#xff1a;精度与速度的博弈&#xff0c;谁更适合工业部署&#xff1f; 在现代智能制造产线中&#xff0c;一个微小划痕可能意味着整批产品被召回。如何让机器“看”得既快又准&#xff1f;这正是目标检测技术的核心挑战。YOLO系列自诞生以来&#xff0c;始终…

作者头像 李华
网站建设 2026/6/10 2:11:44

计算机毕业设计,基于springboot的学生宿舍信息管理系统,附源码+数据库+论文,包远程安装调试运行

1、项目介绍 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了学生宿舍信息管理系统的开发全过程。通过分析学生宿舍信息管理系统管理的不足&#xff0c;创建了一个计算机管理学生宿舍信息管理系统的方案。文章介绍了…

作者头像 李华
网站建设 2026/6/10 12:26:13

Python工程師年薪從80萬到300萬:我掌握的10個高階技能清單

Python工程師年薪從80萬到300萬&#xff1a;我掌握的10個高階技能清單引言&#xff1a;從代碼工匠到技術決策者還記得五年前&#xff0c;當我拿到第一個80萬年薪Python工程師offer時的興奮。那時我以為自己已經達到了職業生涯的頂峰——熟練掌握Django、Flask&#xff0c;能獨立…

作者头像 李华
网站建设 2026/6/10 14:10:06

YOLO目标检测Web Demo上线!后台由GPU实时驱动

YOLO目标检测Web Demo上线&#xff01;后台由GPU实时驱动 在智能视觉应用日益普及的今天&#xff0c;用户对“即时反馈”的期待正不断推高技术门槛。无论是上传一张图片想立刻知道里面有什么物体&#xff0c;还是希望在监控画面中实时识别异常行为&#xff0c;背后都离不开一个…

作者头像 李华
网站建设 2026/6/10 14:09:57

YOLOv7-E6E发布!更大颈部结构但GPU内存控制得当

YOLOv7-E6E&#xff1a;更大颈部结构&#xff0c;更强特征融合&#xff0c;更优显存控制 在智能制造产线高速运转的今天&#xff0c;一个微小焊点的漏检可能引发整批产品的召回&#xff1b;在城市级视频监控系统中&#xff0c;一次对远距离行人的误判可能导致安防响应滞后。这些…

作者头像 李华
网站建设 2026/6/10 12:32:14

健康的关系不是单方面索取:想要别人爱你,要先学会爱自己,让别人知道你并不是一个缺爱的人,他才会更爱你

健康的关系不是单方面索取:想要别人爱你,要先学会爱自己,让别人知道你并不是一个缺爱的人,他才会更爱你 下载链接: https://download.csdn.net/download/qq_38998213/92508853目录 健康的关系不是单方面索取:想要别人爱你,要先学会爱自己,让别人知道你并不是一个缺爱…

作者头像 李华