⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 addexpression.java

📁 一个数据挖掘软件ALPHAMINERR的整个过程的JAVA版源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 *    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 2 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, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 *    AddExpression.java
 *    Copyright (C) 2000 Mark Hall
 *
 */

package weka.filters.unsupervised.attribute;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;

import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.Option;
import weka.core.OptionHandler;
import weka.core.SparseInstance;
import weka.core.Utils;
import weka.filters.Filter;
import weka.filters.StreamableFilter;
import weka.filters.UnsupervisedFilter;

/**
 * Applys a mathematical expression involving attributes and numeric constants
 * to a dataset. A new attribute is appended after the last attribute that
 * contains the result of applying the expression. Supported operators are: +, -, *, /, ^,
 * log, abs, cos, exp, sqrt, floor, ceil, rint, tan, sin, (, ). Attributes are
 * specified by prefixing with 'a', eg. a7 is attribute number 7 (starting from
 * 1).
 * <p>
 * 
 * Valid filter-specific options are:
 * <p>
 * 
 * -E expression <br>
 * Specify the expression to apply. Eg. a1^2*a5/log(a7*4.0).
 * <p>
 * 
 * -N name <br>
 * Specify a name for the new attribute. Default is to name it with the
 * expression provided with the -E option.
 * <p>
 * 
 * -D<br>
 * Debug. Names the attribute with the postfix parse of the expression.
 * <p>
 * 
 * @author Mark Hall (mhall@cs.waikato.ac.nz)
 * @version $Revision$
 */
public class AddExpression extends Filter implements UnsupervisedFilter,
        StreamableFilter, OptionHandler {

    /**
     * Inner class handling an attribute index as an operand
     */
    private class AttributeOperand implements Serializable {

        /** the index of the attribute */
        protected int m_attributeIndex;

        /** true if the value of the attribute are to be multiplied by -1 */
        protected boolean m_negative;

        public AttributeOperand(String operand, boolean sign) throws Exception {
            // strip the leading 'a' and set the index
            m_attributeIndex = (Integer.parseInt(operand.substring(1))) - 1;
            m_negative = sign;
        }

        /**
         * Return a string describing this object
         * 
         * @return a string descibing the attribute operand
         */
        public String toString() {
            String result = "";
            if (m_negative) {
                result += '-';
            }
            return result + "a" + (m_attributeIndex + 1);
        }
    }

    /**
     * Inner class for storing numeric constant opperands
     */
    private class NumericOperand implements Serializable {

        /** numeric constant */
        protected double m_numericConst;

        public NumericOperand(String operand, boolean sign) throws Exception {
            m_numericConst = Double.valueOf(operand).doubleValue();
            if (sign) {
                m_numericConst *= -1.0;
            }
        }

        /**
         * Return a string describing this object
         * 
         * @return a string descibing the numeric operand
         */
        public String toString() {
            return "" + m_numericConst;
        }
    }

    /**
     * Inner class for storing operators
     */
    private class Operator implements Serializable {

        /** the operator */
        protected char m_operator;

        public Operator(char opp) {
            if (!isOperator(opp)) {
                throw new IllegalArgumentException("Unrecognized operator:"
                        + opp);
            }
            m_operator = opp;
        }

        /**
         * Apply this operator to the supplied arguments
         * 
         * @param first
         *            the first argument
         * @param second
         *            the second argument
         * @return the result
         */
        protected double applyOperator(double first, double second) {
            switch (m_operator) {
            case '+':
                return (first + second);
            case '-':
                return (first - second);
            case '*':
                return (first * second);
            case '/':
                return (first / second);
            case '^':
                return Math.pow(first, second);
            }
            return Double.NaN;
        }

        /**
         * Apply this operator (function) to the supplied argument
         * 
         * @param value
         *            the argument
         * @return the result
         */
        protected double applyFunction(double value) {
            double retVal;
            switch (m_operator) {
            case 'l':
                retVal = Math.log(value);
                break;
            case 'b':
                retVal = Math.abs(value);
                break;
            case 'c':
                retVal = Math.cos(value);
                break;
            case 'e':
                retVal = Math.exp(value);
                break;
            case 's':
                retVal = Math.sqrt(value);
                break;
            case 'f':
                retVal = Math.floor(value);
                break;
            case 'h':
                retVal = Math.ceil(value);
                break;
            case 'r':
                retVal = Math.rint(value);
                break;
            case 't':
                retVal = Math.tan(value);
                break;
            case 'n':
                retVal = Math.sin(value);
                break;
            //<<Frank Xu, 09/09/2004
            //Add relational operators.
            case 'u':
                retVal = (double) (value == 0 ? 1 : 0);
                break;
            case 'v':
                retVal = (double) (value != 0 ? 1 : 0);
                break;
            case 'w':
                retVal = (double) (value >= 0 ? 1 : 0);
                break;
            case 'x':
                retVal = (double) (value > 0 ? 1 : 0);
                break;
            case 'y':
                retVal = (double) (value <= 0 ? 1 : 0);
                break;
            case 'z':
                retVal = (double) (value < 0 ? 1 : 0);
                break;
            default:
                retVal = Double.NaN;
            //Frank Xu, 09/09/2004>>
            }
            return retVal;
        }

        /**
         * Return a string describing this object
         * 
         * @return a string descibing the operator
         */
        public String toString() {
            return "" + m_operator;
        }
    }

    /** The infix expression */
    private String m_infixExpression = "a1^2";

    /** Operator stack */
    private Stack m_operatorStack = new Stack();

    /**
     * Supported operators. l = log, b = abs, c = cos, e = exp, s = sqrt, f =
     * floor, h = ceil, r = rint, t = tan, n = sin
     */
    //<<Frank Xu, 09/09/2004
    //Add Relational Operators.
    //private static final String OPERATORS = "+-*/()^lbcesfhrtn";
    //private static final String UNARY_FUNCTIONS = "lbcesfhrtn";
    private static final String OPERATORS = "+-*/()^lbcesfhrtnuvwxyz";

    private static final String UNARY_FUNCTIONS = "lbcesfhrtnuvwxyz";

    //>>Frank Xu, 09/09/2004

    /** Holds the expression in postfix form */
    private Vector m_postFixExpVector;

    /** True if the next numeric constant or attribute index is negative */
    private boolean m_signMod = false;

    /** Holds the previous token */
    private String m_previousTok = "";

    /**
     * Name of the new attribute. "expression" length string will use the
     * provided expression as the new attribute name
     */
    private String m_attributeName = "expression";

    /**
     * If true, makes the attribute name equal to the postfix parse of the
     * expression
     */
    private boolean m_Debug = false;

    /**
     * Returns a string describing this filter
     * 
     * @return a description of the filter suitable for displaying in the
     *         explorer/experimenter gui
     */
    public String globalInfo() {
        return "An instance filter that creates a new attribute by applying a "
                + "mathematical expression to existing attributes. The expression "
                + "can contain attribute references and numeric constants. Supported "
                + "opperators are :  +, -, *, /, ^, log, abs, cos, exp, sqrt, "
                + "floor, ceil, rint, tan, sin, (, ). Attributes are specified "
                + "by prefixing with 'a', eg. a7 is attribute number 7 (starting from 1)."
                + " Example expression : a1^2*a5/log(a7*4.0).";
    }

    /**
     * Handles the processing of an infix operand to postfix
     * 
     * @param tok
     *            the infix operand
     * @exception Exception
     *                if there is difficulty parsing the operand
     */
    private void handleOperand(String tok) throws Exception {
        // if it contains an 'a' then its an attribute index
        if (tok.indexOf('a') != -1) {
            m_postFixExpVector.addElement(new AttributeOperand(tok, m_signMod));
        } else {
            try {
                // should be a numeric constant
                m_postFixExpVector
                        .addElement(new NumericOperand(tok, m_signMod));
            } catch (NumberFormatException ne) {
                throw new Exception("Trouble parsing numeric constant");
            }
        }
        m_signMod = false;
    }

    /**
     * Handles the processing of an infix operator to postfix
     * 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -