1. 输入列与输出列
输入列(Input Columns)
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
featuresCol | Vector | "features" | 特征向量列 |
labelCol | Integer | "label" | 标签列(要预测的类别) |
输出列(Output Columns)
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
predictionCol | Integer | "prediction" | 预测标签 |
2. 参数(Parameters)详解
2.1 NaiveBayesModel(预测侧)参数
| Key | 默认值 | 类型 | 说明 |
|---|---|---|---|
modelType | "multinomial" | String | 模型类型(目前支持 multinomial) |
featuresCol | "features" | String | 特征列名 |
predictionCol | "prediction" | String | 预测列名 |
2.2 NaiveBayes(训练侧)额外参数
| Key | 默认值 | 类型 | 说明 |
|---|---|---|---|
labelCol | "label" | String | 标签列名 |
smoothing | 1.0 | Double | 平滑参数(拉普拉斯平滑,避免零概率) |
smoothing 是干什么的?
在 multinomial 朴素贝叶斯里,经常会遇到某类样本中某个特征从未出现过的情况,这会导致该条件概率为 0,从而让整个后验概率变成 0。smoothing的作用就是避免这种“零概率”问题,让模型更稳健。
工程上:
1.0是最常见的默认选择- 数据稀疏、类别较多时,适当提高 smoothing 往往更稳定
3. Java 示例代码解读
你贴的示例逻辑非常标准,分四步:
1)构造训练数据(features, label)
2)构造预测数据(features)
3)创建 NaiveBayes 并设置参数
4)fit 训练模型 → transform 预测 → collect 打印结果
3.1 训练数据
DataStream<Row>trainStream=env.fromElements(Row.of(Vectors.dense(0,0.),11),Row.of(Vectors.dense(1,0),10),Row.of(Vectors.dense(1,1.),10));TabletrainTable=tEnv.fromDataStream(trainStream).as("features","label");这里的标签是10和11(多分类不一定要从 0 开始),特征向量是 2 维。
3.2 预测数据
DataStream<Row>predictStream=env.fromElements(Row.of(Vectors.dense(0,1.)),Row.of(Vectors.dense(0,0.)),Row.of(Vectors.dense(1,0)),Row.of(Vectors.dense(1,1.)));TablepredictTable=tEnv.fromDataStream(predictStream).as("features");预测表只有 features 列,符合朴素贝叶斯的推理输入。
3.3 创建与训练
NaiveBayesnaiveBayes=newNaiveBayes().setSmoothing(1.0).setFeaturesCol("features").setLabelCol("label").setPredictionCol("prediction").setModelType("multinomial");NaiveBayesModelnaiveBayesModel=naiveBayes.fit(trainTable);3.4 预测输出
TableoutputTable=naiveBayesModel.transform(predictTable)[0];输出表会新增prediction列。
4. 一个小坑:prediction 类型读取
文档定义predictionCol是Integer,但示例中用:
doublepredictionResult=(Double)row.getField(naiveBayes.getPredictionCol());这容易让人误会 prediction 是 Double。更稳的写法是按 Integer 读取:
Integerprediction=(Integer)row.getField(naiveBayes.getPredictionCol());建议你在工程里把 label 与 prediction 都保持 Integer 类型,减少类型转换问题。
5. multinomial 朴素贝叶斯的“工程适配”建议
1)multinomial 更适合“计数/频次类特征”
multinomial Naive Bayes 常见于:
- 词袋计数(word counts)
- TF/TF-IDF(有时也用,但严格上更像连续值,需要注意分布假设)
- 事件次数、出现频次等离散统计特征
如果你的 features 是非常连续的实数(如温度、金额、时长),multinomial 的假设可能不够贴合,效果未必好。此时你可以考虑:
- 先做分桶(binning)
- 或选择 Logistic Regression / LinearSVC 等线性模型
2)特征必须非负更稳
multinomial 模型通常假设特征类似“出现次数/频次”,因此:
- 负数特征会让概率解释变得很奇怪
- 工程上建议保证 features >= 0(或做平移/分桶)
3)smoothing 的调参思路
- 类别多、数据稀疏:smoothing 可以适当大一些
- 数据充足:smoothing=1.0 往往足够
6. 总结
Flink ML 的 Naive Bayes 非常适合做多分类 baseline,尤其在文本/稀疏特征场景下优势明显:
- 输入:
features(Vector)+label(Integer) - 输出:
prediction(Integer) - 关键参数:
modelType=multinomial、smoothing平滑避免零概率 - 用法:
fit()训练 →transform()预测,完全遵循 Flink ML 的 Table API 体系