📄 attribute.java
字号:
* @return whether the attribute is regular or not
*/
public final boolean isRegular() {
return m_IsRegular;
}
/**
* 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.emerateValues();
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 + -