Posso aplicar uma PMML modelo que inclui DefineFunction usando Augusto (Python)?
Pergunta
Eu estou usando Augusto como um modelo PMML consumidor.Modifiquei o adicionar dois números de exemplo para incluir um DefineFunction elemento, como esta:
<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>
Eu salvar este modelo em um arquivo e tente executá-lo assim:
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()
No entanto, eu recebo um erro:
AttributeError: 'DefineFunction' object has no attribute '_setupCalculate'
Eu estou usando a mais recente tronco (revisão 794) e sou capaz de executar não modificado exemplo (sem DefineFunction) sem um problema.É DefineFunction suportado por Augusto?
Solução
jcrudy, você está certo:isso foi um erro.(Uma API alterado e DefineFunction não foi trazido up-to-date.) Já está corrigido no público repositório SVN:com Augusto >= r795, você pode executar o seu exemplo, como estava previsto inicialmente.
Pelo caminho, o seu PMML é proveniente de um arquivo externo, mas você carregar-lo em uma seqüência de caracteres e, em seguida, em um PMML DOM.Você pode pular o passo intermediário por que passam apenas loadXML
o nome de arquivo:
model = modelLoader.loadXml(add_two_numbers_file)
(Isso pode ser relevante para grandes PMML arquivos;observe também que eles podem ser Compactado.)
Outras dicas
Eu era capaz de resolver isso, fazer duas alterações.Depois de ter um olhar para o augustus de origem e a determinação de que, de fato, _setupCalculate
não está definido em qualquer lugar, eu monkey patch-lo.Meu script agora este aspecto:
# 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()
Eu fiz a ingênua suposição de que _setupCalculate
não precisa fazer nada de importante.Eu estava agora recebendo uma diferente e mais difíceis de erro:
ValueError: assignment destination is read-only
na linha de
mask[mask2] = defs.MISSING
no FieldType.py.Depois de algumas viagens através do depurador, eu vi que essa linha foi executada apenas durante a conversão de tipo e percebi que eu estava usando tanto float e double tipos no meu PMML.Removendo desnecessários atributos de tipo de dados, eu era capaz de conseguir o seguinte para trabalhar:
<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>
O tronco versão de augusto, eu usei é equivalente a versão 0.6-beta3.Parece que os problemas que eu tive são apenas erros, e os truques utilizados nesta resposta são susceptíveis de se tornarem desnecessários em um futuro próximo.