1. 输入列(Input Columns)
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
featuresCol | Vector | "features" | 特征向量列 |
labelCol | Integer | "label" | 标签列(要预测的类别标签) |
weightCol | Double | "weight" | 样本权重(可选,用于处理样本不均衡等) |
说明:featuresCol必须是 Flink ML 的 Vector 类型(DenseVector/SparseVector)。
2. 输出列(Output Columns)
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
predictionCol | Integer | "prediction" | 预测标签(最终分类结果) |
rawPredictionCol | Vector | "rawPrediction" | 每个 label 的“原始预测向量”(可理解为得分/概率相关向量) |
注意:文档里把predictionCol描述成 “Label of the max probability”。从工程角度建议你这样理解:
rawPrediction:模型对各类别的打分向量(可能是 margin/score,也可能被映射为概率形式,具体依实现而定)prediction:在rawPrediction基础上做阈值/最大值选择后的最终标签
3. 参数(Parameters)详解
3.1 LinearSVCModel 参数(预测侧)
| Key | 默认值 | 类型 | 说明 |
|---|---|---|---|
featuresCol | "features" | String | 特征列名 |
predictionCol | "prediction" | String | 预测列名 |
rawPredictionCol | "rawPrediction" | String | 原始预测列名 |
threshold | 0.0 | Double | 二分类阈值:作用于 rawPrediction 来决定预测为 0 还是 1 |
threshold只在二分类时特别重要:
- rawPrediction 代表某种“置信/得分”,阈值决定了分类边界偏向哪个类别
- 你可以通过调节 threshold 来控制召回/精度的取舍
3.2 LinearSVC 训练参数(训练侧)
| Key | 默认值 | 类型 | 说明 |
|---|---|---|---|
labelCol | "label" | String | 标签列名 |
weightCol | null | String | 权重列名(不设置就不用权重) |
maxIter | 20 | Integer | 最大迭代次数 |
reg | 0.0 | Double | 正则化强度(防止过拟合) |
elasticNet | 0.0 | Double | ElasticNet 参数(0=L2,1=L1,介于其中混合) |
learningRate | 0.1 | Double | 学习率 |
globalBatchSize | 32 | Integer | 全局 batch size |
tol | 1e-6 | Double | 收敛容差(迭代停止条件之一) |
你可以把这些参数看作“线性模型 + 梯度优化”的通用训练配置:
maxIter + tol控制训练何时停止learningRate + batchSize控制优化步伐reg + elasticNet控制模型复杂度与稀疏性
4. Java 示例代码流程解读
你给的示例代码做了这几件事:
- 构造训练数据(features, label, weight)
- 设置
weightCol,训练 LinearSVC - 用训练后的模型对输入数据做 transform
- 打印 features / expected label / prediction / rawPrediction
示例代码的关键片段
4.1 构造输入表
DataStream<Row>inputStream=env.fromElements(Row.of(Vectors.dense(1,2,3,4),0.,1.),...Row.of(Vectors.dense(15,2,3,4),1.,5.));TableinputTable=tEnv.fromDataStream(inputStream).as("features","label","weight");这份数据大致表达:
- 第一类 label=0:features 的第一个维度在 1~5
- 第二类 label=1:features 的第一个维度在 11~15
因此线性可分,非常适合用线性 SVM 学到一个简单分割平面。
4.2 训练模型
LinearSVClinearSVC=newLinearSVC().setWeightCol("weight");LinearSVCModellinearSVCModel=linearSVC.fit(inputTable);设置weightCol表示不同样本对损失函数贡献不同权重。
在样本不均衡、或者你希望某些样本更重要时很有用。
4.3 预测并输出 rawPrediction
TableoutputTable=linearSVCModel.transform(inputTable)[0];模型输出一般会包含:
- 原始列:features / label / weight
- 新增列:prediction / rawPrediction
5. 一个很容易踩的坑:label 类型与示例的“不一致”
文档写的是:
labelCol类型:IntegerpredictionCol类型:Integer
但示例里 label 使用的是0./1.(Double),打印时也 cast 成Double:
doubleexpectedResult=(Double)row.getField(linearSVC.getLabelCol());doublepredictionResult=(Double)row.getField(linearSVC.getPredictionCol());为了少踩坑,建议你自己的工程里做两件事:
- 标签列
label用 Integer(0/1)更规范 - 输出 prediction 也按 Integer 读取
如果你沿用 Double,也要保证 train/predict/读取类型统一,否则容易出现类型转换异常或 schema 不匹配。
6. 实战建议:Linear SVC 在生产环境怎么用更稳
1)强烈建议做特征缩放(StandardScaler)
SVM 依赖 margin 和距离尺度,特征量纲差异会显著影响结果。典型做法:
- VectorAssembler(拼特征)
- StandardScaler(标准化)
- LinearSVC(训练)
这能明显提升收敛速度与模型稳定性。
2)调 threshold 来平衡召回与精度
二分类任务里,你可以把 threshold 当成“偏向正类/负类”的旋钮:
- threshold 调低:更容易预测为正类(召回↑,误报↑)
- threshold 调高:更保守(精度↑,漏报↑)
3)样本不均衡优先用 weightCol
比如正样本远少于负样本时:
- 给正样本更高权重
- 或给负样本更低权重
一般比盲目调参更直接有效。
4)正则化 reg + elasticNet 控制过拟合与稀疏
- 想要更稳定:提高
reg(偏 L2) - 想要更稀疏特征选择:提高
elasticNet(偏 L1)
7. 小结
Linear SVC 在 Flink ML 中的使用非常符合 Flink ML 的统一设计:
- 用 Table API 输入特征向量
features - 用
fit()训练得到LinearSVCModel - 用
transform()输出prediction和rawPrediction
理解这三点,你就能把它顺利放进 Pipeline 或 Graph 里,和特征工程、数据清洗、结果下游输出串起来。