📄 evaluation.java
字号:
*/
public final double SFSchemeEntropy() {
return m_SumSchemeEntropy;
}
/**
* Returns the entropy per instance for the scheme
*
* @return the scheme entropy per instance
*/
public final double SFMeanSchemeEntropy() {
return m_SumSchemeEntropy / m_WithClass;
}
/**
* Returns the total SF, which is the null model entropy minus
* the scheme entropy.
*
* @return the total SF
*/
public final double SFEntropyGain() {
return m_SumPriorEntropy - m_SumSchemeEntropy;
}
/**
* Returns the SF per instance, which is the null model entropy
* minus the scheme entropy, per instance.
*
* @return the SF per instance
*/
public final double SFMeanEntropyGain() {
return (m_SumPriorEntropy - m_SumSchemeEntropy) / m_WithClass;
}
/**
* Output the cumulative margin distribution as a string suitable
* for input for gnuplot or similar package.
*
* @return the cumulative margin distribution
* @exception Exception if the class attribute is nominal
*/
public String toCumulativeMarginDistributionString() throws Exception {
if (!m_ClassIsNominal) {
throw new Exception("Class must be nominal for margin distributions");
}
String result = "";
double cumulativeCount = 0;
double margin;
for(int i = 0; i <= k_MarginResolution; i++) {
if (m_MarginCounts[i] != 0) {
cumulativeCount += m_MarginCounts[i];
margin = (double)i * 2.0 / k_MarginResolution - 1.0;
result = result + Utils.doubleToString(margin, 7, 3) + ' '
+ Utils.doubleToString(cumulativeCount * 100
/ m_WithClass, 7, 3) + '\n';
} else if (i == 0) {
result = Utils.doubleToString(-1.0, 7, 3) + ' '
+ Utils.doubleToString(0, 7, 3) + '\n';
}
}
return result;
}
/**
* Calls toSummaryString() with no title and no complexity stats
*
* @return a summary description of the classifier evaluation
*/
public String toSummaryString() {
return toSummaryString("", false);
}
/**
* Calls toSummaryString() with a default title.
*
* @param printComplexityStatistics if true, complexity statistics are
* returned as well
*/
public String toSummaryString(boolean printComplexityStatistics) {
return toSummaryString("=== Summary ===\n", printComplexityStatistics);
}
/**
* Outputs the performance statistics in summary form. Lists
* number (and percentage) of instances classified correctly,
* incorrectly and unclassified. Outputs the total number of
* instances classified, and the number of instances (if any)
* that had no class value provided.
*
* @param title the title for the statistics
* @param printComplexityStatistics if true, complexity statistics are
* returned as well
* @return the summary as a String
*/
public String toSummaryString(String title,
boolean printComplexityStatistics) {
double mae, mad = 0;
StringBuffer text = new StringBuffer();
text.append(title + "\n");
try {
if (m_WithClass > 0) {
if (m_ClassIsNominal) {
text.append("Correctly Classified Instances ");
text.append(Utils.doubleToString(correct(), 12, 4) + " " +
Utils.doubleToString(pctCorrect(),
12, 4) + " %\n");
text.append("Incorrectly Classified Instances ");
text.append(Utils.doubleToString(incorrect(), 12, 4) + " " +
Utils.doubleToString(pctIncorrect(),
12, 4) + " %\n");
text.append("Kappa statistic ");
text.append(Utils.doubleToString(kappa(), 12, 4) + "\n");
if (m_CostMatrix != null) {
text.append("Total Cost ");
text.append(Utils.doubleToString(totalCost(), 12, 4) + "\n");
text.append("Average Cost ");
text.append(Utils.doubleToString(avgCost(), 12, 4) + "\n");
}
if (printComplexityStatistics) {
text.append("K&B Relative Info Score ");
text.append(Utils.doubleToString(KBRelativeInformation(), 12, 4)
+ " %\n");
text.append("K&B Information Score ");
text.append(Utils.doubleToString(KBInformation(), 12, 4)
+ " bits");
text.append(Utils.doubleToString(KBMeanInformation(), 12, 4)
+ " bits/instance\n");
}
} else {
text.append("Correlation coefficient ");
text.append(Utils.doubleToString(correlationCoefficient(), 12 , 4) +
"\n");
}
if (printComplexityStatistics) {
text.append("Class complexity | order 0 ");
text.append(Utils.doubleToString(SFPriorEntropy(), 12, 4)
+ " bits");
text.append(Utils.doubleToString(SFMeanPriorEntropy(), 12, 4)
+ " bits/instance\n");
text.append("Class complexity | scheme ");
text.append(Utils.doubleToString(SFSchemeEntropy(), 12, 4)
+ " bits");
text.append(Utils.doubleToString(SFMeanSchemeEntropy(), 12, 4)
+ " bits/instance\n");
text.append("Complexity improvement (Sf) ");
text.append(Utils.doubleToString(SFEntropyGain(), 12, 4) + " bits");
text.append(Utils.doubleToString(SFMeanEntropyGain(), 12, 4)
+ " bits/instance\n");
}
text.append("Mean absolute error ");
text.append(Utils.doubleToString(meanAbsoluteError(), 12, 4)
+ "\n");
text.append("Root mean squared error ");
text.append(Utils.
doubleToString(rootMeanSquaredError(), 12, 4)
+ "\n");
text.append("Relative absolute error ");
text.append(Utils.doubleToString(relativeAbsoluteError(),
12, 4) + " %\n");
text.append("Root relative squared error ");
text.append(Utils.doubleToString(rootRelativeSquaredError(),
12, 4) + " %\n");
}
if (Utils.gr(unclassified(), 0)) {
text.append("UnClassified Instances ");
text.append(Utils.doubleToString(unclassified(), 12,4) + " " +
Utils.doubleToString(pctUnclassified(),
12, 4) + " %\n");
}
text.append("Total Number of Instances ");
text.append(Utils.doubleToString(m_WithClass, 12, 4) + "\n");
if (m_MissingClass > 0) {
text.append("Ignored Class Unknown Instances ");
text.append(Utils.doubleToString(m_MissingClass, 12, 4) + "\n");
}
} catch (Exception ex) {
// Should never occur since the class is known to be nominal
// here
System.err.println("Arggh - Must be a bug in Evaluation class");
}
return text.toString();
}
/**
* Calls toMatrixString() with a default title.
*
* @return the confusion matrix as a string
* @exception Exception if the class is numeric
*/
public String toMatrixString() throws Exception {
return toMatrixString("=== Confusion Matrix ===\n");
}
/**
* Outputs the performance statistics as a classification confusion
* matrix. For each class value, shows the distribution of
* predicted class values.
*
* @param title the title for the confusion matrix
* @return the confusion matrix as a String
* @exception Exception if the class is numeric
*/
public String toMatrixString(String title) throws Exception {
StringBuffer text = new StringBuffer();
char [] IDChars = {'a','b','c','d','e','f','g','h','i','j',
'k','l','m','n','o','p','q','r','s','t',
'u','v','w','x','y','z'};
int IDWidth;
boolean fractional = false;
if (!m_ClassIsNominal) {
throw new Exception("Evaluation: No confusion matrix possible!");
}
// Find the maximum value in the matrix
// and check for fractional display requirement
double maxval = 0;
for(int i = 0; i < m_NumClasses; i++) {
for(int j = 0; j < m_NumClasses; j++) {
double current = m_ConfusionMatrix[i][j];
if (current < 0) {
current *= -10;
}
if (current > maxval) {
maxval = current;
}
double fract = current - Math.rint(current);
if (!fractional
&& ((Math.log(fract) / Math.log(10)) >= -2)) {
fractional = true;
}
}
}
IDWidth = 1 + Math.max((int)(Math.log(maxval) / Math.log(10)
+ (fractional ? 3 : 0)),
(int)(Math.log(m_NumClasses) /
Math.log(IDChars.length)));
text.append(title).append("\n");
for(int i = 0; i < m_NumClasses; i++) {
if (fractional) {
text.append(" ").append(num2ShortID(i,IDChars,IDWidth - 3))
.append(" ");
} else {
text.append(" ").append(num2ShortID(i,IDChars,IDWidth));
}
}
text.append(" <-- classified as\n");
for(int i = 0; i< m_NumClasses; i++) {
for(int j = 0; j < m_NumClasses; j++) {
text.append(" ").append(
Utils.doubleToString(m_ConfusionMatrix[i][j],
IDWidth,
(fractional ? 2 : 0)));
}
text.append(" | ").append(num2ShortID(i,IDChars,IDWidth))
.append(" = ").append(m_ClassNames[i]).append("\n");
}
return text.toString();
}
public String toClassDetailsString() throws Exception {
return toClassDetailsString("=== Detailed Accuracy By Class ===\n");
}
/**
* Generates a breakdown of the accuracy for each class,
* incorporating various information-retrieval statistics, such as
* true/false positive rate, precision/recall/F-Measure. Should be
* useful for ROC curves, recall/precision curves.
*
* @param title the title to prepend the stats string with
* @return the statistics presented as a string
*/
public String toClassDetailsString(String title) throws Exception {
if (!m_ClassIsNominal) {
throw new Exception("Evaluation: No confusion matrix possible!");
}
StringBuffer text = new StringBuffer(title
+ "\nTP Rate FP Rate"
+ " Precision Recall"
+ " F-Measure Class\n");
for(int i = 0; i < m_NumClasses; i++) {
text.append(Utils.doubleToString(truePositiveRate(i), 7, 3))
.append(" ");
text.append(Utils.doubleToString(falsePositiveRate(i), 7, 3))
.append(" ");
text.append(Utils.doubleToString(precision(i), 7, 3))
.append(" ");
text.append(Utils.doubleToString(recall(i), 7, 3))
.append(" ");
text.append(Utils.doubleToString(fMeasure(i), 7, 3))
.append(" ");
text.append(m_ClassNames[i]).append('\n');
}
return text.toString();
}
/**
* Calculate the number of true positives with respect to a particular class.
* This is defined as<p>
* <pre>
* correctly classified positives
* </pre>
*
* @param classIndex the index of the class to consider as "positive"
* @return the true positive rate
*/
public double numTruePositives(int classIndex) {
double correct = 0;
for (int j = 0; j < m_NumClasses; j++) {
if (j == classIndex) {
correct += m_ConfusionMatrix[classIndex][j];
}
}
return correct;
}
/**
* Calculate the true positive rate with respect to a particular class.
* This is defined as<p>
* <pre>
* correctly classified positives
* ------------------------------
* total positives
* </pre>
*
* @param classIndex the index of the class to consider as "positive"
* @return the true positive rate
*/
public double truePositiveRate(int classIndex) {
double correct = 0, total = 0;
for (int j = 0; j < m_NumClasses; j++) {
if (j == classIndex) {
correct += m_ConfusionMatrix[classIndex][j];
}
total += m_ConfusionMatrix[classIndex][j];
}
if (total == 0) {
return 0;
}
return correct / total;
}
/**
* Calculate the number of true negatives with respect to a particular class.
* This is defined as<p>
* <pre>
* correctly classified negatives
* </pre>
*
* @param classIndex the index of the class to consider as "positive"
* @return the true positive rate
*/
public double numTrueNegatives(int classIndex) {
double correct = 0;
for (int i = 0; i < m_NumClasses; i++) {
if (i != classIndex) {
for (int j = 0; j < m_NumClasses; j++) {
if (j != classIndex) {
correct += m_ConfusionMatrix[i][j];
}
}
}
}
return correct;
}
/**
* Calculate the true negative rate with respect to a particular class.
* This is defined as<p>
* <pre>
* correctly classified negatives
* ------------------------------
* total negatives
* </pre>
*
* @param classIndex the index of the class to consider as "positive"
* @return the true positive rate
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -