/* * RapidMiner * * Copyright (C) 2001-2011 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.operator.preprocessing.outlier; import java.util.ArrayList; import java.util.PriorityQueue; import com.rapidminer.tools.math.similarity.DistanceMeasure; /** * The COF class creates COF Objects which handle the representation of objects from the test data set in the core of * the class outlier operators. Such an object is able to store all relevant values, coordinates, dimensions, etc. for * an object (e.g. from an Example from a RapidMiner ExampleSet) as well as perform various operations, such as * computeCOF, and ComputeDistance * * @author Motaz K. Saad */ public class COFObject implements Comparable<COFObject> { double[] values; double cof; int id; double pcl; double deviation; double kDist; double label; public COFObject() { this.cof = Double.POSITIVE_INFINITY; this.id = -1; } public COFObject(double[] vals, double label, double cof, int id) { this.cof = cof; this.id = id; this.values = vals; this.label = label; } /** * @return the values */ public double[] getValues() { return values; } /** * @param values * the values to set */ public void setValues(double[] values) { this.values = values; } /** * @return the value[dim] */ public double getValMember(int dim) { return this.values[dim]; } /** * Provides the (integer) number of dimensions of the Object. Remark: some methods actually use the this.dimensions * reference which is used by this, but this method would be able to provide the dimensions externally. */ public int getDimensions() { return (this.values.length); } /** * @return the cof */ public double getCOF() { return cof; } /** * @param cof * the cof to set */ public void setCOF(double cof) { this.cof = cof; } /** * @return the id */ public int getId() { return id; } /** * @param id * the this.id to set */ public void setId(int id) { this.id = id; } /** * @return the deviation */ public double getDeviation() { return deviation; } /** * @param deviation * the deviation to set */ public void setDeviation(double deviation) { this.deviation = deviation; } /** * @return the kDist */ public double getKDist() { return kDist; } /** * @param dist * the kDist to set */ public void setKDist(double dist) { kDist = dist; } /** * @return the label */ public double getLabel() { return label; } /** * @param label * the label to set */ public void setLabel(double label) { this.label = label; } /** * @return the pcl */ public double getPcl() { return pcl; } /** * @param pcl * the pcl to set */ public void setPcl(double pcl) { this.pcl = pcl; } public int compareTo(COFObject arg0) { if (this.cof < arg0.getCOF()) return 1; if (this.cof > arg0.getCOF()) return -1; else return 0; } public void recomputeCOF(double minDev, double maxDev, double minkDist, double maxkDist) { cof = pcl - ((deviation - minDev) / (maxDev - minDev)) + ((kDist - minkDist) / (maxkDist - minkDist)); } public void computeCOF(ArrayList<COFObject> cofobjectList, int k, DistanceMeasure measure) { // define a list of knn for each cof object PriorityQueue<COFKnn> knnList = new PriorityQueue<COFKnn>(); // reset pcl, kDist, and deviation double pcl = 0.0; double kDist = 0.0; double deviation = 0.0; for (COFObject cofobject : cofobjectList) {// for all objects in the dataset double distance = Double.POSITIVE_INFINITY; // compute the distance to current object distance = measure.calculateDistance(this.getValues(), cofobject.getValues()); COFKnn cOFKnn = new COFKnn(cofobject, distance); // determine if cofobject is on of the nearest neighbors to current object if (knnList.size() < k) knnList.offer(cOFKnn); // if the KNN list is full, remove the far neighbor // i.e, keep only the nearest neighbors else if (distance < knnList.peek().getDistance()) { knnList.remove(); knnList.offer(cOFKnn); } // if the cofobject has the same class label, add its distance to deviation if (this.getLabel() == cofobject.getLabel()) deviation += distance; } this.setDeviation(deviation); // save deviation // compute pcl to current object for (COFKnn cofKnn : knnList) { kDist += measure.calculateDistance(getValues(), cofKnn.getCofobject().getValues()); if (this.getLabel() == cofKnn.getCofobject().getLabel()) { pcl++; } } this.setPcl(pcl); // save pcl this.setCOF(pcl); // save the initial cof based on pcl this.setKDist(kDist); // save kDist } }