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

com.alpine.model.pack.preprocess.PolynomialModel.scala Maven / Gradle / Ivy

/*
 * Copyright (c) 2015 Alpine Data Labs
 * All rights reserved.
 */
package com.alpine.model.pack.preprocess

import com.alpine.features.{DoubleType, FeatureDesc}
import com.alpine.model.RowModel
import com.alpine.model.pack.util.TransformerUtil
import com.alpine.transformer.Transformer

/**
 * Model that creates output features that are polynomial combinations of the input features.
 *
 *
 * We use java.lang.Double for the type of the numeric values, because the scala Double type information
 * is lost by scala/Gson and the deserialization fails badly for edge cases (e.g. Double.NaN).
 *
 * If the exponents are a matrix
 * [[1,2,0], [0.5,3,2]]
 * Then the transformation of a row (x1, x2, x3) will be
 * (y1, y2) = (x1 * x2 pow 2, sqrt(x1) * x2 pow 3 * x3 pow 2).
 */
case class PolynomialModel(exponents: Seq[Seq[java.lang.Double]], inputFeatures: Seq[FeatureDesc[_ <: Number]], override val identifier: String = "") extends RowModel {
  override def transformer: Transformer = PolynomialTransformer(this)

  def outputFeatures: Seq[FeatureDesc[_]] = {
    exponents.indices.map(i => FeatureDesc("y_" + i, DoubleType()))
  }

}

case class PolynomialTransformer(model: PolynomialModel) extends Transformer {

  private val rowAsDoubleArray = Array.ofDim[Double](model.transformationSchema.inputFeatures.length)

  private val exponents: Array[Array[Double]] = model.exponents.map(v => TransformerUtil.javaDoubleSeqToArray(v)).toArray

  override def apply(row: Row): Row = {
    TransformerUtil.fillRowToDoubleArray(row, rowAsDoubleArray)
    val result = Array.ofDim[Double](exponents.length)
    var i = 0
    while (i < exponents.length) {
      var x = 1.0
      var j = 0
      while (j < rowAsDoubleArray.length) {
        // math.pow(0,0) = 1 in Scala, so we do not have to check the 0 case.
        x *= math.pow(rowAsDoubleArray(j), exponents(i)(j))
        j += 1
      }
      result(i) = x
      i += 1
    }
    result
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy