Java 在Python 3.6中调用sklearn2pmml()函数会引发RuntimeError

Java 在Python 3.6中调用sklearn2pmml()函数会引发RuntimeError,java,python,machine-learning,pipeline,pmml,Java,Python,Machine Learning,Pipeline,Pmml,我试图将管道对象保存为PMML,Python抛出一个运行时错误 我的Python版本是3.6,sklearn2pmml版本是0.44.0,JDK版本是1.8.0\u 201 所有这些都符合软件包的先决条件 以下是我到目前为止所做的。(我不包括数据加载和清理部分) 在我运行上面提到的最后一行之后发生的事情是 sklearn2pmml(pmml_pipeline, 'logit.pmml', with_repr=True) Standard output is empty Standard erro

我试图将管道对象保存为PMML,Python抛出一个运行时错误

我的Python版本是
3.6
sklearn2pmml
版本是
0.44.0
,JDK版本是
1.8.0\u 201

所有这些都符合软件包的先决条件

以下是我到目前为止所做的。(我不包括数据加载和清理部分)

在我运行上面提到的最后一行之后发生的事情是

sklearn2pmml(pmml_pipeline, 'logit.pmml', with_repr=True)
Standard output is empty
Standard error:
Apr 30, 2019 11:59:04 AM org.jpmml.sklearn.Main run
INFO: Parsing PKL..
Apr 30, 2019 11:59:04 AM org.jpmml.sklearn.Main run
INFO: Parsed PKL in 230 ms.
Apr 30, 2019 11:59:04 AM org.jpmml.sklearn.Main run
INFO: Converting..
Apr 30, 2019 11:59:04 AM org.jpmml.sklearn.Main run
SEVERE: Failed to convert
java.lang.IllegalArgumentException: Expected an estimator object as the last step, got a transformer object (Python class sklearn.pipeline.Pipeline)
        at sklearn2pmml.pipeline.PMMLPipeline.getEstimator(PMMLPipeline.java:541)
        at sklearn2pmml.pipeline.PMMLPipeline.encodePMML(PMMLPipeline.java:93)
        at org.jpmml.sklearn.Main.run(Main.java:145)
        at org.jpmml.sklearn.Main.main(Main.java:94)

Exception in thread "main" java.lang.IllegalArgumentException: Expected an estimator object as the last step, got a transformer object (Python class sklearn.pipeline.Pipeline)
        at sklearn2pmml.pipeline.PMMLPipeline.getEstimator(PMMLPipeline.java:541)
        at sklearn2pmml.pipeline.PMMLPipeline.encodePMML(PMMLPipeline.java:93)
        at org.jpmml.sklearn.Main.run(Main.java:145)
        at org.jpmml.sklearn.Main.main(Main.java:94)

Traceback (most recent call last):

  File "<ipython-input-129-f5c307b4aaba>", line 1, in <module>
    sklearn2pmml(pmml_pipeline, 'logit.pmml', with_repr=True)

  File "C:\ProgramData\Anaconda3\lib\site-packages\sklearn2pmml\__init__.py", line 252, in sklearn2pmml
    raise RuntimeError("The JPMML-SkLearn conversion application has failed. The Java executable should have printed more information about the failure into its standard output and/or standard error streams")

