2

我使用 Augustus 作为 PMML 模型消费者。我已经修改了添加两个数字的示例以包含一个 DefineFunction 元素,如下所示:

<PMML version="4.1" xmlns="http://www.dmg.org/PMML-4_1">
    <Header/>
    <DataDictionary>
        <DataField name="x" dataType="double" optype="continuous"/>
        <DataField name="y" dataType="double" optype="continuous"/>
    </DataDictionary>
    <TransformationDictionary>
        <DefineFunction dataType="float" optype="continuous" name="add">
            <ParameterField optype="continuous" name="first"></ParameterField>
            <ParameterField optype="continuous" name="second"></ParameterField>
                <Apply function="+" invalidValueTreatment="returnInvalid">
                    <FieldRef field="first"></FieldRef>
                    <FieldRef field="second"></FieldRef>
                </Apply>
        </DefineFunction>
        <DerivedField name="z" dataType="double" optype="continuous">
            <Apply function="add">
                <FieldRef field="x"/>
                <FieldRef field="y"/>
            </Apply>
        </DerivedField>
    </TransformationDictionary>
</PMML>

我将此模型保存在一个文件中并尝试像这样运行它:

from resources import add_two_numbers_file # this is just the path to my model file
from augustus.strict import modelLoader

# Load model
with open(add_two_numbers_file, 'r') as model_file:
    model_str = model_file.read()
    model = modelLoader.loadXml(model_str)

# Run model
print model.calc({'x':[1,2,3],'y':[4,5,6]}).look()

但是,我收到一个错误:

AttributeError: 'DefineFunction' object has no attribute '_setupCalculate'

我正在使用最新的主干(修订版 794)并且能够毫无问题地运行未修改的示例(没有 DefineFunction)。Augustus 是否支持 DefineFunction?

4

2 回答 2

2

jcrudy,你是对的:这是一个错误。(API 已更改,DefineFunction 未更新。)它现在已在公共 SVN 存储库中修复:使用 Augustus >= r795,您可以按照最初的预期运行示例。

顺便说一句,您的 PMML 来自外部文件,但您将其加载到字符串中,然后加载到 PMML DOM 中。您只需传递loadXML文件名即可跳过中间步骤:

model = modelLoader.loadXml(add_two_numbers_file)

(这可能与非常大的 PMML 文件相关;还要注意它们可以被 GZipped。)

于 2014-01-14T18:07:03.547 回答
2

我能够通过进行两项更改来解决此问题。在查看了 augustus 源并确定确实_setupCalculate没有在任何地方定义之后,我对其进行了猴子修补。我的脚本现在看起来像这样:

# Monkey-patch augustus
import augustus.pmml.DefineFunction
def _setupCalculate(self, dataTable, functionTable, performanceTable):
    return (dataTable, functionTable, performanceTable)
augustus.pmml.DefineFunction.DefineFunction._setupCalculate = _setupCalculate

# Now the actual script
from augustus.strict import modelLoader

# Load model
add_two_numbers_file = 'addTwoNumbers.pmml'
with open(add_two_numbers_file, 'r') as model_file:
    model_str = model_file.read()
    model = modelLoader.loadXml(model_str)

# Run model
print model.calc({'x':[1,2,3],'y':[4,5,6]}).look()

我做了一个天真的假设,_setupCalculate不需要做任何重要的事情。我现在遇到了一个不同的、更难以理解的错误:

ValueError: assignment destination is read-only

在线

mask[mask2] = defs.MISSING

在 FieldType.py 中。在调试器运行了几次之后,我看到这一行只在类型转换期间执行,并注意到我在我的 PMML 中同时使用了 float 和 double 类型。通过删除不必要的 dataType 属性,我能够使以下工作:

<PMML version="4.1" xmlns="http://www.dmg.org/PMML-4_1">
    <Header/>
    <DataDictionary>
        <DataField name="x" dataType="double" optype="continuous"/>
        <DataField name="y" dataType="double" optype="continuous"/>
    </DataDictionary>
    <TransformationDictionary>
        <DefineFunction optype="continuous" name="add">
            <ParameterField optype="continuous" name="first"></ParameterField>
            <ParameterField optype="continuous" name="second"></ParameterField>
            <Apply function="+" invalidValueTreatment="returnInvalid">
                <FieldRef field="first"></FieldRef>
                <FieldRef field="second"></FieldRef>
            </Apply>
        </DefineFunction>
        <DerivedField name="z" dataType="double" optype="continuous">
            <Apply function="add">
                <FieldRef field="x"/>
                <FieldRef field="y"/>
            </Apply>
        </DerivedField>
    </TransformationDictionary>
</PMML>

我使用的augustus的trunk版本相当于0.6-beta3版本。似乎我遇到的问题只是错误,并且在不久的将来,此答案中使用的技巧可能会变得不必要。

于 2014-01-11T18:59:18.393 回答