/* * Copyright (c) 1998-2005, The University of Sheffield. * * This file is part of GATE (see http://gate.ac.uk/), and is free * software, licenced under the GNU Library General Public License, * Version 2, June 1991 (in the distribution as file licence.html, * and also available at http://gate.ac.uk/gate/licence.html). * * Valentin Tablan 19/11/2002 * semantic type added by Mike Dowman 31-03-2004 * Weightings added by Mike Dowman 24-5-2004 * * $Id: Attribute.java 6974 2005-10-18 11:52:16 +0000 (Tue, 18 Oct 2005) nirajaswani $ * */ package gate.creole.ml; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import org.jdom.Element; import gate.util.GateException; /** * Describes an attribute associated to a ML instance. */ public class Attribute implements Serializable{ public Attribute(Element jdomElement) throws GateException { //find the name Element anElement = jdomElement.getChild("NAME"); if(anElement == null) throw new GateException( "Required element \"NAME\" not present in attribute:\n" + jdomElement.toString() + "!"); else name = anElement.getTextTrim(); //find the type anElement = jdomElement.getChild("TYPE"); if(anElement == null) throw new GateException( "Required element \"TYPE\" not present in attribute:\n" + jdomElement.toString() + "!"); else type = anElement.getTextTrim(); //find the feature if present anElement = jdomElement.getChild("FEATURE"); if(anElement != null)feature = anElement.getTextTrim(); //find the position if present anElement = jdomElement.getChild("POSITION"); if(anElement == null) position = 0; else position = Integer.parseInt(anElement.getTextTrim()); // find the weighting if present anElement = jdomElement.getChild("WEIGHTING"); if (anElement == null) weighting = 1.0; else weighting = Double.parseDouble(anElement.getTextTrim()); //find the class if present isClass = jdomElement.getChild("CLASS") != null; //find the allowed values if present anElement = jdomElement.getChild("VALUES"); if(anElement == null) values = null; else{ values = new ArrayList(); Iterator valuesIter = anElement.getChildren("VALUE").iterator(); while(valuesIter.hasNext()){ values.add(((Element)valuesIter.next()).getTextTrim()); } } } public Attribute(){ name = null; type =null; feature = null; isClass = false; position = 0; values = null; weighting = 1.0; } public String toString(){ StringBuffer res = new StringBuffer(); res.append("Name: " + name + "\n"); res.append("Type: " + type + "\n"); res.append("Feature: " + feature + "\n"); res.append("Weighting: "+ weighting + "\n"); Iterator valIter = values.iterator(); while(valIter.hasNext()){ res.append(" Value:" + valIter.next().toString() + "\n"); } return res.toString(); } /** * This method is a clone of gate.creole.mi.Attribute.parseSerie method with minor * changes to make it compatible with ML API. It basically given an attribute element * first locates all required variable and creates multiple attributes for the given RANGE. */ public static java.util.List parseSeries(Element jdomElement) throws GateException { //find the name Element anElement = jdomElement.getChild("NAME"); if(anElement == null) throw new GateException( "Required element \"NAME\" not present in attribute:\n" + jdomElement.toString() + "!"); String name = anElement.getTextTrim(); //find the type anElement = jdomElement.getChild("TYPE"); if(anElement == null) throw new GateException( "Required element \"TYPE\" not present in attribute:\n" + jdomElement.toString() + "!"); String type = anElement.getTextTrim(); String feature = null; //find the feature if present anElement = jdomElement.getChild("FEATURE"); if(anElement != null)feature = anElement.getTextTrim(); int minpos = 0; int maxpos = 0; //find the range of this element (e.g. from - to) anElement = jdomElement.getChild("RANGE"); try { minpos = Integer.parseInt(anElement.getAttributeValue("from").trim()); maxpos = Integer.parseInt(anElement.getAttributeValue("to").trim()); } catch (Exception e){ throw new GateException( "Range element is uncorrect:\n" + jdomElement.toString() + "!"); } double weighting = 1.0; // find the weighting if present anElement = jdomElement.getChild("WEIGHTING"); if (anElement != null) weighting = Double.parseDouble(anElement.getTextTrim()); //find the class if present boolean isClass = jdomElement.getChild("CLASS") != null; if (isClass){ throw new GateException( "Cannot define the class in a serie:\n" + jdomElement.toString() + "!"); } java.util.List values = null; //find the allowed values if present anElement = jdomElement.getChild("VALUES"); if(anElement == null) values = null; else{ values = new ArrayList(); Iterator valuesIter = anElement.getChildren("VALUE").iterator(); while(valuesIter.hasNext()){ values.add(((Element)valuesIter.next()).getTextTrim()); } } // Create a list of Attributes ArrayList attributes = new ArrayList(); for (int position =minpos; position<maxpos+1;position++ ){ Attribute attribute = new Attribute(); attribute.setClass(false); attribute.setFeature(feature); attribute.setName(name+"_"+position); attribute.setPosition(position); attribute.setType(type); attribute.setWeighting(weighting); attribute.setValues(values); attributes.add(attribute); } return attributes; } public boolean isClass(){ return isClass; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setType(String type) { this.type = type; } public String getType() { return type; } public void setFeature(String feature) { this.feature = feature; } public String getFeature() { return feature; } public void setWeighting(double weighting) { this.weighting = weighting; } public double getWeighting() { return weighting; } public java.util.List getValues() { return values; } public int getPosition() { return position; } public void setClass(boolean isClass) { this.isClass = isClass; } public void setValues(java.util.List values) { this.values = values; } public void setPosition(int position) { this.position = position; } /** * This method reports whether the attribute is nominal, numeric or boolean. * * @return Attribute.NOMINAL, Attribute.NUMERIC or Attribute.BOOLEAN */ public int semanticType() { // Only nominal attributes specify values, and only numeric and nominal // attributes specify feature, so this code is sufficient to distinguish // the three kinds of attribute. if (feature==null) return BOOLEAN; if (values==null) return NUMERIC; return NOMINAL; } // These constants are used only for returning values from semanticType public static final int NOMINAL=1; public static final int NUMERIC=2; public static final int BOOLEAN=3; boolean isClass = false; private String name; private String type; private String feature; private java.util.List values; private int position; // The SVMLightWrapper allows weighting for attributes to be specified in // the configuration file, and those weightings are stored in this member. // Weightings are (at time of writing) ignored by the Weka and Maxent // wrappers. private double weighting; }