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

📄 supportvectorclassifier.java

📁 一个数据挖掘软件ALPHAMINERR的整个过程的JAVA版源代码
💻 JAVA
字号:
/*
 *    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.
 */

/**
 * Title: XELOPES Data Mining Library
 * Description: The XELOPES library is an open platform-independent and data-source-independent library for Embedded Data Mining.
 * Copyright: Copyright (c) 2002 Prudential Systems Software GmbH
 * Company: ZSoft (www.zsoft.ru), Prudsys (www.prudsys.com)
 * @author Michael Thess
 * @version 1.1
 */
package com.prudsys.pdm.Models.Regression.SVM;

import com.prudsys.pdm.Core.Category;
import com.prudsys.pdm.Core.MetaDataOperations;
import com.prudsys.pdm.Core.MiningAttribute;
import com.prudsys.pdm.Core.MiningDataSpecification;
import com.prudsys.pdm.Core.MiningException;
import com.prudsys.pdm.Input.MiningSparseVector;
import com.prudsys.pdm.Input.MiningVector;
import com.prudsys.pdm.Models.Supervised.Classifier;

/**
 * Basic class of a Support Vector Classifier.
 */
public class SupportVectorClassifier implements Classifier
{
  // -----------------------------------------------------------------------
  //  Variables declarations
  // -----------------------------------------------------------------------
  // SVM types:
  protected int svmType    = SupportVectorSettings.SVM_C_SVC;
  protected int kernelType = SupportVectorSettings.KERNEL_RBF;

  // Kernel parameters:
  protected double degree = 3.0;
  protected double gamma  = 1.0;
  protected double coef0  = 0.0;

  // SVM coefficients:
  protected MiningVector[] supportVectors;
  protected double[] coefficients;
  protected double absoluteCoefficient;

  // Meta data:
  protected MiningDataSpecification metaData;
  protected int classIndex = -1;  // number of classifying attribute, if exists

  // Caching:
  protected MiningDataSpecification pretransMetaData = null;
  protected MiningDataSpecification transMetaData = null;
  protected int vecClassIndex = -1;

  // -----------------------------------------------------------------------
  //  Constructor
  // -----------------------------------------------------------------------
  /**
   * Empty constructor.
   */
  public SupportVectorClassifier()
  {
  }

  // -----------------------------------------------------------------------
  //  Getter and setter methods
  // -----------------------------------------------------------------------
  /**
   * Returns meta data.
   *
   * @return meta data
   */
  public MiningDataSpecification getMetaData()
  {
      return metaData;
  }

  /**
   * Sets meta data.
   *
   * @param metaData meta data to set
   */
  public void setMetaData(MiningDataSpecification metaData)
  {
      this.metaData = metaData;
  }

  /**
   * Returns array of all support vectors.
   *
   * @return array of all support vectors
   */
  public MiningVector[] getSupportVectors()
  {
    return supportVectors;
  }

  /**
   * Returns array of all support vector coefficients.
   *
   * @return array of all support vector coefficients
   */
  public double[] getCoefficients()
  {
    return coefficients;
  }

  /**
   * Returns absolute coefficient.
   *
   * @return absolute coefficient
   */
  public double getAbsoluteCoefficient()
  {
    return absoluteCoefficient;
  }

