📄 olm.java
字号:
} if (m_etype == ET_MAX || m_etype == ET_BOTH) { if (m_baseMax != null) { sb.append("Number of examples in the maximal rule base = " + m_baseMax.numInstances() + "\n"); } else { sb.append("maximal rule base not yet created"); } } if (m_Debug == true) { if (m_etype == ET_MIN || m_etype == ET_BOTH) { sb.append("The minimal rule base is \n"); if (m_baseMin != null) { sb.append(m_baseMin.toString()); } else { sb.append(".... not yet created"); } } if (m_etype == ET_MAX || m_etype == ET_BOTH) { sb.append("The second rule base is \n"); if (m_baseMax != null) { sb.append(m_baseMax.toString()); } else { sb.append(".... not yet created"); } } } sb.append("\n"); return sb.toString(); } /** * Is <code> instance </code> redundant wrt the * current <code> m_baseMin </code>. * This mean we are looking if there is an element in * <code> m_baseMin </code> smaller than <code> instance </code> * and with the same class. * * @param instance the instance of which the redundancy needs to be * checked * @return <code> true </code> if <code> instance </code> * is redundant, <code> false </code> otherwise */ private boolean isRedundant(Instance instance) { Iterator it = new EnumerationIterator(m_baseMin.enumerateInstances()); while(it.hasNext()) { Instance r = (Instance) it.next(); if (instance.classValue() == r.classValue() && InstancesUtil.smallerOrEqual(r, instance) ) { return true; } } return false; } /** * Is <code> instance </code> redundant wrt the * current <code> m_baseMax </code>. * This is dual to the previous method, this means that * <code> instance </code> is redundant if there exists * and example greater of equal than <code> instance </code> * with the same class value. * * @param instance the instance of which the redundancy needs to be * checked * @return <code> true </code> if <code> instance </code> * is redundant, <code> false </code> otherwise */ private boolean isRedundantMax(Instance instance) { Iterator it = new EnumerationIterator(m_baseMax.enumerateInstances()); while(it.hasNext()) { Instance r = (Instance) it.next(); if (instance.classValue() == r.classValue() && InstancesUtil.smallerOrEqual(instance, r) ) { return true; } } return false; } /** * If we were to add <code> instance </code>, how many * and which elements from <code> m_baseMin </code> would * be made redundant by <code> instance </code>. * * @param instance the instance of which the influence is to be determined * @return an array containing two components * [0] is 0 if instance makes no elements redundant; * is 1 if there is one rule that is made redundant by instance; * is 2 if there is more than one rule that is made redundant; * [1] if [0] == 1, this entry gives the element that is made redundant */ private int[] makesRedundant(Instance instance) { int[] ret = new int[2]; for (int i = 0; i < m_baseMin.numInstances(); i++) { Instance r = m_baseMin.instance(i); if (r.classValue() == instance.classValue() && InstancesUtil.smallerOrEqual(instance, r)) { if (ret[0] == 0) { ret[0] = 1; ret[1] = i; } else { // this means ret[0] == 1 ret[0] = 2; return ret; } } } return ret; } /** * If we were to add <code> instance </code>, how many * and which elements from <code> m_baseMax </code> would * be made redundant by <code> instance </code>. * This method is simply dual to <code> makesRedundant </code>. * * @param instance the instance to add * @return an array containing two components * [0] is 0 if instance makes no elements redundant; * is 1 if there is one rule that is made redundant by instance; * is 2 if there is more than one rule that is made redundant; * [1] if [0] == 1, this entry gives the element that is made redundant */ private int[] makesRedundantMax(Instance instance) { int[] ret = new int[2]; for (int i = 0; i < m_baseMax.numInstances(); i++) { Instance r = m_baseMax.instance(i); if (r.classValue() == instance.classValue() && InstancesUtil.smallerOrEqual(r, instance)) { if (ret[0] == 0) { ret[0] = 1; ret[1] = i; } else { // this means ret[0] == 1 ret[0] = 2; return ret; } } } return ret; } /** * Checks if adding <code> instance </code> to <code> m_baseMin </code> * causes reversed preference amongst the elements of <code> * m_baseMin </code>. * * @param instance the instance of which the influence needs to be * determined * @return <code> true </code> if adding <code> instance </code> * to the rule base would cause reversed preference among the rules, * <code> false </code> otherwise. */ private boolean causesReversedPreference(Instance instance) { Iterator it = new EnumerationIterator(m_baseMin.enumerateInstances()); while (it.hasNext()) { Instance r = (Instance) it.next(); if (instance.classValue() > r.classValue() && InstancesUtil.smallerOrEqual(instance, r)) { // in the original version of OLM this should not happen System.err.println ("Should not happen in the original OLM algorithm"); return true; } else if (r.classValue() > instance.classValue() && InstancesUtil.smallerOrEqual(r, instance)) { return true; } } return false; } /** * Checks if adding <code> instance </code> to <code> m_baseMax </code> * causes reversed preference amongst the elements of * <code> m_baseMax </code>. * * @param instance the instance to add * @return true if adding <code> instance </code> to the rule * base would cause reversed preference among the rules, * false otherwise. */ private boolean causesReversedPreferenceMax(Instance instance) { Iterator it = new EnumerationIterator(m_baseMax.enumerateInstances()); while (it.hasNext()) { Instance r = (Instance) it.next(); if (instance.classValue() > r.classValue() && InstancesUtil.smallerOrEqual(instance, r)) { return true; } else if (r.classValue() > instance.classValue() && InstancesUtil.smallerOrEqual(r, instance)) { return true; } } return false; } /** * Find indices of the elements from <code> m_baseMin </code> * that are inconsistent with instance. * * @param instance the instance of which the influence needs to be * determined * @return an array containing two components * [0] is 0 if instance is consistent with all present elements * is 1 if instance is inconsistent (reversed preference) with * exactly one element * is 2 if instance is inconsistent with more than one element * [1] if [0] == 1, this entry gives the index of the * element that has reversed preference wrt to * <code> instance </code> */ private int[] reversedPreferences(Instance instance) { int[] revPreferences = new int[2]; for (int i = 0; i < m_baseMin.numInstances(); i++) { Instance r = m_baseMin.instance(i); if (instance.classValue() < r.classValue() && InstancesUtil.smallerOrEqual(r, instance) ) { if (revPreferences[0] == 0) { revPreferences[0] = 1; revPreferences[1] = i; } else { revPreferences[0] = 2; return revPreferences; } } } return revPreferences; } /** * Find indices of the elements from <code> m_baseMin </code> * that are inconsistent with instance. * * @param instance the instance of which the influence needs to be * determined * @return an array containing two components * [0] is 0 if instance is consistent with all present elements * is 1 if instance is inconsistent (reversed preference) with * exactly one element * is 2 if instance is inconsistent with more than one element * [1] if [0] == 1, this entry gives the index of the * element that has reversed preference wrt to * <code> instance </code> */ private int[] reversedPreferencesMax(Instance instance) { int[] revPreferences = new int[2]; for (int i = 0; i < m_baseMax.numInstances(); i++) { Instance r = m_baseMax.instance(i); if (instance.classValue() > r.classValue() && InstancesUtil.smallerOrEqual(instance, r) ) { if (revPreferences[0] == 0) { revPreferences[0] = 1; revPreferences[1] = i; } else { revPreferences[0] = 2; return revPreferences; } } } return revPreferences; } /** * Calculates the square of the Euclidian distance between * two arrays of doubles. The arrays should have the same length. * * @param a1 the first array * @param a2 the second array * @return the square of the Euclidian distance between the two * arrays <code> a1 </code> and <code> a2 </code> */ private double euclidDistance(double[] a1, double[] a2) { double dist = 0; for (int i = 0; i < a1.length; i++) { dist += (a1[i] - a2[i]) * (a1[i] - a2[i]); } return dist; } /** * Calculates the Hamming distances between two arrays, this * means one counts the number of positions in which these * two array differ. The arrays should be of the same length. * * @param a1 the first array * @param a2 the second array * @return the requested Hamming distance * The Hamming distance between a1 and a2, this is * the number of positions in which a1 and a2 differ */ private int hammingDistance(double[] a1, double[] a2) { int dist = 0; for (int i = 0; i < a1.length; i++) { dist += (a1[i] == a2[i]) ? 0 : 1; } return dist; } /** * Get an enumeration of all available options for this classifier. * * @return an enumeration of available options */ public Enumeration listOptions() { Vector options = new Vector(); Enumeration enm = super.listOptions(); while (enm.hasMoreElements()) options.addElement(enm.nextElement()); String description = "\tSets the classification type to be used.\n" + "\t(Default: " + new SelectedTag(CT_REAL, TAGS_CLASSIFICATIONTYPES) + ")"; String synopsis = "-C " + Tag.toOptionList(TAGS_CLASSIFICATIONTYPES); String name = "C"; options.addElement(new Option(description, name, 1, synopsis)); description = "\tSets the averaging type used in phase 1 of the classifier.\n" + "\t(Default: " + new SelectedTag(AT_MEAN, TAGS_AVERAGINGTYPES) + ")"; synopsis = "-A " + Tag.toOptionList(TAGS_AVERAGINGTYPES); name = "A"; options.addElement(new Option(description, name, 1, synopsis)); description = "\tIf different from " + new SelectedTag(DT_NONE, TAGS_DISTANCETYPES) + ", a nearest neighbour rule is fired when the\n" + "\trule base doesn't contain an example smaller than the instance\n" + "\tto be classified\n" + "\t(Default: " + new SelectedTag(DT_NONE, TAGS_DISTANCETYPES) + ")."; synopsis = "-N " + Tag.toOptionList(TAGS_DISTANCETYPES); name = "N"; options.addElement(new Option(description, name, 1, synopsis)); description = "\tSets the extension type, i.e. the rule base to use." + "\n\t(Default: " + new SelectedTag(ET_MIN, TAGS_EXTENSIONTYPES) + ")"; synopsis = "-E " + Tag.toOptionList(TAGS_EXTENSIONTYPES); name = "E"; options.addElement(new Option(description, name, 1, synopsis)); description = "\tIf set, the instances are also sorted within the same class\n" + "\tbefore building the rule bases"; synopsis = "-sort"; name = "sort"; options.addElement(new Option(description, name, 0, synopsis)); return options.elements(); } /** * Parses the options for this object. <p/> * <!-- options-start --> * Valid options are: <p/> * * <pre> -S <num> * Random number seed. * (default 1)</pre> * * <pre> -D * If set, classifier is run in debug mode and * may output additional info to the console</pre> * * <pre> -C <CL|REG> * Sets the classification type to be used. * (Default: REG)</pre> * * <pre> -A <MEAN|MED|MAX> * Sets the averaging type used in phase 1 of the classifier. * (Default: MEAN)</pre> * * <pre> -N <NONE|EUCL|HAM> * If different from NONE, a nearest neighbour rule is fired when the * rule base doesn't contain an example smaller than the instance * to be classified * (Default: NONE).</pre> * * <pre> -E <MIN|MAX|BOTH> * Sets the extension type, i.e. the rule base to use. * (Default: MIN)</pre> * * <pre> -sort * If set, the instances are also sorted within the same class * before building the rule bases</pre> * <!-- options-end --> * * @param options an array of strings containing the options * @throws Exception if there are options that have invalid arguments. */ public void setOptions(String[] options) throws Exception { String args; // classification type args = Utils.getOption('C', options); if (args.length() != 0) setClassificationType(new SelectedTag(args, TAGS_CLASSIFICATIONTYPES)); else setClassificationType(new SelectedTag(CT_REAL, TAGS_CLASSIFICATIONTYPES)); // averaging type args = Utils.getOption('A', options); if (args.length() != 0) setAveragingType(new SelectedTag(args, TAGS_AVERAGINGTYPES)); else setAveragingType(new SelectedTag(AT_MEAN, TAGS_AVERAGINGTYPES)); // distance type args = Utils.getOption('N', options); if (args.length() != 0) setDistanceType(new SelectedTag(args, TAGS_DISTANCETYPES)); else setDistanceType(new SelectedTag(DT_NONE, TAGS_DISTANCETYPES)); // extension type args = Utils.getOption('E', options); if (args.length() != 0) setExtensionType(new SelectedTag(args, TAGS_EXTENSIONTYPES)); else setExtensionType(new SelectedTag(ET_MIN, TAGS_EXTENSIONTYPES)); // sort ? setSort(Utils.getFlag("sort", options)); super.setOptions(options); } /** * Gets an array of string with the current options of the classifier. * * @return an array suitable as argument for <code> setOptions </code> */ public String[] getOptions() { int i; Vector result; String[] options; result = new Vector(); options = super.getOptions(); for (i = 0; i < options.length; i++) result.add(options[i]); // classification type result.add("-C"); result.add("" + getClassificationType()); result.add("-A"); result.add("" + getAveragingType()); result.add("-N"); result.add("" + getDistanceType()); result.add("-E"); result.add("" + getExtensionType()); if (getSort()) result.add("-sort"); return (String[]) result.toArray(new String[result.size()]); } /** * Main method for testing this class. * * @param args the command line arguments */ public static void main(String[] args) { runClassifier(new OLM(), args); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -