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 列喂给模型
相关推荐
路溪非溪2 分钟前
Python语言的执行流程总结
开发语言·python
宋均浩26 分钟前
AI 生成代码质量防线实战:5 个 CI/CD 配置,把 8% 的逻辑错拦在线上之前0
python
kisbad29 分钟前
Day 036|OpenAI Agents SDK 快速开始:今天跑通第一个 Agent
java·前端·javascript
憧憬成为java架构高手的小白31 分钟前
langchain4j框架学习
java
树码小子37 分钟前
Pycharm解释器配置问题解决
ide·python·pycharm
国雪1 小时前
python-协程
python
0x531 小时前
Java网络编程(四)
java·网络
一木 之林1 小时前
Python.六.(一)--1.标准库、常用工具与基础操作(进阶)
python·rpc·dubbo
ly76891 小时前
Java 设计模式详解:从原则到 23 种经典模式
java·开发语言·设计模式
月光船幽幽1 小时前
铁牌协议卡:节流与重构
python·重构