source: branches/MetisMQI/src/main/java/weka/core/pmml/NormDiscrete.java

Last change on this file was 29, checked in by gnappo, 15 years ago

Taggata versione per la demo e aggiunto branch.

File size: 6.7 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 *    NormDiscrete.java
19 *    Copyright (C) 2008 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.core.pmml;
24
25import java.util.ArrayList;
26
27import org.w3c.dom.Element;
28
29import weka.core.Attribute;
30import weka.core.Instance;
31import weka.core.Utils;
32
33/**
34 * Class encapsulating a NormDiscrete Expression. Creates an
35 * indicator for a particular discrete value.
36 *
37 * @author Mark Hall (mhall{[at]}pentaho{[dot]}com)
38 * @version $Revision 1.0 $
39 */
40public class NormDiscrete extends Expression {
41 
42  /**
43   * For serialization
44   */
45  private static final long serialVersionUID = -8854409417983908220L;
46
47  /** The name of the field to lookup our value in */
48  protected String m_fieldName;
49 
50  /** The actual attribute itself */
51  protected Attribute m_field;
52 
53  /** The index of the attribute */
54  protected int m_fieldIndex = -1;
55 
56  /** The actual value (as a String) that will correspond to an output of 1 */
57  protected String m_fieldValue;
58 
59  /** True if a replacement for missing values has been specified */
60  protected boolean m_mapMissingDefined = false;
61 
62  /** The value of the missing value replacement (if defined) */
63  protected double m_mapMissingTo;
64 
65  /**
66   *  If we are referring to a nominal (rather than String) attribute
67   * then this holds the index of the value in question. Will be faster
68   * than searching for the value each time.
69   */
70  protected int m_fieldValueIndex = -1;
71 
72  /**
73   * Constructor. Reads the field name and field value for this NormDiscrete
74   * Expression.
75   *
76   * @param normDisc the Element encapsulating this NormDiscrete
77   * @param opType the optype for this expression (taken from either the
78   * enclosing DefineFunction or DerivedField)
79   * @param fieldDefs an ArrayList of Attributes for the fields that this
80   * Expression might need to access
81   * enclosing DefineFunction or DerivedField)
82   * @throws Exception if there is a problem parsing this Apply Expression
83   */
84  public NormDiscrete(Element normDisc, FieldMetaInfo.Optype opType, ArrayList<Attribute> fieldDefs)
85    throws Exception {
86    super(opType, fieldDefs);
87   
88    if (opType != FieldMetaInfo.Optype.CONTINUOUS) {
89      throw new Exception("[NormDiscrete] can only have a continuous optype");
90    }
91   
92    m_fieldName = normDisc.getAttribute("field");
93    m_fieldValue = normDisc.getAttribute("value");
94   
95    String mapMissing = normDisc.getAttribute("mapMissingTo");
96    if (mapMissing != null && mapMissing.length() > 0) {
97      m_mapMissingTo = Double.parseDouble(mapMissing);
98      m_mapMissingDefined = true;
99    }
100   
101    if (fieldDefs != null) {
102      setUpField();
103    }
104  }
105 
106  /**
107   * Set the field definitions for this Expression to use
108   *
109   * @param fieldDefs the field definitions to use
110   * @throws Exception if there is a problem setting the field definitions
111   */
112  public void setFieldDefs(ArrayList<Attribute> fieldDefs) throws Exception {
113    super.setFieldDefs(fieldDefs);
114    setUpField();
115  }
116 
117  /**
118   * Find the named field, set up the index(es) etc.
119   *
120   * @throws Exception if a problem occurs.
121   */
122  private void setUpField() throws Exception {
123    m_fieldIndex = -1;
124    m_fieldValueIndex = -1;
125    m_field = null;
126   
127    if (m_fieldDefs != null) {
128      m_fieldIndex = getFieldDefIndex(m_fieldName);
129
130      if (m_fieldIndex < 0) {
131        throw new Exception("[NormDiscrete] Can't find field " + m_fieldName
132            + " in the supplied field definitions.");
133      }
134      m_field = m_fieldDefs.get(m_fieldIndex);
135     
136      if (!(m_field.isString() || m_field.isNominal())) {
137        throw new Exception("[NormDiscrete] reference field " + m_fieldName
138            +" must be categorical");
139      }
140     
141      if (m_field.isNominal()) {
142        // set up the value index
143        m_fieldValueIndex = m_field.indexOfValue(m_fieldValue);
144        if (m_fieldValueIndex < 0) {
145          throw new Exception("[NormDiscrete] Unable to find value " + m_fieldValue
146              + " in nominal attribute " + m_field.name());
147        }
148      } else if (m_field.isString()) {
149        // add our value to this attribute (if it is already there
150        // then this will have no effect).
151        m_fieldValueIndex = m_field.addStringValue(m_fieldValue);
152      }
153    }
154  }
155
156  /**
157   * Return the structure of the result of applying this Expression
158   * as an Attribute.
159   *
160   * @return the structure of the result of applying this Expression as an
161   * Attribute.
162   */
163  protected Attribute getOutputDef() {   
164    return new Attribute(m_fieldName + "=" + m_fieldValue);
165  }
166
167  /**
168   * Get the result of evaluating the expression. In the case
169   * of a continuous optype, a real number is returned; in
170   * the case of a categorical/ordinal optype, the index of the nominal
171   * value is returned as a double.
172   *
173   * @param incoming the incoming parameter values
174   * @return the result of evaluating the expression
175   * @throws Exception if there is a problem computing the result
176   */
177  public double getResult(double[] incoming) throws Exception {
178   
179    double result = 0.0;
180    if (Utils.isMissingValue(incoming[m_fieldIndex])) {
181      if (m_mapMissingDefined) {
182        result = m_mapMissingTo; // return the replacement
183      } else {
184        result = incoming[m_fieldIndex]; // just return the missing value
185      }
186    } else {
187      if (m_fieldValueIndex == (int)incoming[m_fieldIndex]) {
188        result = 1.0;
189      }
190    }
191   
192    return result;
193  }
194
195  /**
196   * Always throws an Exception since the result of NormDiscrete must
197   * be continuous.
198   *
199   * @param incoming the incoming parameter values
200   * @throws Exception always
201   */
202  public String getResultCategorical(double[] incoming) throws Exception {
203    throw new Exception("[NormDiscrete] Can't return the result as a categorical value!");
204  }
205 
206  public String toString(String pad) {
207    StringBuffer buff = new StringBuffer();
208    buff.append("NormDiscrete: " + m_fieldName + "=" + m_fieldValue);
209    if (m_mapMissingDefined) {
210      buff.append("\n" + pad + "map missing values to: " + m_mapMissingTo);
211    }
212   
213    return buff.toString();
214  }
215}
Note: See TracBrowser for help on using the repository browser.