All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.radicalbit.flink.pmml.scala.api.pipeline.Pipeline.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2017  Radicalbit
 *
 * This file is part of flink-JPMML
 *
 * flink-JPMML is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * flink-JPMML is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with flink-JPMML.  If not, see .
 */

package io.radicalbit.flink.pmml.scala.api.pipeline

import io.radicalbit.flink.pmml.scala.api._
import io.radicalbit.flink.pmml.scala.api.exceptions.InputPreparationException
import io.radicalbit.flink.pmml.scala.models.prediction.Prediction
import org.apache.flink.ml.math.Vector
import org.dmg.pmml.FieldName
import org.jpmml.evaluator.{EvaluatorUtil, FieldValue, ModelField}

import scala.collection.JavaConversions._
import scala.collection.mutable
import scala.util.{Failure, Success, Try}

/** Self type trait extending [[PmmlModel]] instance methods; they offer
  * additional features for the preparation and extraction pipeline steps.
  *
  */
private[api] trait Pipeline { self: PmmlModel =>

  def predict[V <: Vector](inputVector: V, replaceNan: Option[Double] = None): Prediction

  /** Emits prepared input if JPMML preparation went fine.
    *
    * @throws InputPreparationException if the JPMML preparation fails.
    *
    * @param outcome `Try` evaluation of [[EvaluatorUtil.prepare]] method output value
    * @param field The field name related to the value
    * @return Prepared Input
    */
  private[api] def prepareAndEmit(outcome: Try[FieldValue], field: FieldName): (FieldName, FieldValue) =
    outcome match {
      case Success(value) => (field, value)
      case Failure(_) =>
        throw new InputPreparationException(s"The ${field.getValue} field JPMML finalization failed.")
    }

  /** Extracts all the target fields specified by the PMML document.
    *
    * @param evaluationResult evaluation step outcome
    * @return extracted output
    */
  private[api] def extractTargetFields(evaluationResult: java.util.Map[FieldName, _]): Seq[(String, Any)] =
    extractFields(evaluator.model.getTargetFields, evaluationResult, evaluator)

  /** Extracts all the output fields specified by the PMML document.
    *
    * @param evaluationResult evaluation step outcome
    * @return extracted output
    */
  private[api] def extractOutputFields(evaluationResult: java.util.Map[FieldName, _]): Seq[(String, Any)] =
    extractFields(evaluator.model.getOutputFields, evaluationResult, evaluator)

  /** Calls [[EvaluatorUtil.decode]] for each field demanded for extraction.
    *
    * @param fields demanded for extraction
    * @param evaluationResult evaluation outcome container
    * @param evaluator The PMML instance as a [[org.jpmml.evaluator.ModelEvaluator]]
    * @return
    */
  private[api] def extractFields(fields: java.util.List[_ <: ModelField],
                                 evaluationResult: java.util.Map[FieldName, _],
                                 evaluator: Evaluator): mutable.Buffer[(String, AnyRef)] =
    for {
      field <- fields
      fieldName <- Option(field.getName)
    } yield { fieldName.getValue -> EvaluatorUtil.decode(evaluationResult.get(fieldName)) }

  /** Casts a String to Double if the outcome is a String, returns the Double otherwise.
    *
    * @param target The extracted target
    * @throws scala.ClassCastException if the outcome could not be casted to Double
    * @return The outcome as a Double
    */
  @throws(classOf[ClassCastException])
  protected def extractTargetValue(target: Any): Option[Double] = target match {
    case s: String => Some(s.toDouble)
    case d: Double => Some(d)
    case _ => None
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy