glm.deploy

'C' and 'Java' Source Code Generator for Fitted Glm Objects


License
AML

Documentation

glm.deploy

C and JAVA source code generator for fitted glm objects

Description

The glm.deploy package provides two functions that generate source code implementing the predict function of fitted glm objects. In this version, code can be generated for either C or JAVA. The idea is to provide a tool for the easy and fast deployment of glm predictive models into production. The source code generated by this package implements two function/methods. One of such functions implements the equivalent to predict(type="response"), while the second implements predict(type="link"). Source code is written to disk as a .c or .java file in the current working directory, unless an absolute path is specified for the output filename. In the case of c, an .h file is also generated.

Link Function Compatibility

This package is compatible with the following link functions:

  • identity
  • probit
  • cloglog
  • log
  • sqrt
  • inverse
  • 1/mu^2
  • logit

Examples

This is a basic example with the iris dataset to create a glm object and pass it to the two functions glm2c() and glm2java():

Create a glm model in R

Example with the iris dataset with a Logical target and numeric variables, using the binomial family and the logit link function.

  ## Load and transform iris dataset, make Species a binary target.
  data(iris)
  iristest = iris
  iristest$Virginica = ifelse(iristest$Species == 'virginica', TRUE,FALSE)
  iristest$Species = NULL
  # Load Package
  library(glm.deploy)
  #For repeatable results:
  set.seed(123)
  #fit glm model
  model <- glm(Virginica ~ ., family = binomial(logit), data=iristest)

Example with the glm2c() function

# Load Package
library(glm.deploy)
#Call the glm2c() function:
glm2c(model)

The glm2c() function generates the files "glm_virginica.c" and "glm_virginica.h":

glm_virginica.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

double glm_virginica_link(double sepal_length, double sepal_width, double petal_length, double petal_width){
  double new_sepal_length = -2.46522019518341 * sepal_length;
  double new_sepal_width = -6.68088701405762 * sepal_width;
  double new_petal_length = 9.4293851538836 * petal_length;
  double new_petal_width = 18.2861368877881 * petal_width;
  
  return -42.6378038127854+new_sepal_length+new_sepal_width+new_petal_length+new_petal_width;
}

double glm_virginica_response(double sepal_length, double sepal_width, double petal_length, double petal_width){
  return 1/(1+exp(-glm_virginica_link(sepal_length, sepal_width, petal_length, petal_width)));
}

glm_virginica.h

double glm_virginica_link(double sepal_length, double sepal_width, double petal_length, double petal_width);
double glm_virginica_response(double sepal_length, double sepal_width, double petal_length, double petal_width);

Usage of the functions in another programs:

  1. We need to add an include line #include "virginica_glm.h" to all source files that use library definitions.
  2. Link the .c file with the library object file.
gcc -c glm_virginica.c
  1. The following is an example file "test.c" to call the functions and print the result:

test.c

#include <stdio.h>
#include "glm_virgnica.h" //This must be added to call the scoring functions.

int main(int argc, char *argv[]){
  printf("%f\n",glm_virginica_link(5.7,2.5,5.0,2.0));
  printf("%f\n",glm_virginica_response(5.7,2.5,5.0,2.0));
  return 0;
}
  1. Compile the "test.c" file and link it to the glm_virginica shared library, we also need to add the "-lm" option to link it to the math.h library:
gcc test.c -o test glm_virginica.o -lm
  1. Finally run the test.o program in linux:
./test

Example with the glm2java() function

# Load Package
library(glm.deploy)
#Call the glm2java() function:
glm2java(model)

The glm2java() function generates the file "glm_virginica_class.java":

glm_virginica_class.java

package test;
public class glm_virginica_class{

  public static double glm_virginica_link(double sepal_length, double sepal_width, double petal_length, double petal_width){
    double new_sepal_length = -2.46522019518341 * sepal_length;
    double new_sepal_width = -6.68088701405762 * sepal_width;
    double new_petal_length = 9.4293851538836 * petal_length;
    double new_petal_width = 18.2861368877881 * petal_width;
  
    return -42.6378038127854+new_sepal_length+new_sepal_width+new_petal_length+new_petal_width;
  }
  public static double glm_virginica_response(double sepal_length, double sepal_width, double petal_length, double petal_width){
    return 1/(1+Math.exp(-glm_virginica_link(sepal_length, sepal_width, petal_length, petal_width)));
  }

}

To use these methods in another class just add the line "import glm_virginica_class.*;".

Notes

All numeric variables used as input to the glm object are treated as doubles, whereas factor variables are treated as strings.

Author(s)

  • Oscar J. Castro-Lopez
  • Ines F. Vega-Lopez