You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark转PMML失败求助:无法用转换后数据生成PMML文件

问题分析与解决方案

核心问题

第一种方法失败的根本原因是:你把数据转换(StringIndexer)和模型训练拆成了两个独立的Pipeline,最终的dts_model只包含RFormula和决策树的逻辑,丢失了前面StringIndexer的转换元数据。而indexed_data本身带有StringIndexer生成的列元数据,pyspark2pmml在结合这个DataFrame和不完整的Model时,无法正确对齐数据处理流程,最终触发报错。

CSV导出再导入的方法能成功,是因为导出再读入后的test_df是无额外元数据的纯基础类型DataFrame,列类型都是普通数值/字符串,和RFormula训练时的预期完全匹配,pyspark2pmml可以正常解析整个流程。

正确实现方式

你需要把StringIndexer、RFormula、决策树整合到同一个Pipeline中,让从数据预处理到模型训练的完整流程被记录在PipelineModel里,这样pyspark2pmml就能正确生成包含所有预处理逻辑的PMML文件。

修改后的代码如下:

... (previous steps)

filtered_data = filtered_data.filter(data['year'] <= '2020')

cat_cols = ['CYC_CLASS', 'CYC_DISCHPORT']
num_cols = ['weekofyear']
label_cols = 'dwell_time'

# 直接处理原始分类列,生成索引后列
si = [StringIndexer(inputCol=d, outputCol=d + "_indexed", handleInvalid='keep') for d in cat_cols]
# 特征列替换为索引后的分类列+数值列
feat_cols = [d + "_indexed" for d in cat_cols] + num_cols

# 基于处理后的特征列定义RFormula
formula = RFormula(formula = f"{label_cols} ~ {' + '.join(feat_cols)}")

dt_clf = DecisionTreeClassifier(maxBins=10)

# 整合所有步骤到同一个Pipeline
full_pipeline = Pipeline(stages = si + [formula, dt_clf])
# 使用原始filtered_data训练完整Pipeline
dts_model = full_pipeline.fit(filtered_data)

# 生成PMML
from pyspark2pmml import PMMLBuilder
pmmlDTs = PMMLBuilder(spark, filtered_data, dts_model)
pmmlDTs.buildFile("test_dtsi_22121230556.pmml")

关键差异说明

  1. 流程完整性

    • 错误方法:数据转换和模型训练分离,Model不包含预处理逻辑,PMMLBuilder无法理解indexed_data的列来源。
    • 正确方法:整个流程从原始数据到模型训练都在一个Pipeline里,Model包含所有预处理+训练逻辑,PMMLBuilder可以完整解析并生成符合规范的PMML。
  2. 元数据处理

    • indexed_data的列带有StringIndexer生成的元数据(比如标签到索引的映射),但单独训练的dts_model未关联这些元数据,导致PMMLBuilder解析时出现不匹配。
    • CSV导出再导入会丢失所有列元数据,变成纯基础类型,此时Model和DataFrame的元数据完全对齐,虽然能生成PMML,但会丢失预处理逻辑,实际部署使用时会出现数据不兼容问题。

内容的提问来源于stack exchange,提问作者fritzp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:25:24