Могу ли я применить модель PMML, которая включает DefineFunction, используя Augustus (Python)?
Я использую 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) без проблем. DefineFunction поддерживается Августом?
2 ответа
jcrudy, вы правы: это была ошибка. (API был изменен, и DefineFunction не была обновлена.) Теперь он исправлен в общедоступном репозитории SVN: с Augustus >= r795 вы можете запустить свой пример, как первоначально предполагалось.
Кстати, ваш PMML приходит из внешнего файла, но вы загружаете его в строку, а затем в PMML DOM. Вы можете пропустить промежуточный шаг, просто пройдя loadXML
имя файла:
model = modelLoader.loadXml(add_two_numbers_file)
(Это может быть актуально для очень больших файлов PMML; также обратите внимание, что они могут быть GZipped.)
Я смог решить эту проблему, сделав два изменения. Посмотрев на августовский источник и определив, что _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 я использовал типы с плавающей и двойной типами. Удалив ненужные атрибуты 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, которую я использовал, эквивалентна версии 0.6-бета3. Кажется, что проблемы, которые у меня были, это просто ошибки, и уловки, использованные в этом ответе, скорее всего, станут ненужными в ближайшем будущем.