📄 supportvectorclassifier.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 + -