import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Random; import jnisvmlight.LabeledFeatureVector; import jnisvmlight.SVMLightModel; import jnisvmlight.SVMLightInterface; import jnisvmlight.TrainingParameters; public class JNI_SVMLight_Test { public static int N = 2000; // number of training docs public static int M = 100; // max. number of features per doc public static void main(String[] args) throws Exception { Random rd = new java.util.Random(new Date().getTime()); // The trainer interface with the native communication to the SVM-light shared // libraries SVMLightInterface trainer = new SVMLightInterface(); // The training data LabeledFeatureVector[] traindata = new LabeledFeatureVector[N]; // Sort all feature vectors in ascedending order of feature dimensions // before training the model SVMLightInterface.SORT_INPUT_VECTORS = true; // Generate a randomly initialized array of N sparse training vectors // with at most M randomly chosen feature dimensions and values System.out.print("GENERATING A RANDOM TRAINING SET [N=" + N + ", M=" + M + "] .."); for (int i = 0; i < N; i++) { int nDims = 1 + rd.nextInt(M - 1); int[] dims = new int[nDims]; double[] values = new double[nDims]; // Generate a number of distinct random feature dimensions HashSet hashedDims = new HashSet(); while (hashedDims.size() < nDims) { hashedDims.add(new Integer(1 + rd.nextInt(M - 1))); } // Fill the vectors int j = 0; for (Iterator iterator = hashedDims.iterator(); iterator.hasNext(); j++) { dims[j] = ((Integer) iterator.next()).intValue(); values[j] = rd.nextDouble(); } if (i % 10 == 0) { System.out.print(i + "."); } // Store dimension/value pairs in new LabeledFeatureVector object traindata[i] = new LabeledFeatureVector(((i < (N / 2)) ? +1 : -1), dims, values); // Use cosine similarities (LinearKernel with L2-normalized input vectors) traindata[i].normalizeL2(); } System.out.println(" DONE."); // Initialize a new TrainingParamteres object with the default SVM-light // values TrainingParameters tp = new TrainingParameters(); // Switch on some debugging output tp.getLearningParameters().verbosity = 1; System.out.println("\nTRAINING SVM-light MODEL .."); SVMLightModel model = trainer.trainModel(traindata, tp); System.out.println(" DONE."); // Use this to store a model to a file or read a model from a URL. //model.writeModelToFile("jni_model.dat"); //model = SVMLightModel.readSVMLightModelFromURL(new java.io.File("jni_model.dat").toURL()); // Use the classifier on the randomly created feature vectors System.out.println("\nVALIDATING SVM-light MODEL in Java.."); int precision = 0; for (int i = 0; i < N; i++) { // Classify a test vector using the Java object // (in a real application, this should not be one of the training vectors) double d = model.classify(traindata[i]); if ((traindata[i].getLabel() < 0 && d < 0) || (traindata[i].getLabel() > 0 && d > 0)) { precision++; } if (i % 10 == 0) { System.out.print(i + "."); } } System.out.println(" DONE."); System.out.println("\n" + ((double) precision / N) + " PRECISION=RECALL ON RANDOM TRAINING SET."); System.out.println("\nVALIDATING SVM-light MODEL in Native Mode.."); precision = 0; for (int i = 0; i < N; i++) { // Classify a test vector using the Native Interface // (in a real application, this should not be one of the training vectors) double d = trainer.classifyNative(traindata[i]); if ((traindata[i].getLabel() < 0 && d < 0) || (traindata[i].getLabel() > 0 && d > 0)) { precision++; } if (i % 10 == 0) { System.out.print(i + "."); } } System.out.println(" DONE."); System.out.println("\n" + ((double) precision / N) + " PRECISION=RECALL ON RANDOM TRAINING SET."); // An alternative way to invoke the SVM-light interface similar to using the // command line parameters. //System.out // .println("\nTRAINING SVM-light MODEL WITH COMMAND LINE PARAMETERS .."); //model = trainer.trainModel(traindata, new String[] { "-z", "c" }); System.out.println(" DONE."); } }