use of org.dmg.pmml.SupportVectorsDocument.SupportVectors in project knime-core by knime.
the class PMMLSVMTranslator method addSVMs.
/**
* @param svmModel the SVM model to add the SVMs to
*/
private void addSVMs(final SupportVectorMachineModel svmModel) {
if (m_svms.size() == 0) {
svmModel.addNewSupportVectorMachine();
// TODO Review what is necessary for the case of an empty model
// for (String target : m_targetValues) {
// SupportVectorMachine svm =
// svmModel.addNewSupportVectorMachine();
// svm.setTargetCategory(target);
// SupportVectors supportVectors = svm.addNewSupportVectors();
// supportVectors.setNumberOfSupportVectors(
// BigInteger.valueOf(0));
// }
} else {
for (Svm svm : m_svms) {
SupportVectorMachine pmmlSvm = svmModel.addNewSupportVectorMachine();
pmmlSvm.setTargetCategory(svm.getPositive());
final boolean binaryClassification = (m_svms.size() == 2);
if (binaryClassification) {
pmmlSvm.setAlternateTargetCategory(m_svms.get(1).getPositive());
}
// add support vectors
SupportVectors pmmlSupportVectors = pmmlSvm.addNewSupportVectors();
DoubleVector[] supVectors = svm.getSupportVectors();
pmmlSupportVectors.setNumberOfAttributes(BigInteger.valueOf(supVectors[0].getNumberValues()));
pmmlSupportVectors.setNumberOfSupportVectors(BigInteger.valueOf(supVectors.length));
for (int i = 0; i < supVectors.length; i++) {
SupportVector pmmlSupportVector = pmmlSupportVectors.addNewSupportVector();
pmmlSupportVector.setVectorId(getSupportVectorId(supVectors[i]));
}
// ----------------------------------------
// add coefficients
Coefficients pmmlCoefficients = pmmlSvm.addNewCoefficients();
double[] alphas = svm.getTargetAlphas();
pmmlCoefficients.setNumberOfCoefficients(BigInteger.valueOf(alphas.length));
pmmlCoefficients.setAbsoluteValue(svm.getThreshold());
for (int i = 0; i < alphas.length; i++) {
Coefficient pmmlCoefficient = pmmlCoefficients.addNewCoefficient();
/* KNIME defines the winner as the positive side of the
* threshold, but the DMG defines the winner as the negative
* side of the threshold. Therefore, to avoid changing KNIME
* algorithm, we need to add an additional minus sign for
* each svm output. When importing the PMML into KNIME
* the absolute value of the alphas is read. Hence the
* negative sign in the PMML alpha has no influence on
* the KNIME model.*/
pmmlCoefficient.setValue(-1 * alphas[i]);
}
if (binaryClassification) {
/* Binary classification case. Only one SVM is needed. */
break;
}
}
}
}
use of org.dmg.pmml.SupportVectorsDocument.SupportVectors in project knime-core by knime.
the class PMMLSVMTranslator method initSVMs.
/**
* @param svmModel
*/
private void initSVMs(final SupportVectorMachineModel svmModel) {
final Map<String, ArrayList<Double>> vectors = new LinkedHashMap<String, ArrayList<Double>>();
for (VectorInstance vectorInstance : svmModel.getVectorDictionary().getVectorInstanceArray()) {
REALSparseArray sparseArray = vectorInstance.getREALSparseArray1();
ArrayList<Double> values = new ArrayList<Double>();
for (Object realEntry : sparseArray.getREALEntries()) {
values.add((Double) realEntry);
}
vectors.put(vectorInstance.getId(), values);
}
for (SupportVectorMachine supportVectorMachine : svmModel.getSupportVectorMachineArray()) {
// collect support vectors
SupportVectors svs = supportVectorMachine.getSupportVectors();
DoubleVector[] supportVectors = new DoubleVector[svs.getNumberOfSupportVectors().intValue()];
SupportVector[] supportVectorArray = svs.getSupportVectorArray();
for (int i = 0; i < supportVectorArray.length; i++) {
SupportVector supportVector = supportVectorArray[i];
String vectorId = supportVector.getVectorId();
String classValue = getClassValue(vectorId);
supportVectors[i] = new DoubleVector(new RowKey(vectorId), vectors.get(vectorId), classValue);
}
Coefficients coef = supportVectorMachine.getCoefficients();
double threshold = coef.getAbsoluteValue();
// collect coefficients
Coefficient[] coefficientArray = coef.getCoefficientArray();
double[] alpha = new double[coefficientArray.length];
for (int i = 0; i < coefficientArray.length; i++) {
/**
* The alpha in KNIME is always positive. When calculating the
* distance it is multiplied with a target factor that is 1 or
* -1 depending on whether we have a positive example or not.
* (see {@link SVM#getTargetAlphas()} for details)
*/
alpha[i] = Math.abs(coefficientArray[i].getValue());
}
m_svms.add(new Svm(supportVectors, alpha, supportVectorMachine.getTargetCategory(), threshold, m_kernel));
/* The KNIME internal representation requires two SVMs for the
* binary classification case. Therefore add a second SVM with the
* same configuration as the first one except for the negative
* threshold. */
if (svmModel.getSupportVectorMachineArray().length == 1) {
m_svms.add(new Svm(supportVectors.clone(), alpha, supportVectorMachine.getAlternateTargetCategory(), threshold * -1, m_kernel));
}
}
}
Aggregations