📄 svmlightmodel.java
字号:
/*
* YALE - Yet Another Learning Environment
* Copyright (C) 2001-2004
* Simon Fischer, Ralf Klinkenberg, Ingo Mierswa,
* Katharina Morik, Oliver Ritthoff
* Artificial Intelligence Unit
* Computer Science Department
* University of Dortmund
* 44221 Dortmund, Germany
* email: yale-team@lists.sourceforge.net
* web: http://yale.cs.uni-dortmund.de/
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
package edu.udo.cs.yale.operator.learner.kernel;
import edu.udo.cs.yale.operator.UserError;
import edu.udo.cs.yale.operator.parameter.*;
import edu.udo.cs.yale.operator.learner.FileModel;
import edu.udo.cs.yale.operator.learner.Model;
import edu.udo.cs.yale.example.Attribute;
import edu.udo.cs.yale.example.ExampleReader;
import edu.udo.cs.yale.example.ExampleSet;
import edu.udo.cs.yale.example.Example;
import edu.udo.cs.yale.operator.Operator;
import edu.udo.cs.yale.operator.OperatorException;
import edu.udo.cs.yale.tools.LogService;
import edu.udo.cs.yale.tools.TempFileService;
import edu.udo.cs.yale.tools.Tools;
import edu.udo.cs.yale.tools.Ontology;
import edu.udo.cs.yale.tools.ParameterService;
import java.io.*;
/** A <code>SVMLightModel</code> stores a classification model produced by a
* <code>SVMLightLearner</code> and can apply this model to an <code>ExampleSet</code>
* in order to label the examples of this example set with their predicted labels.
* <p>
* For applying a stored SVM<sup><i>light</i></sup> model to an example set, a
* <code>SVMLightModel</code> invokes the external
* <a TARGET="_top" HREF="http://svmlight.joachims.org/">SVM<i><sup>light</sup></i></a>
* program by <a href="http://www.joachims.org/">Thorsten Joachims</a>
* [Joachims/1999], an implementation of Vladimir Vapnik's Support Vector Machine (SVM)
* learning method from statistical learning theory [Vapnik/1998].
* The SVM<sup><i>light</i></sup> parameters are the same that were previously used by the
* <code>SVMLightLearner</code> to learn the model and that are stored in the model.
* See the description of the <code>SVMLightLearner</code> for further information.
* </p>
*
* <p><i>Bibliography:</i><br>
* <b>[Joachims/1999]</b>
* <a href="http://www.joachims.org/">Thorsten Joachims</a>:
* <I>Making large-Scale SVM Learning Practical</I>. Chapter 11 in:
* Advances in Kernel Methods - Support Vector Learning,
* B. Schölkopf and C. Burges and A. Smola (editors),
* MIT Press, 1999. <BR>
* <a TARGET="_top" HREF="http://www.joachims.org/publications/joachims_99a.ps.gz">[Postscript (gz)]</a>
* <a TARGET="_top" HREF="http://www.joachims.org/publications/joachims_99a.pdf">[PDF]</a>
* <a TARGET="_top" HREF="http://svmlight.joachims.org/">[SVM<i><sup>light</sup></i>]</a>
* <br>
* <b>[Vapnik/1998]</b> Vladimir N. Vapnik.
* <i>Statistical Learning Theory</i>. Wiley, Chichester, UK, 1998.
* <br>
* </p>
*
* @author Ingo Mierswa, Ralf Klinkenberg
* @version $Id: SVMLightModel.java,v 1.3 2004/08/27 11:57:40 ingomierswa Exp $
* @see edu.udo.cs.yale.operator.learner.kernel.SVMLightLearner
* @see edu.udo.cs.yale.example.ExampleSet
*/
public class SVMLightModel extends FileModel {
private boolean classificationTask;
private int predictionType = PREDICT_CLASSIFICATION;
public SVMLightModel(Attribute label) throws IOException {
super(label);
}
public SVMLightModel(Attribute label, File modelFile, boolean classificationTask) throws IOException {
super(label, modelFile);
this.classificationTask = classificationTask;
}
public void writeYaleData(ObjectOutputStream out) throws IOException {
out.writeBoolean(classificationTask);
}
public void readYaleData(ObjectInputStream in) throws IOException {
classificationTask = in.readBoolean();
}
/** applies the SVM<i><sup>light</sup></i> model to a test set and sets the predicted labels for the examples of this test set. */
public void apply(ExampleSet exampleSet) throws OperatorException {
LogService.logMessage("SVMLightModel '"+getName()+"': SVM^light starts predicting labels ("
+exampleSet.getSize()+" examples).", LogService.TASK);
if (!Ontology.ATTRIBUTE_VALUE_TYPE.isA(exampleSet.getLabel().getValueType(),
Ontology.NOMINAL)) {
LogService.logMessage("SVMLightModel '"+getName()+"': Example set does not have nominal labels!",
LogService.ERROR);
}
// Prepare output and input files (Yale output = SVM^light input = test examples,
// SVM^light output = Yale input = predicted labels for these test examples):
File testFile = writeExamples(exampleSet);
String command = ParameterService.getProperty("yale.svmlight.applycommand");
File outputFile = TempFileService.createTempFile(getName() + "_labels_");
// Start process:
Process process = null;
File modelFile = null;
try {
modelFile = writeModelToTmp();
} catch (IOException e) {
TempFileService.deleteTempFile(modelFile);
TempFileService.deleteTempFile(outputFile);
throw new UserError(null, 303, new Object[] { modelFile, e.getMessage() });
}
String completeCommand = command + " " + testFile + " " + modelFile + " " + outputFile;
LogService.logMessage("SVMLightModel '"+getName()+"': SVM^light called with command '"
+ completeCommand + "'", LogService.TASK);
try {
process = Runtime.getRuntime().exec(completeCommand);
} catch (IOException e) {
TempFileService.deleteTempFile(modelFile);
TempFileService.deleteTempFile(outputFile);
throw new UserError(null, e, 310, new Object[] {completeCommand, e.getMessage()});
}
// Read SVM^light output:
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = null;
try {
output = Tools.readOutput(in);
in.close();
} catch (IOException e) {
TempFileService.deleteTempFile(modelFile);
TempFileService.deleteTempFile(outputFile);
throw new UserError(null, e, 310, new Object[] {completeCommand, e.getMessage()});
}
try {
Tools.waitForProcess(null, process, "svmlight");
} catch (OperatorException e) {
LogService.logMessage("Output of svm_classify:\n"+output, LogService.ERROR);
TempFileService.deleteTempFile(modelFile);
TempFileService.deleteTempFile(outputFile);
throw e;
}
LogService.logMessage("SVMlightModel '"+getName()+"' has succesfully "+
"predicted labels for the example set.",
LogService.TASK);
try {
setPredictedLabels(exampleSet, outputFile);
} catch (IOException e) {
throw new UserError(null, 302, new Object[] { outputFile, e.getMessage() });
} finally {
TempFileService.deleteTempFile(modelFile);
TempFileService.deleteTempFile(outputFile);
}
}
/** Creates the file with examples for the external SVM<i><sup>light</sup></i> process. */
private File writeExamples(ExampleSet exampleSet) throws OperatorException {
File testFile = TempFileService.createTempFile(getName() + "_test_data_");
PrintWriter out = null;
try {
out = new PrintWriter(new FileWriter(testFile));
} catch (IOException e) {
throw new UserError(null, e, 303, new Object[] { testFile, e.getMessage() });
}
ExampleReader r = exampleSet.getExampleReader();
int numberOfAttributes = exampleSet.getNumberOfAttributes();
while (r.hasNext()) {
Example e = r.next();
out.println(e.getAttributesAsSparseString());
}
out.close();
return testFile;
}
/** iterates all examples and the predicted label file and sets the predicted label of each example.
*/
private void setPredictedLabels(ExampleSet exampleSet, File labels) throws IOException {
BufferedReader reader = null;
reader = new BufferedReader(new FileReader(labels));;
ExampleReader r = exampleSet.getExampleReader();
String line = "";
while (((line=reader.readLine())!=null) && (r.hasNext())) {
double readLabel = Double.NaN;
try {
readLabel = Double.parseDouble(line);
} catch (NumberFormatException e) {
LogService.logMessage("SVMLightModel '"+getName()+"': "+
"Read 'NaN' (Not a Number) from SVM^light",
LogService.WARNING);
}
double label;
switch (predictionType) {
case PREDICT_CLASSIFICATION:
if (classificationTask) {
label = (readLabel >= 0) ? Attribute.FIRST_CLASS_INDEX : Attribute.FIRST_CLASS_INDEX + 1;
} else {
label = readLabel;
}
break;
case PREDICT_CONFIDENCE:
label = readLabel;
break;
default:
throw new IllegalArgumentException("SVMLightModel '"+getName()+"': Illegal prediction type.");
}
r.next().setPredictedLabel(label);
}
}
public boolean equals(Object o) {
if (!super.equals(o)) return false;
SVMLightModel other = (SVMLightModel)o;
return this.classificationTask == other.classificationTask;
}
public void setPredictionType(int type) {
this.predictionType = type;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -