/**
* Copyright 2014 Marco Cornolti
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package it.acubelab.smaph.learn;
import it.acubelab.smaph.learn.TuneModel.OptimizaionProfiles;
import java.io.Serializable;
import java.util.List;
import java.util.Vector;
public class ModelConfigurationResult implements Serializable {
private static final long serialVersionUID = 1L;
private Vector<Integer> pickedFtrs;
private double editDistanceThreshold;
private double wPos;
private double wNeg;
private int totalInstances;
private int tp;
private int fp;
private int fn;
private int tn;
private float microf1, fnRate, macrof1, macroPrec, macroRec;
public ModelConfigurationResult(Vector<Integer> pickedFtrsI, double wPos,
double wNeg, double editDistanceThreshold, int tp, int fp, int fn,
int tn, float microF1, float macroF1, float macroRec, float macroPrec) {
this.pickedFtrs = new Vector<>(pickedFtrsI);
this.wPos = wPos;
this.wNeg = wNeg;
this.editDistanceThreshold = editDistanceThreshold;
this.totalInstances = tp + fp + fn + tn;
this.tp = tp;
this.fp = fp;
this.fn = fn;
this.tn = tn;
this.microf1 = microF1;
this.macrof1 = macroF1;
this.fnRate = (float) fn / (float) (fn + tp);
this.macroRec = macroRec;
this.macroPrec = macroPrec;
}
public String getReadable() {
String ftrsString = "";
for (int ftrId : pickedFtrs)
ftrsString += ftrId + ",";
ftrsString = pickedFtrs.isEmpty() ? "null!" : ftrsString.substring(0,
ftrsString.length() - 1);
return String
.format("Features:%s wPos:%.5f wNeg:%.5f ED-threshold=%.2f tot=%d TP=%d FP=%d FN=%d TN=%d -> FN_rate=%.2f%% mic-F1=%.2f%% mac-P/R/F1=%.2f%%/%.2f%%/%.2f%%",
ftrsString, wPos, wNeg, editDistanceThreshold,
totalInstances, tp, fp, fn, tn, fnRate * 100,
microf1 * 100, macroPrec*100,macroRec*100, macrof1 * 100);
}
public Vector<Integer> getFeatures() {
return this.pickedFtrs;
}
public double getWPos() {
return this.wPos;
}
public double getWNeg() {
return this.wNeg;
}
public int getTN() {
return this.tn;
}
public float getMicroF1() {
return this.microf1;
}
public float getMacroF1() {
return this.macrof1;
}
public double getFNrate() {
return this.fnRate;
}
public boolean worseThan(ModelConfigurationResult other,
OptimizaionProfiles optProfile, double optProfileThreshold) {
boolean betterResult = false;
if (other == null)
return true;
if (optProfile == OptimizaionProfiles.MAXIMIZE_TN)
betterResult = other.getFNrate() < optProfileThreshold
&& other.getTN() > this.getTN();
else if (optProfile == OptimizaionProfiles.MAXIMIZE_MICRO_F1)
betterResult = other.getMicroF1() > this.getMicroF1();
else if (optProfile == OptimizaionProfiles.MAXIMIZE_MACRO_F1)
betterResult = other.getMacroF1() > this.getMacroF1();
return betterResult;
}
public boolean equalResult(ModelConfigurationResult other,
OptimizaionProfiles optProfile, double optProfileThreshold) {
boolean equalResult = false;
if (other == null)
return true;
if (optProfile == OptimizaionProfiles.MAXIMIZE_TN)
equalResult = other.getFNrate() < optProfileThreshold
&& other.getTN() == this.getTN();
else if (optProfile == OptimizaionProfiles.MAXIMIZE_MICRO_F1)
equalResult = other.getMicroF1() == this.getMicroF1();
else if (optProfile == OptimizaionProfiles.MAXIMIZE_MACRO_F1)
equalResult = other.getMacroF1() == this.getMacroF1();
return equalResult;
}
public static ModelConfigurationResult findBest(
List<ModelConfigurationResult> configurations,
OptimizaionProfiles optProfile, double optProfileThreshold) {
ModelConfigurationResult best = null;
for (ModelConfigurationResult conf : configurations)
if (best == null
|| best.worseThan(conf, optProfile, optProfileThreshold)
|| (best.equalResult(conf, optProfile, optProfileThreshold) && best
.getFeatures().size() > conf.getFeatures().size()))
best = conf;
return best;
}
public float getMacroPrecision() {
return this.macroPrec;
}
public float getMacroRecall() {
return this.macroRec;
}
}