/* * 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 <http://www.gnu.org/licenses/>. */ /* * ClusterGenerator.java * Copyright (C) 2000-2012 University of Waikato, Hamilton, New Zealand * */ package weka.datagenerators; import java.util.Enumeration; import java.util.Vector; import weka.core.Option; import weka.core.Range; import weka.core.Utils; /** * Abstract class for cluster data generators. <p/> * * Example usage as the main of a datagenerator called RandomGenerator: * <pre> * public static void main(String[] args) { * try { * DataGenerator.makeData(new RandomGenerator(), args); * } * catch (Exception e) { * e.printStackTrace(); * System.err.println(e.getMessage()); * } * } * </pre> * <p/> * * @author Gabi Schmidberger (gabi@cs.waikato.ac.nz) * @author FracPete (fracpete at waikato dot ac dot nz) * @version $Revision: 8034 $ */ public abstract class ClusterGenerator extends DataGenerator { /** for serialization */ private static final long serialVersionUID = 6131722618472046365L; /** Number of attribute the dataset should have */ protected int m_NumAttributes; /** class flag */ protected boolean m_ClassFlag = false; /** Stores which columns are boolean (default numeric) */ protected Range m_booleanCols; /** Stores which columns are nominal (default numeric) */ protected Range m_nominalCols; /** * initializes the generator */ public ClusterGenerator() { super(); setNumAttributes(defaultNumAttributes()); } /** * Returns an enumeration describing the available options. * * @return an enumeration of all the available options. */ public Enumeration listOptions() { Vector result = enumToVector(super.listOptions()); result.addElement(new Option( "\tThe number of attributes (default " + defaultNumAttributes() + ").", "a", 1, "-a <num>")); result.addElement(new Option( "\tClass Flag, if set, the cluster is listed in extra attribute.", "c", 0, "-c")); result.addElement(new Option( "\tThe indices for boolean attributes.", "b", 1, "-b <range>")); result.addElement(new Option( "\tThe indices for nominal attributes.", "m", 1, "-m <range>")); return result.elements(); } /** * Sets the options. * * @param options the options * @throws Exception if invalid option */ public void setOptions(String[] options) throws Exception { String tmpStr; super.setOptions(options); tmpStr = Utils.getOption('a', options); if (tmpStr.length() != 0) setNumAttributes(Integer.parseInt(tmpStr)); else setNumAttributes(defaultNumAttributes()); setClassFlag(Utils.getFlag('c', options)); tmpStr = Utils.getOption('b', options); setBooleanIndices(tmpStr); m_booleanCols.setUpper(getNumAttributes()); tmpStr = Utils.getOption('m', options); setNominalIndices(tmpStr); m_nominalCols.setUpper(getNumAttributes()); // check indices tmpStr = checkIndices(); if (tmpStr.length() > 0) throw new IllegalArgumentException(tmpStr); } /** * Gets the current settings of the classifier. * * @return an array of strings suitable for passing to setOptions */ public String[] getOptions() { Vector result; String[] options; int i; result = new Vector(); options = super.getOptions(); for (i = 0; i < options.length; i++) result.add(options[i]); result.add("-a"); result.add("" + getNumAttributes()); if (getClassFlag()) result.add("-c"); if (!getBooleanCols().toString().equalsIgnoreCase("empty")) { result.add("-b"); result.add("" + getBooleanCols()); } if (!getNominalCols().toString().equalsIgnoreCase("empty")) { result.add("-m"); result.add("" + getNominalCols()); } return (String[]) result.toArray(new String[result.size()]); } /** * returns the default number of attributes * * @return the default number of attributes */ protected int defaultNumAttributes() { return 10; } /** * Sets the number of attributes the dataset should have. * @param numAttributes the new number of attributes */ public void setNumAttributes(int numAttributes) { m_NumAttributes = numAttributes; getBooleanCols().setUpper(getNumAttributes()); getNominalCols().setUpper(getNumAttributes()); } /** * Gets the number of attributes that should be produced. * @return the number of attributes that should be produced */ public int getNumAttributes() { return m_NumAttributes; } /** * Returns the tip text for this property * * @return tip text for this property suitable for * displaying in the explorer/experimenter gui */ public String numAttributesTipText() { return "The number of attributes the generated data will contain."; } /** * Sets the class flag, if class flag is set, * the cluster is listed as class atrribute in an extra attribute. * @param classFlag the new class flag */ public void setClassFlag(boolean classFlag) { m_ClassFlag = classFlag; } /** * Gets the class flag. * @return the class flag */ public boolean getClassFlag() { return m_ClassFlag; } /** * Returns the tip text for this property * * @return tip text for this property suitable for * displaying in the explorer/experimenter gui */ public String classFlagTipText() { return "If set to TRUE, lists the cluster as an extra attribute."; } /** * Sets which attributes are boolean * @param rangeList a string representing the list of attributes. Since * the string will typically come from a user, attributes are indexed from * 1. <br/> * eg: first-3,5,6-last * @throws IllegalArgumentException if an invalid range list is supplied */ public void setBooleanIndices(String rangeList) { m_booleanCols.setRanges(rangeList); } /** * Sets which attributes are boolean. * @param value the range to use */ public void setBooleanCols(Range value) { m_booleanCols.setRanges(value.getRanges()); } /** * returns the range of boolean attributes. * * @return the range of boolean attributes */ public Range getBooleanCols() { if (m_booleanCols == null) m_booleanCols = new Range(); return m_booleanCols; } /** * Returns the tip text for this property * * @return tip text for this property suitable for * displaying in the explorer/experimenter gui */ public String booleanColsTipText() { return "The range of attributes that are generated as boolean ones."; } /** * Sets which attributes are nominal * @param rangeList a string representing the list of attributes. Since * the string will typically come from a user, attributes are indexed from * 1. <br/> * eg: first-3,5,6-last * @throws IllegalArgumentException if an invalid range list is supplied */ public void setNominalIndices(String rangeList) { m_nominalCols.setRanges(rangeList); } /** * Sets which attributes are nominal. * @param value the range to use */ public void setNominalCols(Range value) { m_nominalCols.setRanges(value.getRanges()); } /** * returns the range of nominal attributes * * @return the range of nominal attributes */ public Range getNominalCols() { if (m_nominalCols == null) m_nominalCols = new Range(); return m_nominalCols; } /** * Returns the tip text for this property * * @return tip text for this property suitable for * displaying in the explorer/experimenter gui */ public String nominalColsTipText() { return "The range of attributes to generate as nominal ones."; } /** * check if attribute types are not contradicting * * @return empty string if no problem, otherwise error message */ protected String checkIndices() { for (int i = 1; i < getNumAttributes() + 1; i++) { m_booleanCols.isInRange(i); if (m_booleanCols.isInRange(i) && m_nominalCols.isInRange(i)) { return "Error in attribute type: Attribute " + i + " is set boolean and nominal."; } } return ""; } }