Как объединить 2 файла pmml в 1 файл с 2 выводами?

#modeling #pmml

Вопрос:

я разработал две модели (классификацию и регрессию) и экспортировал их в формат обмена PMML через https://github.com/jpmml/jpmml-xgboost. Обе модели работают нормально, когда я вызываю их на python. Тем не менее, я хотел бы объединить оба в один файл, который возвращает два значения: вероятность класса модели классификации И прогнозируемое значение из регрессионной модели.

Я пытался уже несколько часов, но не смог понять спецификацию PMML настолько хорошо, насколько это было необходимо.

Есть ли у кого-нибудь опыт в этом и может ли он подсказать мне, как объединить файлы и передавать значения через файл ? Обе модели требуют совершенно одинаковых входных данных.

Спасибо!

Смотрите два мини-примера ниже: регрессионная модель:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PMML xmlns="http://www.dmg.org/PMML-4_4" xmlns:data="http://jpmml.org/jpmml-model/InlineTable" version="4.4">
    <Header>
        <Application name="JPMML-XGBoost" version="1.5-SNAPSHOT"/>
        <Timestamp>2021-07-27T11:55:26Z</Timestamp>
    </Header>
    <DataDictionary>
        <DataField name="mpg" optype="continuous" dataType="float">
            <Value value="NaN" property="missing"/>
        </DataField>
        <DataField name="IDVAR_REINIG" optype="continuous" dataType="float">
            <Value value="NaN" property="missing"/>
        </DataField>
    </DataDictionary>
    <MiningModel functionName="regression" algorithmName="XGBoost (GBTree)" x-mathContext="float">
        <MiningSchema>
            <MiningField name="mpg" usageType="target"/>
            <MiningField name="IDVAR_REINIG"/>
        </MiningSchema>
        <Targets>
            <Target field="mpg" rescaleConstant="0.5"/>
        </Targets>
        <Segmentation multipleModelMethod="sum">
            <Segment id="1">
                <True/>
                <TreeModel functionName="regression" noTrueChildStrategy="returnLastPrediction" x-mathContext="float">
                    <MiningSchema>
                        <MiningField name="IDVAR_REINIG"/>
                    </MiningSchema>
                    <Output>
                        <OutputField name="mpg" optype="continuous" dataType="float" isFinalResult="false" rescaleConstant="0.5"/>
                    </Output>
                    <Node score="1.7433707">
                        <True/>
                        <Node score="6.1398296">
                            <SimplePredicate field="IDVAR_REINIG" operator="greaterOrEqual" value="6033.51"/>
                        </Node>
                    </Node>
                </TreeModel>
            </Segment>
        </Segmentation>
    </MiningModel>
</PMML>

 

модель классификации:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PMML xmlns="http://www.dmg.org/PMML-4_4" xmlns:data="http://jpmml.org/jpmml-model/InlineTable" version="4.4">
    <Header>
        <Application name="JPMML-XGBoost" version="1.5-SNAPSHOT"/>
        <Timestamp>2021-07-27T11:54:45Z</Timestamp>
    </Header>
    <DataDictionary>
        <DataField name="mpg" optype="categorical" dataType="integer">
            <Value value="0"/>
            <Value value="1"/>
        </DataField>
        <DataField name="IDVAR_REINIG" optype="continuous" dataType="float">
            <Value value="NaN" property="missing"/>
        </DataField>
    </DataDictionary>
    <MiningModel functionName="classification" algorithmName="XGBoost (GBTree)" x-mathContext="float">
        <MiningSchema>
            <MiningField name="mpg" usageType="target"/>
            <MiningField name="IDVAR_REINIG"/>
        </MiningSchema>
        <Segmentation multipleModelMethod="modelChain" missingPredictionTreatment="returnMissing">
            <Segment id="1">
                <True/>
                <MiningModel functionName="regression" x-mathContext="float">
                    <MiningSchema>
                        <MiningField name="IDVAR_REINIG"/>
                    </MiningSchema>
                    <Output>
                        <OutputField name="xgbValue" optype="continuous" dataType="float" isFinalResult="false"/>
                    </Output>
                    <Segmentation multipleModelMethod="sum">
                        <Segment id="1">
                            <True/>
                            <TreeModel functionName="regression" noTrueChildStrategy="returnLastPrediction" x-mathContext="float">
                                <MiningSchema>
                                    <MiningField name="IDVAR_REINIG"/>
                                </MiningSchema>
                                <Node score="0.0070259375">
                                    <True/>
                                    <Node score="-0.030500757">
                                        <SimplePredicate field="IDVAR_REINIG" operator="greaterOrEqual" value="2240.835"/>
                                    </Node>
                                </Node>
                            </TreeModel>
                        </Segment>
                    </Segmentation>
                </MiningModel>
            </Segment>
            <Segment id="2">
                <True/>
                <RegressionModel functionName="classification" normalizationMethod="logit" x-mathContext="float">
                    <MiningSchema>
                        <MiningField name="mpg" usageType="target"/>
                        <MiningField name="xgbValue"/>
                    </MiningSchema>
                    <Output>
                        <OutputField name="probability(0)" optype="continuous" dataType="float" feature="probability" value="0"/>
                        <OutputField name="probability(1)" optype="continuous" dataType="float" feature="probability" value="1"/>
                    </Output>
                    <RegressionTable intercept="0.0" targetCategory="1">
                        <NumericPredictor name="xgbValue" coefficient="1.0"/>
                    </RegressionTable>
                    <RegressionTable intercept="0.0" targetCategory="0"/>
                </RegressionModel>
            </Segment>
        </Segmentation>
    </MiningModel>
</PMML>

 

Комментарии:

1. Я пытался заставить его работать, но не смог после нескольких часов и различных сообщений об ошибках. Мое понимание PMML слишком мало. В качестве другого варианта используйте 2 файла и вызовите его 2 раза, для меня это более эффективно, я не буду пытаться решить эту проблему.

Ответ №1:

Создайте родительский MiningModel элемент, содержащий два существующих дочерних элемента модели. Сначала вставьте модель классификации, а затем регрессионную модель; выполните их как цепочку моделей.

По умолчанию в этой цепочке моделей будут отображаться только поля результатов последней дочерней модели. Однако вы можете экспортировать одно или несколько полей результатов первой модели в «локальные переменные», а затем при необходимости отражать их значения.

Образец скелета разметки PMML:

 <MiningModel>
  <Segmentation multipleModelMethod="modelChain">
    <Segment id="classification">
      <True/>
      <MiningModel>
        <Output>
         <!-- Export the probability value to evaluation context -->
         <OutputField name="probability(event)" feature="probability" value="event"/>
        </Output>
      </MiningModel>
    </Segment>
    <Segment id="regression">
      <True/>
      <MiningModel>
        <MiningSchema>
          <!-- Import the probability value from the evaluation context -->
          <MiningField name="probability(event")/>
        </MiningSchema>
        <Output>
          <!-- Re-export the probability value under a different name -->
          <OutputField name="copy(probability(event))" feature="transformedValue">
            <FieldRef field="probability(event)"/>
          </OutputField>
        </Output>
      </MiningModel>
    </Segment>
  </Segmentation>
</MiningModel>
 

Ответ №2:

В качестве альтернативы вы можете использовать механизм «ссылки на сегменты» для доступа к выводам дочерней модели из родительского вывода.

Смотрите описание OutputField@segmentId атрибута здесь.

Образец скелета разметки PMML:

 <MiningModel>
  <Segmentation multipleModelMethod="modelChain">
    <Segment id="classification/>
    <Segment id="regresion">
  </Segmentation>
  <Output>
    <!-- Reflect the probability of the "event" class of the classification model -->
    <OutputField name="probability(event)" segmentId="classification" feature="probability"/>
    <!-- Reflect the predicted value of the regression model -->
    <OutputField name="y" segmentId="regression" feature="predictedValue"/>
  </Output>
</MiningModel>