📄 attribute.java
字号:
/** * Returns whether the attribute can be averaged meaningfully. * * @return whether the attribute can be averaged or not */ public final boolean isAveragable() { return m_IsAveragable; } /** * Returns whether the attribute has a zeropoint and may be * added meaningfully. * * @return whether the attribute has a zeropoint or not */ public final boolean hasZeropoint() { return m_HasZeropoint; } /** * Returns the attribute's weight. * * @return the attribute's weight as a double */ public final double weight() { return m_Weight; } /** * Returns the lower bound of a numeric attribute. * * @return the lower bound of the specified numeric range */ public final double getLowerNumericBound() { return m_LowerBound; } /** * Returns whether the lower numeric bound of the attribute is open. * * @return whether the lower numeric bound is open or not (closed) */ public final boolean lowerNumericBoundIsOpen() { return m_LowerBoundIsOpen; } /** * Returns the upper bound of a numeric attribute. * * @return the upper bound of the specified numeric range */ public final double getUpperNumericBound() { return m_UpperBound; } /** * Returns whether the upper numeric bound of the attribute is open. * * @return whether the upper numeric bound is open or not (closed) */ public final boolean upperNumericBoundIsOpen() { return m_UpperBoundIsOpen; } /** * Determines whether a value lies within the bounds of the attribute. * * @return whether the value is in range */ public final boolean isInRange(double value) { // dates and missing values are a special case if (m_Type == DATE || value == Instance.missingValue()) return true; if (m_Type != NUMERIC) { // do label range check int intVal = (int) value; if (intVal < 0 || intVal >= m_Hashtable.size()) return false; } else { // do numeric bounds check if (m_LowerBoundIsOpen) { if (value <= m_LowerBound) return false; } else { if (value < m_LowerBound) return false; } if (m_UpperBoundIsOpen) { if (value >= m_UpperBound) return false; } else { if (value > m_UpperBound) return false; } } return true; } /** * Sets the metadata for the attribute. Processes the strings stored in the * metadata of the attribute so that the properties can be set up for the * easy-access metadata methods. Any strings sought that are omitted will * cause default values to be set. * * The following properties are recognised: * ordering, averageable, zeropoint, regular, weight, and range. * * All other properties can be queried and handled appropriately by classes * calling the getMetadata() method. * * @param metadata the metadata * @exception IllegalArgumentException if the properties are not consistent */ private void setMetadata(ProtectedProperties metadata) { m_Metadata = metadata; if (m_Type == DATE) { m_Ordering = ORDERING_ORDERED; m_IsRegular = true; m_IsAveragable = false; m_HasZeropoint = false; } else { // get ordering String orderString = m_Metadata.getProperty("ordering",""); // numeric ordered attributes are averagable and zeropoint by default String def; if (m_Type == NUMERIC && orderString.compareTo("modulo") != 0 && orderString.compareTo("symbolic") != 0) def = "true"; else def = "false"; // determine boolean states m_IsAveragable = (m_Metadata.getProperty("averageable",def).compareTo("true") == 0); m_HasZeropoint = (m_Metadata.getProperty("zeropoint",def).compareTo("true") == 0); // averagable or zeropoint implies regular if (m_IsAveragable || m_HasZeropoint) def = "true"; m_IsRegular = (m_Metadata.getProperty("regular",def).compareTo("true") == 0); // determine ordering if (orderString.compareTo("symbolic") == 0) m_Ordering = ORDERING_SYMBOLIC; else if (orderString.compareTo("ordered") == 0) m_Ordering = ORDERING_ORDERED; else if (orderString.compareTo("modulo") == 0) m_Ordering = ORDERING_MODULO; else { if (m_Type == NUMERIC || m_IsAveragable || m_HasZeropoint) m_Ordering = ORDERING_ORDERED; else m_Ordering = ORDERING_SYMBOLIC; } } // consistency checks if (m_IsAveragable && !m_IsRegular) throw new IllegalArgumentException("An averagable attribute must be" + " regular"); if (m_HasZeropoint && !m_IsRegular) throw new IllegalArgumentException("A zeropoint attribute must be" + " regular"); if (m_IsRegular && m_Ordering == ORDERING_SYMBOLIC) throw new IllegalArgumentException("A symbolic attribute cannot be" + " regular"); if (m_IsAveragable && m_Ordering != ORDERING_ORDERED) throw new IllegalArgumentException("An averagable attribute must be" + " ordered"); if (m_HasZeropoint && m_Ordering != ORDERING_ORDERED) throw new IllegalArgumentException("A zeropoint attribute must be" + " ordered"); // determine weight m_Weight = 1.0; String weightString = m_Metadata.getProperty("weight"); if (weightString != null) { try{ m_Weight = Double.valueOf(weightString).doubleValue(); } catch (NumberFormatException e) { // Check if value is really a number throw new IllegalArgumentException("Not a valid attribute weight: '" + weightString + "'"); } } // determine numeric range if (m_Type == NUMERIC) setNumericRange(m_Metadata.getProperty("range")); } /** * Sets the numeric range based on a string. If the string is null the range * will default to [-inf,+inf]. A square brace represents a closed interval, a * curved brace represents an open interval, and 'inf' represents infinity. * Examples of valid range strings: "[-inf,20)","(-13.5,-5.2)","(5,inf]" * * @param rangeString the string to parse as the attribute's numeric range * @exception IllegalArgumentException if the range is not valid */ private void setNumericRange(String rangeString) { // set defaults m_LowerBound = Double.NEGATIVE_INFINITY; m_LowerBoundIsOpen = false; m_UpperBound = Double.POSITIVE_INFINITY; m_UpperBoundIsOpen = false; if (rangeString == null) return; // set up a tokenzier to parse the string StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(rangeString)); tokenizer.resetSyntax(); tokenizer.whitespaceChars(0, ' '); tokenizer.wordChars(' '+1,'\u00FF'); tokenizer.ordinaryChar('['); tokenizer.ordinaryChar('('); tokenizer.ordinaryChar(','); tokenizer.ordinaryChar(']'); tokenizer.ordinaryChar(')'); try { // get opening brace tokenizer.nextToken(); if (tokenizer.ttype == '[') m_LowerBoundIsOpen = false; else if (tokenizer.ttype == '(') m_LowerBoundIsOpen = true; else throw new IllegalArgumentException("Expected opening brace on range," + " found: " + tokenizer.toString()); // get lower bound tokenizer.nextToken(); if (tokenizer.ttype != tokenizer.TT_WORD) throw new IllegalArgumentException("Expected lower bound in range," + " found: " + tokenizer.toString()); if (tokenizer.sval.compareToIgnoreCase("-inf") == 0) m_LowerBound = Double.NEGATIVE_INFINITY; else if (tokenizer.sval.compareToIgnoreCase("+inf") == 0) m_LowerBound = Double.POSITIVE_INFINITY; else if (tokenizer.sval.compareToIgnoreCase("inf") == 0) m_LowerBound = Double.NEGATIVE_INFINITY; else try { m_LowerBound = Double.valueOf(tokenizer.sval).doubleValue(); } catch (NumberFormatException e) { throw new IllegalArgumentException("Expected lower bound in range," + " found: '" + tokenizer.sval + "'"); } // get separating comma if (tokenizer.nextToken() != ',') throw new IllegalArgumentException("Expected comma in range," + " found: " + tokenizer.toString()); // get upper bound tokenizer.nextToken(); if (tokenizer.ttype != tokenizer.TT_WORD) throw new IllegalArgumentException("Expected upper bound in range," + " found: " + tokenizer.toString()); if (tokenizer.sval.compareToIgnoreCase("-inf") == 0) m_UpperBound = Double.NEGATIVE_INFINITY; else if (tokenizer.sval.compareToIgnoreCase("+inf") == 0) m_UpperBound = Double.POSITIVE_INFINITY; else if (tokenizer.sval.compareToIgnoreCase("inf") == 0) m_UpperBound = Double.POSITIVE_INFINITY; else try { m_UpperBound = Double.valueOf(tokenizer.sval).doubleValue(); } catch (NumberFormatException e) { throw new IllegalArgumentException("Expected upper bound in range," + " found: '" + tokenizer.sval + "'"); } // get closing brace tokenizer.nextToken(); if (tokenizer.ttype == ']') m_UpperBoundIsOpen = false; else if (tokenizer.ttype == ')') m_UpperBoundIsOpen = true; else throw new IllegalArgumentException("Expected closing brace on range," + " found: " + tokenizer.toString()); // check for rubbish on end if (tokenizer.nextToken() != tokenizer.TT_EOF) throw new IllegalArgumentException("Expected end of range string," + " found: " + tokenizer.toString()); } catch (IOException e) { throw new IllegalArgumentException("IOException reading attribute range" + " string: " + e.getMessage()); } if (m_UpperBound < m_LowerBound) throw new IllegalArgumentException("Upper bound (" + m_UpperBound + ") on numeric range is" + " less than lower bound (" + m_LowerBound + ")!"); } /** * Simple main method for testing this class. */ public static void main(String[] ops) { try { // Create numeric attributes "length" and "weight" Attribute length = new Attribute("length"); Attribute weight = new Attribute("weight"); // Create date attribute "date" Attribute date = new Attribute("date", "yyyy-MM-dd HH:mm:ss"); System.out.println(date); double dd = date.parseDate("2001-04-04 14:13:55"); System.out.println("Test date = " + dd); System.out.println(date.formatDate(dd)); dd = new Date().getTime(); System.out.println("Date now = " + dd); System.out.println(date.formatDate(dd)); // Create vector to hold nominal values "first", "second", "third" FastVector my_nominal_values = new FastVector(3); my_nominal_values.addElement("first"); my_nominal_values.addElement("second"); my_nominal_values.addElement("third"); // Create nominal attribute "position" Attribute position = new Attribute("position", my_nominal_values); // Print the name of "position" System.out.println("Name of \"position\": " + position.name()); // Print the values of "position" Enumeration attValues = position.enumerateValues(); while (attValues.hasMoreElements()) { String string = (String)attValues.nextElement(); System.out.println("Value of \"position\": " + string); } // Shallow copy attribute "position" Attribute copy = (Attribute) position.copy(); // Test if attributes are the same System.out.println("Copy is the same as original: " + copy.equals(position)); // Print index of attribute "weight" (should be unset: -1) System.out.println("Index of attribute \"weight\" (should be -1): " + weight.index()); // Print index of value "first" of attribute "position" System.out.println("Index of value \"first\" of \"position\" (should be 0): " + position.indexOfValue("first")); // Tests type of attribute "position" System.out.println("\"position\" is numeric: " + position.isNumeric()); System.out.println("\"position\" is nominal: " + position.isNominal()); System.out.println("\"position\" is string: " + position.isString()); // Prints name of attribute "position" System.out.println("Name of \"position\": " + position.name()); // Prints number of values of attribute "position" System.out.println("Number of values for \"position\": " + position.numValues()); // Prints the values (againg) for (int i = 0; i < position.numValues(); i++) { System.out.println("Value " + i + ": " + position.value(i)); } // Prints the attribute "position" in ARFF format System.out.println(position); // Checks type of attribute "position" using constants switch (position.type()) { case Attribute.NUMERIC: System.out.println("\"position\" is numeric"); break; case Attribute.NOMINAL: System.out.println("\"position\" is nominal"); break; case Attribute.STRING: System.out.println("\"position\" is string"); break; case Attribute.DATE: System.out.println("\"position\" is date"); break; default: System.out.println("\"position\" has unknown type"); } } catch (Exception e) { e.printStackTrace(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -