web-dev-qa-db-fra.com

La régression logistique PMML ne produira pas de probabilités

Dans le cadre d'un projet de déploiement d'apprentissage automatique, j'ai construit une preuve de concept où j'ai créé deux modèles de régression logistique simples pour une tâche de classification binaire en utilisant la fonction glm de R et le scikit-learn De python. Par la suite, j'ai converti ces modèles simples formés en PMML en utilisant la fonction pmml dans R et la fonction from sklearn2pmml.pipeline import PMMLPipeline En Python.

Ensuite, j'ai ouvert un workflow très simple dans KNIME pour voir si je peux mettre ces deux PMML en action. Fondamentalement, le but de cette preuve de concept est de tester si le service informatique peut marquer de nouvelles données en utilisant les PMML que je leur remets simplement. Cet exercice doit produire des probabilités, tout comme le feraient les régressions logistiques d'origine.

Dans KNIME, je lis des données de test de seulement 4 lignes en utilisant le noeud CSV Reader, Je lis le PMML en utilisant le noeud PMML Reader, Et finalement j'obtiens ce modèle pour noter ces données de test en utilisant Noeud PMML Predictor. Le problème est que les prédictions ne sont pas des probabilités finales que je veux, mais une étape avant cela (somme des coefficients multipliée par des valeurs de variables indépendantes, appelées XBETA je suppose?). Veuillez consulter le flux de travail et les prévisions dans l'image ci-dessous:

KNIME output

Pour arriver aux probabilités finales, il faut exécuter ces nombres via la fonction sigmoïde. Donc, fondamentalement, pour le premier enregistrement, au lieu de 2.654, J'ai besoin de 1/(1+exp(-2.654)) = 0.93. Je suis sûr que le fichier PMML contient les informations requises pour permettre à KNIME ( ou à toute autre plate-forme similaire ) d'effectuer cette opération sigmoïde pour moi , mais je ne l'ai pas trouvé. C'est là que j'ai désespérément besoin d'aide.

J'ai examiné les documentations régression et régression généralePMML, et mes PMML semblent très bien, mais je n'arrive pas à comprendre pourquoi je ne peux pas les obtenir probabilités.

Toute aide est grandement appréciée!

Pièce jointe 1 - Voici mes données de test:

age credit  payfreq gmi
25  550 4   1500
27  650 4   3400
35  600 2   3200
40  680 2   4000

Pièce jointe 2 - Voici mon PMML généré par R:

<?xml version="1.0"?>
<PMML version="4.2" xmlns="http://www.dmg.org/PMML-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dmg.org/PMML-4_2 http://www.dmg.org/v4-2/pmml-4-2.xsd">
 <Header copyright="Copyright (c) 2018 fakici" description="Generalized Linear Regression Model">
  <Extension name="user" value="fakici" extender="Rattle/PMML"/>
  <Application name="Rattle/PMML" version="1.4"/>
  <Timestamp>2018-10-30 17:36:39</Timestamp>
 </Header>
 <DataDictionary numberOfFields="5">
  <DataField name="bad" optype="categorical" dataType="double"/>
  <DataField name="age" optype="continuous" dataType="double"/>
  <DataField name="credit" optype="continuous" dataType="double"/>
  <DataField name="payfreq" optype="continuous" dataType="double"/>
  <DataField name="gmi" optype="continuous" dataType="double"/>
 </DataDictionary>
 <GeneralRegressionModel modelName="General_Regression_Model" modelType="generalLinear" functionName="regression" algorithmName="glm" distribution="binomial" linkFunction="logit" targetReferenceCategory="1">
  <MiningSchema>
   <MiningField name="bad" usageType="predicted" invalidValueTreatment="returnInvalid"/>
   <MiningField name="age" usageType="active" invalidValueTreatment="returnInvalid"/>
   <MiningField name="credit" usageType="active" invalidValueTreatment="returnInvalid"/>
   <MiningField name="payfreq" usageType="active" invalidValueTreatment="returnInvalid"/>
   <MiningField name="gmi" usageType="active" invalidValueTreatment="returnInvalid"/>
  </MiningSchema>
  <Output>
   <OutputField name="Predicted_bad" feature="predictedValue"/>
  </Output>
  <ParameterList>
   <Parameter name="p0" label="(Intercept)"/>
   <Parameter name="p1" label="age"/>
   <Parameter name="p2" label="credit"/>
   <Parameter name="p3" label="payfreq"/>
   <Parameter name="p4" label="gmi"/>
  </ParameterList>
  <FactorList/>
  <CovariateList>
   <Predictor name="age"/>
   <Predictor name="credit"/>
   <Predictor name="payfreq"/>
   <Predictor name="gmi"/>
  </CovariateList>
  <PPMatrix>
   <PPCell value="1" predictorName="age" parameterName="p1"/>
   <PPCell value="1" predictorName="credit" parameterName="p2"/>
   <PPCell value="1" predictorName="payfreq" parameterName="p3"/>
   <PPCell value="1" predictorName="gmi" parameterName="p4"/>
  </PPMatrix>
  <ParamMatrix>
   <PCell parameterName="p0" df="1" beta="14.4782176066955"/>
   <PCell parameterName="p1" df="1" beta="-0.16633241754673"/>
   <PCell parameterName="p2" df="1" beta="-0.0125492006930571"/>
   <PCell parameterName="p3" df="1" beta="0.422786551151072"/>
   <PCell parameterName="p4" df="1" beta="-0.0005500245399861"/>
  </ParamMatrix>
 </GeneralRegressionModel>
</PMML>

Pièce jointe 3 - Voici mon PMML généré par Python:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PMML xmlns="http://www.dmg.org/PMML-4_2" xmlns:data="http://jpmml.org/jpmml-model/InlineTable" version="4.2">
    <Header>
        <Application name="JPMML-SkLearn" version="1.5.8"/>
        <Timestamp>2018-10-30T22:10:32Z</Timestamp>
    </Header>
    <MiningBuildTask>
        <Extension>PMMLPipeline(steps=[('mapper', DataFrameMapper(default=False, df_out=False,
        features=[(['age', 'credit', 'payfreq', 'gmi'], [ContinuousDomain(high_value=None, invalid_value_replacement=None,
         invalid_value_treatment='return_invalid', low_value=None,
         missing_value_replacement=None, missing_value_treatment='as_is',
         missing_values=None, outlier_treatment='as_is', with_data=True,
         with_statistics=True), Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)])],
        input_df=False, sparse=False)),
       ('classifier', LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
          verbose=0, warm_start=False))])</Extension>
    </MiningBuildTask>
    <DataDictionary>
        <DataField name="bad" optype="categorical" dataType="double">
            <Value value="0"/>
            <Value value="1"/>
        </DataField>
        <DataField name="age" optype="continuous" dataType="double">
            <Interval closure="closedClosed" leftMargin="20.0" rightMargin="50.0"/>
        </DataField>
        <DataField name="credit" optype="continuous" dataType="double">
            <Interval closure="closedClosed" leftMargin="501.0" rightMargin="699.0"/>
        </DataField>
        <DataField name="payfreq" optype="continuous" dataType="double">
            <Interval closure="closedClosed" leftMargin="2.0" rightMargin="4.0"/>
        </DataField>
        <DataField name="gmi" optype="continuous" dataType="double">
            <Interval closure="closedClosed" leftMargin="1012.0" rightMargin="4197.0"/>
        </DataField>
    </DataDictionary>
    <RegressionModel functionName="classification" normalizationMethod="softmax" algorithmName="glm" targetFieldName="bad">
        <MiningSchema>
            <MiningField name="bad" usageType="target"/>
            <MiningField name="age" missingValueReplacement="35.05" missingValueTreatment="asMean"/>
            <MiningField name="credit" missingValueReplacement="622.28" missingValueTreatment="asMean"/>
            <MiningField name="payfreq" missingValueReplacement="2.74" missingValueTreatment="asMean"/>
            <MiningField name="gmi" missingValueReplacement="3119.4" missingValueTreatment="asMean"/>
        </MiningSchema>
        <Output>
            <OutputField name="probability(0)" optype="categorical" dataType="double" feature="probability" value="0"/>
            <OutputField name="probability(1)" optype="categorical" dataType="double" feature="probability" value="1"/>
        </Output>
        <ModelStats>
            <UnivariateStats field="age">
                <Counts totalFreq="100.0" missingFreq="0.0" invalidFreq="0.0"/>
                <NumericInfo minimum="20.0" maximum="50.0" mean="35.05" standardDeviation="9.365228240678386" median="40.5" interQuartileRange="18.0"/>
            </UnivariateStats>
            <UnivariateStats field="credit">
                <Counts totalFreq="100.0" missingFreq="0.0" invalidFreq="0.0"/>
                <NumericInfo minimum="501.0" maximum="699.0" mean="622.28" standardDeviation="76.1444784603585" median="662.0" interQuartileRange="150.5"/>
            </UnivariateStats>
            <UnivariateStats field="payfreq">
                <Counts totalFreq="100.0" missingFreq="0.0" invalidFreq="0.0"/>
                <NumericInfo minimum="2.0" maximum="4.0" mean="2.74" standardDeviation="0.9656086163658655" median="2.0" interQuartileRange="2.0"/>
            </UnivariateStats>
            <UnivariateStats field="gmi">
                <Counts totalFreq="100.0" missingFreq="0.0" invalidFreq="0.0"/>
                <NumericInfo minimum="1012.0" maximum="4197.0" mean="3119.4" standardDeviation="1282.4386379082625" median="4028.5" interQuartileRange="2944.0"/>
            </UnivariateStats>
        </ModelStats>
        <RegressionTable targetCategory="1" intercept="0.9994024132088255">
            <NumericPredictor name="age" coefficient="-0.1252021965856186"/>
            <NumericPredictor name="credit" coefficient="-8.682780007730786E-4"/>
            <NumericPredictor name="payfreq" coefficient="1.2605378393614861"/>
            <NumericPredictor name="gmi" coefficient="1.4681704138387003E-4"/>
        </RegressionTable>
        <RegressionTable targetCategory="0" intercept="0.0"/>
    </RegressionModel>
</PMML>
43
FatihAkici

Une solution flottante consiste à utiliser le nœud de formule mathématique pour appliquer la fonction sigmoïde sur la sortie du prédicteur PMML. As-tu essayé ça?

1
Matt L.