weka.core.pmml.NormDiscrete 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 .
*/
/*
* NormDiscrete.java
* Copyright (C) 2008-2012 University of Waikato, Hamilton, New Zealand
*
*/
package weka.core.pmml;
import java.util.ArrayList;
import org.w3c.dom.Element;
import weka.core.Attribute;
import weka.core.Utils;
/**
* Class encapsulating a NormDiscrete Expression. Creates an
* indicator for a particular discrete value.
*
* @author Mark Hall (mhall{[at]}pentaho{[dot]}com)
* @version $Revision 1.0 $
*/
public class NormDiscrete extends Expression {
/**
* For serialization
*/
private static final long serialVersionUID = -8854409417983908220L;
/** The name of the field to lookup our value in */
protected String m_fieldName;
/** The actual attribute itself */
protected Attribute m_field;
/** The index of the attribute */
protected int m_fieldIndex = -1;
/** The actual value (as a String) that will correspond to an output of 1 */
protected String m_fieldValue;
/** True if a replacement for missing values has been specified */
protected boolean m_mapMissingDefined = false;
/** The value of the missing value replacement (if defined) */
protected double m_mapMissingTo;
/**
* If we are referring to a nominal (rather than String) attribute
* then this holds the index of the value in question. Will be faster
* than searching for the value each time.
*/
protected int m_fieldValueIndex = -1;
/**
* Constructor. Reads the field name and field value for this NormDiscrete
* Expression.
*
* @param normDisc the Element encapsulating this NormDiscrete
* @param opType the optype for this expression (taken from either the
* enclosing DefineFunction or DerivedField)
* @param fieldDefs an ArrayList of Attributes for the fields that this
* Expression might need to access
* enclosing DefineFunction or DerivedField)
* @throws Exception if there is a problem parsing this Apply Expression
*/
public NormDiscrete(Element normDisc, FieldMetaInfo.Optype opType, ArrayList fieldDefs)
throws Exception {
super(opType, fieldDefs);
if (opType != FieldMetaInfo.Optype.CONTINUOUS) {
throw new Exception("[NormDiscrete] can only have a continuous optype");
}
m_fieldName = normDisc.getAttribute("field");
m_fieldValue = normDisc.getAttribute("value");
String mapMissing = normDisc.getAttribute("mapMissingTo");
if (mapMissing != null && mapMissing.length() > 0) {
m_mapMissingTo = Double.parseDouble(mapMissing);
m_mapMissingDefined = true;
}
if (fieldDefs != null) {
setUpField();
}
}
/**
* 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 {
super.setFieldDefs(fieldDefs);
setUpField();
}
/**
* Find the named field, set up the index(es) etc.
*
* @throws Exception if a problem occurs.
*/
private void setUpField() throws Exception {
m_fieldIndex = -1;
m_fieldValueIndex = -1;
m_field = null;
if (m_fieldDefs != null) {
m_fieldIndex = getFieldDefIndex(m_fieldName);
if (m_fieldIndex < 0) {
throw new Exception("[NormDiscrete] Can't find field " + m_fieldName
+ " in the supplied field definitions.");
}
m_field = m_fieldDefs.get(m_fieldIndex);
if (!(m_field.isString() || m_field.isNominal())) {
throw new Exception("[NormDiscrete] reference field " + m_fieldName
+" must be categorical");
}
if (m_field.isNominal()) {
// set up the value index
m_fieldValueIndex = m_field.indexOfValue(m_fieldValue);
if (m_fieldValueIndex < 0) {
throw new Exception("[NormDiscrete] Unable to find value " + m_fieldValue
+ " in nominal attribute " + m_field.name());
}
} else if (m_field.isString()) {
// add our value to this attribute (if it is already there
// then this will have no effect).
m_fieldValueIndex = m_field.addStringValue(m_fieldValue);
}
}
}
/**
* 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 Attribute getOutputDef() {
return new Attribute(m_fieldName + "=" + m_fieldValue);
}
/**
* 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 double getResult(double[] incoming) throws Exception {
double result = 0.0;
if (Utils.isMissingValue(incoming[m_fieldIndex])) {
if (m_mapMissingDefined) {
result = m_mapMissingTo; // return the replacement
} else {
result = incoming[m_fieldIndex]; // just return the missing value
}
} else {
if (m_fieldValueIndex == (int)incoming[m_fieldIndex]) {
result = 1.0;
}
}
return result;
}
/**
* Always throws an Exception since the result of NormDiscrete must
* be continuous.
*
* @param incoming the incoming parameter values
* @throws Exception always
*/
public String getResultCategorical(double[] incoming) throws Exception {
throw new Exception("[NormDiscrete] Can't return the result as a categorical value!");
}
public String toString(String pad) {
StringBuffer buff = new StringBuffer();
buff.append("NormDiscrete: " + m_fieldName + "=" + m_fieldValue);
if (m_mapMissingDefined) {
buff.append("\n" + pad + "map missing values to: " + m_mapMissingTo);
}
return buff.toString();
}
}