  // -----------------------------------------------------------------------
  //  Apply SVM to mining vector
  // -----------------------------------------------------------------------
  /**
   * SVM Classification of a given vector.
   *
   * @param vector the vector to be classified
   * @return index of the predicted value
   * @exception MiningException if vector could not be classified
   * successfully
   */
  public double apply(MiningVector vector) throws MiningException {

    // Remove target attribute, if exists:
    vector = removeTargetAttribute(vector);

    // Bring mining vector to same meta data like model:
    MetaDataOperations metaOp = metaData.getMetaDataOp();
    metaOp.setUsageType( MetaDataOperations.USE_ATT_NAMES_AND_TYPES );
    MiningVector mv = metaOp.transform(vector);

    // Two-class or regression SVM:
    if (svmType == SupportVectorSettings.SVM_ONE_CLASS ||
        svmType == SupportVectorSettings.SVM_EPSILON_SVR ||
        svmType == SupportVectorSettings.SVM_NU_SVR)
    {
            double sum = 0;
            for(int i = 0; i < coefficients.length; i++)
                    sum += coefficients[i] * kernelFunction(mv, supportVectors[i]);
            sum -= absoluteCoefficient;
            if (svmType == SupportVectorSettings.SVM_ONE_CLASS)
                    return (sum>0)?1:-1;
            else
                    return sum;
    };

    return Category.MISSING_VALUE;
  }

  //<<17/03/2005, Frank J. Xu
  //Do not add any changes for the current version except implementing the interface.
  // -----------------------------------------------------------------------
  //  Apply SVM to mining vector
  // -----------------------------------------------------------------------
  /**
   * SVM Classification of a given vector.
   *
   * @param vector the vector to be classified
   * @return index of the predicted value
   * @exception MiningException if vector could not be classified
   * successfully
   */
  public double apply(MiningVector vector, Object a_wekaInstances) throws MiningException {

    // Remove target attribute, if exists:
    vector = removeTargetAttribute(vector);

    // Bring mining vector to same meta data like model:
    MetaDataOperations metaOp = metaData.getMetaDataOp();
    metaOp.setUsageType( MetaDataOperations.USE_ATT_NAMES_AND_TYPES );
    MiningVector mv = metaOp.transform(vector);

    // Two-class or regression SVM:
    if (svmType == SupportVectorSettings.SVM_ONE_CLASS ||
        svmType == SupportVectorSettings.SVM_EPSILON_SVR ||
        svmType == SupportVectorSettings.SVM_NU_SVR)
    {
            double sum = 0;
            for(int i = 0; i < coefficients.length; i++)
                    sum += coefficients[i] * kernelFunction(mv, supportVectors[i]);
            sum -= absoluteCoefficient;
            if (svmType == SupportVectorSettings.SVM_ONE_CLASS)
                    return (sum>0)?1:-1;
            else
                    return sum;
    };

    return Category.MISSING_VALUE;
  }
  //17/03/2005, Frank J. Xu>>
  /**
   * Removes target attribute from input vector. Does not change
   * the vector if it does not contain a target attribute.
   *
   * @param vector input vector
   * @return output vector without target attribute
   * @throws MiningException error while trying to remve target vector
   */
  private MiningVector removeTargetAttribute(MiningVector vector)
    throws MiningException {

    // No class index, return:
    if (classIndex == -1)
      return vector;

    // Transform meta data:
    MiningDataSpecification vecMetaData = vector.getMetaData();
    if (vecMetaData != null) {
      // Use caching if possible:
      if (vecMetaData != pretransMetaData) {
        String className = metaData.getMiningAttribute(classIndex).getName();
        MiningAttribute vecTarget = vecMetaData.getMiningAttribute(className);
        if (vecTarget == null)
          vecClassIndex = -1;
        else
          vecClassIndex = vecMetaData.getAttributeIndex(vecTarget);

        // Create reduced meta data:
        if (vecClassIndex > -1) {
          transMetaData = (MiningDataSpecification) vecMetaData.clone();
          transMetaData.setAttributesArray(null);
          for (int i = 0; i < vecClassIndex; i++)
            transMetaData.addMiningAttribute( vecMetaData.getMiningAttribute(i) );
          for (int i = vecClassIndex + 1; i < vecMetaData.getAttributesNumber() ; i++)
            transMetaData.addMiningAttribute( vecMetaData.getMiningAttribute(i) );
        };

        // Caching:
        pretransMetaData = vecMetaData;
      }
    }
    else {
      if (transMetaData == null)
        throw new MiningException("No meta data ressource for attribute removal");
    }

    // Vector does not contain target attribute => return:
    if (vecClassIndex == -1)
      return vector;

    // If target attribute => remove from vector:
    MiningVector mv = vector;
    double[] vec = new double[vector.getValues().length-1];
    for (int i = 0; i < vecClassIndex; i++)
        vec[i]   = vector.getValue(i);
    for (int i = vecClassIndex + 1; i < vector.getValues().length; i++)
        vec[i-1] = vector.getValue(i);

    mv = new MiningVector(vec);
    mv.setMetaData( transMetaData );

    return mv;
  }

  /**
   * Calculates kernel value for given mining vectors.
   *
   * @param vec1 given vector 1
   * @param vec2 given vector 2
   * @return function value
   */
  protected double kernelFunction(MiningVector vec1, MiningVector vec2) {

    MiningSparseVector sv1 = new MiningSparseVector(vec1);
    MiningSparseVector sv2 = new MiningSparseVector(vec2);

    switch (kernelType)
    {
          case SupportVectorSettings.KERNEL_LINEAR:
                  return dot(sv1, sv2);
          case SupportVectorSettings.KERNEL_POLY:
                  return Math.pow(gamma*dot(sv1, sv2)+coef0, degree);
          case SupportVectorSettings.KERNEL_RBF:
          {
                  double sum = 0;
                  int len1 = sv1.getNumValuesSparse();
                  int len2 = sv2.getNumValuesSparse();
                  int i = 0;
                  int j = 0;
                  while (i < len1 && j < len2)
                  {
                          if(sv1.getIndex(i) == sv2.getIndex(j))
                          {
                                  double d = sv1.getValueSparse(i++) - sv2.getValueSparse(j++);
                                  sum += d*d;
                          }
                          else if(sv1.getIndex(i) > sv2.getIndex(j))
                          {
                                  sum += sv2.getValueSparse(j)*sv2.getValueSparse(j);
                                  ++j;
                          }
                          else
                          {
                                  sum += sv1.getValueSparse(i)*sv1.getValueSparse(i);
                                  ++i;
                          };
                  };

                  while(i < len1)
                  {
                          sum += sv1.getValueSparse(i)*sv1.getValueSparse(i);
                          ++i;
                  };

                  while(j < len2)
                  {
                          sum += sv2.getValueSparse(j)*sv2.getValueSparse(j);
                          ++j;
                  };

                  return Math.exp(-gamma*sum);
          }
          case SupportVectorSettings.KERNEL_SIGMOID:
                  return tanh(gamma*dot(sv1,sv2)+absoluteCoefficient);
          default:
                  System.out.println("unknown kernel function.\n");
    };

    return Category.MISSING_VALUE;
  }

  /**
   * Calculates inner product of two sparse mining vectors.
   *
   * @param sv1 first sparse mining vector
   * @param sv2 second sparse mining vector
   * @return dot product of both vectors
   */
  protected double dot(MiningSparseVector sv1, MiningSparseVector sv2) {

    double sum = 0;
    int len1 = sv1.getNumValuesSparse();
    int len2 = sv2.getNumValuesSparse();
    int i = 0;
    int j = 0;
    while(i < len1 && j < len2)
    {
            if (sv1.getIndex(i) == sv2.getIndex(j))
                    sum += sv1.getValueSparse(i++)*sv2.getValueSparse(j++);
            else
            {
                    if (sv1.getIndex(i) > sv2.getIndex(j))
                            ++j;
                    else
                            ++i;
            };
    }
    return sum;
  }

  /**
   * Calculates tangens hyperbolicus.
   *
   * @param x argument
   * @return tanh(x)
   */
  private double tanh(double x)
  {
          double e = Math.exp(x);
          return 1.0-2.0/(e*e+1);
  }

  /**
   * Constructs internel SVM classifier model from data read.
   *
   * @throws MiningException could not construct internal SVM model
   */
  protected void constructModel() throws MiningException {

  }
}

⌨️ 快捷键说明

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