RuntimeError: The JPMML-SkLearn conversion application has failed. The Java executable should have printed more information about the failure into its standard output and/or standard error streams
sklearn2pmml(pmml_管道,'logit.pmml',且_repr=True)
标准输出为空
标准错误:
2019年4月30日上午11:59:04 org.jpmml.sklearn.Main run
信息:正在解析PKL。。
2019年4月30日上午11:59:04 org.jpmml.sklearn.Main run
信息:在230毫秒内解析了PKL。
2019年4月30日上午11:59:04 org.jpmml.sklearn.Main run
信息:正在转换。。
2019年4月30日上午11:59:04 org.jpmml.sklearn.Main run
严重:转换失败
java.lang.IllegalArgumentException:最后一步需要一个estimator对象,得到一个transformer对象(Python类sklearn.pipeline.pipeline)
位于sklearn2pmml.pipeline.PMMLPipeline.getEstimator(PMMLPipeline.java:541)
位于sklearn2pmml.pipeline.PMMLPipeline.encodePMML(PMMLPipeline.java:93)
位于org.jpmml.sklearn.Main.run(Main.java:145)
位于org.jpmml.sklearn.Main.Main(Main.java:94)
线程“main”java.lang.IllegalArgumentException中的异常:最后一步需要一个estimator对象,得到一个transformer对象(Python类sklearn.pipeline.pipeline)
位于sklearn2pmml.pipeline.PMMLPipeline.getEstimator(PMMLPipeline.java:541)
位于sklearn2pmml.pipeline.PMMLPipeline.encodePMML(PMMLPipeline.java:93)
位于org.jpmml.sklearn.Main.run(Main.java:145)
位于org.jpmml.sklearn.Main.Main(Main.java:94)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
sklearn2pmml(pmml_管道'logit.pmml',其中_repr=True)
文件“C:\ProgramData\Anaconda3\lib\site packages\sklearn2pmml\\uuuu init\uuuu.py”,第252行,位于sklearn2pmml中
raise RUNTIMERROR(“JPMML SKLERN转换应用程序失败。Java可执行文件应已将有关失败的更多信息打印到其标准输出和/或标准错误流中”)
运行时错误:JPMML SkLearn转换应用程序失败。Java可执行文件应该已经将有关故障的更多信息打印到其标准输出和/或标准错误流中

现在根据一些人的说法,这是一些JDK兼容性问题,使用JDK版本1.9及以上或1.6及以下会引发此类问题。但是既然sklearn2pmml可以接受我的JDK版本,为什么会出现这种错误?

正如底层Java异常所告诉的那样,
sklearn2pmml.pipeline.PMMLPipeline
类希望通过步骤列表进行参数化,其中最后一步包含一些估计器对象。在您的例子中,您正在使用步骤的单个元素列表参数化
PMMLPipeline
;最后一步保存一个
管道
对象,在这个意义上它不是估计器对象

要解决这个问题,只需去掉中间层
logit\u pipline
层(在管道中包装管道的想法是什么?)

例如,这将起作用:

logit_pipline = PMMLPipeline([..])
logit_pipeline.fit(X, y)
sklearn2pmml(logit_pipeline, "logit.pmml")

这个问题与JDK、Python或Scikit学习版完全无关。

对于新手来说,这个问题非常好!希望有人能过来解释一下。如果不知道你的“logit.pmml”文件,答案不大可能。我认为此文件中缺少一些配置/步骤。即使在进行了您建议的更改后,我仍会收到相同的错误。那么,您仍然有一个管道嵌套在另一个管道中?只需去掉这两个管道中的一个(
logit\u pipline
pmml\u pipeline
),并将“幸存者”的类型更改为
PMMLPipeline
。我去掉了嵌套管道,并尝试运行代码。我仍然收到相同的错误。它不可能是相同的错误,因为此错误是关于嵌套在另一个管道中的一个管道。这不是一个不同的错误,就是您仍然有两条管道。显示你的代码。是的,你是对的。我的错。我得到一个与CountVectorizer相关的错误。logit_pipeline=PMMLPipeline([('vect',CountVectorizer(ngram_range=(1,2)),('tfidf',tfidftranger(use_idf=True)),('clf',logisticsregression(C=11.3)))logit_pipeline.fit(X,y)sklearn2pmml(logit_pipeline,'logit.pmml'))严重:无法转换java.lang.IllegalArgumentException:属性“sklearn.feature\u extraction.text.CountVectorizer.tokenizer”缺少一个值(无/空)
logit_pipline = PMMLPipeline([..])
logit_pipeline.fit(X, y)
sklearn2pmml(logit_pipeline, "logit.pmml")