📄 gainschartassessment.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.0
*/
package com.prudsys.pdm.Models.Classification;
import java.util.Vector;
import com.prudsys.pdm.Automat.ExternalDataModelAssessment;
import com.prudsys.pdm.Core.MiningException;
import com.prudsys.pdm.Models.Supervised.SupervisedMiningModel;
/**
* Calculates Gains chart and its integral for assessment
* of classification models.
*
* Performs "soft classification".
*/
public class GainsChartAssessment extends ExternalDataModelAssessment
{
public static final double INTERPOLATION_EPSILON = 0.000001;
private boolean useInterpolation = false;
private boolean useNormalization = true;
private int nVec1 = 0;
/**
* Empty constructor.
*/
public GainsChartAssessment()
{
}
/**
* Get whether used interpolation for data vectors with equal score
* (in the interval of INTERPOLATION_EPSILON).
*
* @return true if interpolation is used, else false
*/
public boolean isUseInterpolation()
{
return useInterpolation;
}
/**
* Set whether normalization for gains chart to interval [0,1] is
* used. Otherwise, the number of vectors of class 1 is returned.
*
* @param useInterpolation true if normalization is used, otherwise false
*/
public void setUseInterpolation(boolean useInterpolation)
{
this.useInterpolation = useInterpolation;
}
/**
* Get whether normalization for gains chart to interval [0,1] is
* used. Otherwise, the number of vectors of class 1 is returned.
*
* @return true if normalization is used, otherwise false
*/
public boolean isUseNormalization()
{
return useNormalization;
}
/**
* Set whether normalization for gains chart to interval [0,1] is
* used. Otherwise, the number of vectors of class 1 is returned.
*
* @param useNormalization true if normalization is used, otherwise false
*/
public void setUseNormalization(boolean useNormalization)
{
this.useNormalization = useNormalization;
}
/**
* Calculates gains chart and returns it as array of doubles.
* First value is 0, last is number of class 0 vectors (or 1 if
* normalized).
*
* @returns values of gains chart
* @exception MiningException could not calculate gains chart
*/
public double[] calculateGainsChart() throws MiningException {
if ( miningModel == null || !(miningModel instanceof SupervisedMiningModel) )
throw new MiningException("No supervised mining model specified");
if (assessmentData == null)
throw new MiningException("No assessment data specified");
String targetAttName = ((SupervisedMiningModel) miningModel).getTarget().getName();
// Apply classifier to data and sort:
Vector scoreVec = new Vector();
Vector classVec = new Vector();
while (assessmentData.next()) {
double score = ((SupervisedMiningModel) miningModel).applyModelFunction( assessmentData.read() );
double scoClass = assessmentData.readAttributeValue( assessmentData.getMetaData().getMiningAttribute( targetAttName) );
// Sort:
boolean found = false;
for (int i = 0; i < scoreVec.size(); i++) {
if ( ((Double) scoreVec.elementAt(i)).doubleValue() > score) {
scoreVec.insertElementAt( new Double(score), i );
classVec.insertElementAt( new Double(scoClass), i );
found = true;
break;
};
};
if (! found) {
scoreVec.addElement( new Double(score) );
classVec.addElement( new Double(scoClass) );
};
};
int nVec = scoreVec.size();
double[] gc = new double[ nVec ];
// Fill gains chart:
nVec1 = 0;
int ic = 0; // only for interpolation
for (int i = 0; i < nVec; i++) {
double scoClass = ((Double) classVec.elementAt(i)).doubleValue();
if (scoClass < 0.1) // belongs to class 0
nVec1 = nVec1 + 1;
gc[i] = nVec1;
// Just for interpolation:
if (useInterpolation) {
if (i > 0) {
double score = ((Double) scoreVec.elementAt(i)).doubleValue();
double preScore = ((Double) scoreVec.elementAt(i-1)).doubleValue();
if (score - preScore > INTERPOLATION_EPSILON || i == nVec - 1) {
double diff = (gc[i] - gc[ic]) / (i - ic);
for (int j = ic+1; j < i; j++)
gc[j] = gc[ic] + (j-ic)*diff;
ic = i;
};
};
};
};
// Apply normalization:
if (useNormalization) {
double fac = gc[nVec-1];
if (fac < 0.000001)
fac = 1.0;
for (int i = 0; i < nVec; i++)
gc[i] = gc[i] / fac;
};
return gc;
}
/**
* Calculates Gains chart integral.
*
* @return Gains chart integral
* @exception MiningException if assessment could not be calculated
*/
public double calculateAssessment() throws MiningException {
// useInterpolation = false;
double sum = 0.0;
double[] gc = calculateGainsChart();
int nVec = gc.length;
for (int i = 0; i < nVec; i++)
sum = sum + gc[i];
double fullSum = 0.0;
for (int i = 0; i < nVec; i++) {
if (i < nVec1)
fullSum = fullSum + i+1;
else
fullSum = fullSum + nVec1;
};
if (fullSum > 0.000001)
sum = sum / fullSum;
return sum;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -