在Python 3.6中调用sklearn2pmml()函数会抛出RuntimeError异常。

5
我试图将一个Pipeline对象保存为PMML格式,但Python抛出了一个运行时错误。
我的Python版本是3.6,sklearn2pmml版本是0.44.0,JDK版本是1.8.0_201。所有这些都符合包的先决条件。
到目前为止,我已经完成了以下步骤。(不包括数据加载和清洗部分)
from sklearn2pmml.pipeline import PMMLPipeline
from sklearn2pmml import make_pmml_pipeline, sklearn2pmml

logit_pipline = Pipeline([('vect', CountVectorizer(ngram_range=(1,2))), ('tfidf', TfidfTransformer(use_idf=True)), ('clf', LogisticRegression(C=11.3))])
pmml_pipeline = PMMLPipeline([("logit", logit_pipline)])
pmml_pipeline.fit(X, Y)

sklearn2pmml(pmml_pipeline, 'logit.pmml', with_repr=True)

当我运行上面提到的最后一行代码后,会发生什么事情...
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

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


非常适合新手的好问题!希望有人能够来解答并且使它变得清晰明了。 - GhostCat
不了解您的“logit.pmml”文件,很难给出答案。 我认为这个文件中缺少一些配置/步骤。 - SirFartALot
1个回答

0

正如底层的Java异常所述,sklearn2pmml.pipeline.PMMLPipeline类希望使用一系列步骤进行参数化,其中最后一步包含某个估算器对象。在您的情况下,您正在使用单元素步骤列表对PMMLPipeline进行参数化;最后一步包含一个Pipeline对象,在这种意义上不是估算器对象。

要解决问题,只需摆脱中间的logit_pipline层(将管道包装在管道中的想法是什么?)。

例如,这样做可以解决问题:

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

这个问题与JDK、Python或Scikit-Learn版本完全无关。


即使按照您的建议进行更改,我仍然收到相同的错误。 - dilip sundar
所以,您仍然有一个流水线嵌套在另一个流水线中?只需摆脱这两个流水线中的一个(logit_piplinepmml_pipeline),并将“survivor”的类型更改为PMMLPipeline - user1808924
我摆脱了嵌套的管道并尝试运行代码。我仍然得到相同的错误。 - dilip sundar
这不可能是相同的错误,因为该错误涉及到一个嵌套在另一个管道内部的管道。要么是不同的错误,要么你仍然有两个管道。请展示你的代码。 - user1808924
是的,你说得对。我的错。我遇到了与CountVectorizer相关的错误。logit_pipeline = PMMLPipeline([('vect', CountVectorizer(ngram_range=(1,2))), ('tfidf', TfidfTransformer(use_idf=True)), ('clf', LogisticRegression(C=11.3))]) logit_pipeline.fit(X, y) sklearn2pmml(logit_pipeline, 'logit.pmml')严重: 转换失败 java.lang.IllegalArgumentException: 属性'sklearn.feature_extraction.text.CountVectorizer.tokenizer'具有缺失(None/null)值 - dilip sundar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接