weka.core.pmml.Expression Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-stable Show documentation
Show all versions of weka-stable Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This is the stable version. Apart from bugfixes, this version
does not receive any other updates.
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Expression.java
* Copyright (C) 2008-2012 University of Waikato, Hamilton, New Zealand
*
*/
package weka.core.pmml;
import java.io.Serializable;
import java.util.ArrayList;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import weka.core.Attribute;
public abstract class Expression implements Serializable {
/**
* For serialization
*/
private static final long serialVersionUID = 4448840549804800321L;
/** The optype of this Expression */
protected FieldMetaInfo.Optype m_opType;
/** The field defs */
protected ArrayList m_fieldDefs = null;
// NOTE - might need to pass in mining schema in order
// to determine values for nominal optypes
public Expression(FieldMetaInfo.Optype opType, ArrayList fieldDefs) {
m_opType = opType;
m_fieldDefs = fieldDefs;
}
/**
* Set the field definitions for this Expression to use
*
* @param fieldDefs the field definitions to use
* @throws Exception if there is a problem setting the field definitions
*/
public void setFieldDefs(ArrayList fieldDefs) throws Exception {
m_fieldDefs = fieldDefs;
}
/**
* Get the result of evaluating the expression. In the case
* of a continuous optype, a real number is returned; in
* the case of a categorical/ordinal optype, the index of the nominal
* value is returned as a double.
*
* @param incoming the incoming parameter values
* @return the result of evaluating the expression
* @throws Exception if there is a problem computing the result
*/
public abstract double getResult(double[] incoming) throws Exception;
/**
* Get the result of evaluating the expression for continuous
* optype. Is the same as calling getResult() when the optype
* is continuous.
*
* @param incoming the incoming parameter values
* mining schema
* @return the result of evaluating the expression.
* @throws Exception if the optype is not continuous.
*/
public double getResultContinuous(double[] incoming) throws Exception {
if (!(m_opType == FieldMetaInfo.Optype.CONTINUOUS)) {
throw new Exception("[Expression] Can't return continuous result "
+ "as optype is not continuous");
}
return getResult(incoming);
}
/**
* Gets the result of evaluating the expression when the
* optype is categorical or ordinal as the actual String
* value.
*
* @param incoming the incoming parameter values
* @return the result of evaluating the expression
* @throws Exception if the optype is continuous
*/
public abstract String getResultCategorical(double[] incoming)
throws Exception;
/**
* Return the structure of the result of applying this Expression
* as an Attribute.
*
* @return the structure of the result of applying this Expression as an
* Attribute.
*/
protected abstract Attribute getOutputDef();
/**
* Static factory method that returns a subclass of Expression that
* encapsulates the type of expression contained in the Element
* supplied. Assumes that there is just one expression contained
* in the supplied Element.
*
* @param container the Node containing the expression
* @param opType the optype of the value returned by this Expression.
* @param fieldDefs an ArrayList of Attributes for the fields that this
* Expression may need to access
* Since Expressions are children of either DerivedFields or
* DefineFuntions, they will have the same optype as their parent.
* @param transDict the TransformationDictionary (may be null if there
* is no dictionary)
* @return an Expression object or null if there is no known expression in
* the container
* @throws Exception for unsupported Expression types
*/
public static Expression getExpression(Node container,
FieldMetaInfo.Optype opType,
ArrayList fieldDefs,
TransformationDictionary transDict) throws Exception {
// we need to examine children of this Node to find an expression,
// not the entire subtree (as would be returned by Element.getElementsByTagName()
Expression result = null;
String tagName = "";
NodeList children = container.getChildNodes();
if (children.getLength() == 0) {
throw new Exception("[Expression] container has no children!");
}
// at this level in the tree there should be only one expression type
// specified - look for it here.
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
tagName = ((Element)child).getTagName();
result = getExpression(tagName, child, opType, fieldDefs, transDict);
if (result != null) {
break;
}
}
}
return result;
}
/**
* Static factory method that returns a subclass of Expression that
* encapsulates the type of expression supplied as an argument.
*
* @param name the name of the Expression to get
* @param expression the Node containing the expression
* @param opType the optype of the value returned by this Expression.
* @param fieldDefs an ArrayList of Attributes for the fields that this
* Expression may need to access
* Since Expressions are children of either DerivedFields or
* DefineFuntions, they will have the same optype as their parent.
* @param transDict the TransformationDictionary (may be null if there
* is no dictionary)
* @return an Expression object or null if there is no known expression in
* the container
* @throws Exception for unsupported Expression types
*/
public static Expression getExpression(String name,
Node expression,
FieldMetaInfo.Optype opType,
ArrayList fieldDefs,
TransformationDictionary transDict) throws Exception {
Expression result = null;
if (name.equals("Constant")) {
// construct a Constant expression
result = new Constant((Element)expression, opType, fieldDefs);
} else if (name.equals("FieldRef")) {
// construct a FieldRef expression
result = new FieldRef((Element)expression, opType, fieldDefs);
} else if (name.equals("Apply")) {
// construct an Apply expression
result = new Apply((Element)expression, opType, fieldDefs, transDict);
} else if (name.equals("NormDiscrete")) {
result = new NormDiscrete((Element)expression, opType, fieldDefs);
} else if (name.equals("NormContinuous")) {
result = new NormContinuous((Element)expression, opType, fieldDefs);
} else if (name.equals("Discretize")) {
result = new Discretize((Element)expression, opType, fieldDefs);
} else if (name.equals("MapValues") ||
name.equals("Aggregate")) {
throw new Exception("[Expression] Unhandled Expression type " + name);
}
return result;
}
/**
* Return the named attribute from the list of reference fields.
*
* @param attName the name of the attribute to retrieve
* @return the named attribute (or null if it can't be found).
*/
public Attribute getFieldDef(String attName) {
Attribute returnV = null;
for (int i = 0; i < m_fieldDefs.size(); i++) {
if (m_fieldDefs.get(i).name().equals(attName)) {
returnV = m_fieldDefs.get(i);
break;
}
}
return returnV;
}
public int getFieldDefIndex(String attName) {
int returnV = -1;
for (int i = 0; i < m_fieldDefs.size(); i++) {
if (m_fieldDefs.get(i).name().equals(attName)) {
returnV = i;
break;
}
}
return returnV;
}
/**
* Get the optype of the result of applying this Expression.
*
* @return the optype of the result of applying this Expression
*/
public FieldMetaInfo.Optype getOptype() {
return m_opType;
}
public String toString() {
return toString("");
}
public String toString(String pad) {
return pad + this.getClass().getName();
}
}