Flink ML VectorAssembler 把多列特征“拼”成一个向量列(数值 + 向量都支持)

1. VectorAssembler 做什么?

给定一组输入列 inputCols(每列类型必须是 数值Vector ),把它们按顺序组合成一个新向量列 outputCol

  • 输入可以混合:

    • 单个数值列(Number)
    • DenseVector / SparseVector(Vector)
  • 输出是一个 Vector(通常是稠密或稀疏表示,取决于内部实现与输入组合)

典型用途:

  • StringIndexer -> OneHotEncoder -> VectorAssembler -> LogisticRegression
  • 数值特征 + one-hot 稀疏特征 + embedding 向量 -> VectorAssembler -> 模型

2. 输入列与输出列

输入列(Input Columns)

参数名 类型 默认值 说明
inputCols Number / Vector null 待拼接的列(可多列)

输出列(Output Columns)

参数名 类型 默认值 说明
outputCol Vector "output" 拼接后的向量列

3. 参数详解(Parameters)

Key 默认值 必填 说明
inputCols null 输入列名数组(顺序很重要)
outputCol "output" 输出列名
handleInvalid ERROR_INVALID 遇到非法值如何处理(如空值/类型不对等)

工程建议:

  • inputCols 的顺序决定最终向量的维度排列,一旦上线最好固定,否则训练/预测会对不上。

4. Java 示例逐段解读

示例里把三列拼成一列:

  • vec:DenseVector(2.1, 3.1)(长度 2)
  • num:数值 1.0(长度 1)
  • sparseVec:SparseVector(size=5, ...)(长度 5)

最终拼出来的向量长度应该是:2 + 1 + 5 = 8

4.1 输入数据

java 复制代码
DataStream<Row> inputStream =
        env.fromElements(
                Row.of(
                        Vectors.dense(2.1, 3.1),
                        1.0,
                        Vectors.sparse(5, new int[] {3}, new double[] {1.0})),
                Row.of(
                        Vectors.dense(2.1, 3.1),
                        1.0,
                        Vectors.sparse(
                                5,
                                new int[] {4, 2, 3, 1},
                                new double[] {4.0, 2.0, 3.0, 1.0})));
Table inputTable = tEnv.fromDataStream(inputStream).as("vec", "num", "sparseVec");

这里 sparseVec 的 size=5,意味着它代表长度为 5 的向量,只不过用稀疏方式存储非零位置。

4.2 创建 VectorAssembler

java 复制代码
VectorAssembler vectorAssembler =
        new VectorAssembler()
                .setInputCols("vec", "num", "sparseVec")
                .setOutputCol("assembledVec");

拼接顺序就是:vec 在前,num 在中间,sparseVec 在最后。

最终向量的 layout 可以理解为:

复制代码
assembledVec = [ vec(2 dims) | num(1 dim) | sparseVec(5 dims) ]

4.3 transform 并读取输出

java 复制代码
Table outputTable = vectorAssembler.transform(inputTable)[0];

Vector outputValue = (Vector) row.getField(vectorAssembler.getOutputCol());
System.out.printf("... Output Value: %s\n", outputValue);

输出 Value 会是一个 Vector(可能打印成 dense 或 sparse),内容会把三列的信息组合到同一个向量里。

5. 实战注意点(很关键)

1)OneHotEncoder 输出通常是 SparseVector,Assembler 非常适配

这也是最常见链路:

  • StringIndexer:city -> cityIndex
  • OneHotEncoder:cityIndex -> cityVec (SparseVector)
  • VectorAssembler:[数值列, cityVec, 其它Vec] -> features
  • LogisticRegression:features -> prediction

2)数值列不要忘记类型一致性

你的示例里 num 是 Double(1.0)。实际表里可能是 INT/LONG/FLOAT,建议统一成 Double 或确保能被识别为 Number。

3)维度稳定性是上线生命线

如果你在训练时 inputCols=["age","cityVec","deviceVec"],上线推理千万不要换成 ["cityVec","age","deviceVec"],否则模型输入维度语义全错。

4)handleInvalid 的选择

  • 离线训练:可以 ERROR_INVALID 让问题暴露
  • 线上:更倾向"先做清洗",或者用能跳过/替代的策略(如果支持),避免任务被脏数据打挂

6. 小结

VectorAssembler 是 Flink ML 里把"多列特征形态"统一成 features 向量列的关键组件:

  • 支持 Number + Vector 混合拼接
  • inputCols 顺序决定最终向量维度布局
  • 常用于把 one-hot、embedding、数值特征拼成一个 features 列喂给模型
相关推荐
dreamer_839926 分钟前
AI智能合同比对系统:从零搭建实战教程
人工智能·python
噢,我明白了1 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品1 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘1 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
AOwhisky1 小时前
Python 学习笔记(第十五期)——运维自动化(下·后篇):堡垒机实战——paramiko高阶篇
运维·python·学习·云原生·自动化·运维开发
Java内核笔记1 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端
观察员1 小时前
带你用一个 Python 图书系统,通关封装继承多态
python
糖果店的幽灵2 小时前
langgraph的 MessagesState 解读
java·开发语言·人工智能·windows·langgraph
极光代码工作室3 小时前
基于SpringBoot的在线博客系统
java·springboot·web开发·后端开发
林泽毅3 小时前
PyTRIO快速入门(一):概念、推理与训练
人工智能·python·深度学习·机器学习·语言模型