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 列喂给模型
相关推荐
盼哥PyAI实验室2 小时前
[特殊字符]️ 实战爬虫:Python 抓取【采购公告】接口数据(含踩坑解析)
开发语言·爬虫·python
TeamDev2 小时前
使用 Vue.js 构建 Java 桌面应用
java·前端·vue.js
Biehmltym2 小时前
【AI】04AI Aent:十分钟跑通LangGraph项目:调用llm+agent开发+langSmith使用
java·人工智能·langchain·langgraph
Csvn2 小时前
🐫 Ollama 基础使用指南
人工智能·python
SCBAiotAigc2 小时前
opencv-python学习笔记(一):画线、打开摄像头
人工智能·python·opencv
Samson Bruce2 小时前
【docker swarm】
java·docker·eureka
狂放不羁霸2 小时前
VSCode | 设置保存时自动格式化 Python 文件
ide·vscode·python
代码笔耕2 小时前
面向对象开发实践之消息中心设计(四)--- 面向变化的定力
java·设计模式·架构
唐叔在学习2 小时前
buildozer打包详解:细说那些我踩过的坑
android·后端·python