我正在尝试使用Smile(https://github.com/haifengl/smile)来训练SVM。
我的数据以SvmLight / LibSvm格式给出,所以我认为我可能应该使用库的阅读器来读取我的数据,并温和地进行了本教程:https://github.com/haifengl/smile/wiki/Tutorial:-A-Gentle-Introduction-to-Smile。
LibsvmParser parser = new LibsvmParser();
File training = new File("[...]");
File testing = new File("[...]");
try {
SparseDataset trainingData = parser.parse(training);
SparseDataset testingData = parser.parse(testing);
double[][] trainVectors = trainingData.toArray();
int[] trainClasses = trainingData.toArray(new int[trainingData.size()]);
double[][] testVectors = testingData.toArray();
int[] testClasses = testingData.toArray(new int[testingData.size()]);
[...]
这导致训练和测试向量的长度不同,因为训练/测试集中的最大索引不同。我本来以为来自训练有素的SVM的预测会在内部将特征向量提升到一个通用的大小,但这似乎并没有。这意味着:
SVM<double[]> svm = new SVM<>(new GaussianKernel(8.0), 5.0, 2);
svm.learn(trainVectors, trainClasses);
svm.finish();
int error = 0;
for (int i = 0; i < testVectors.length; i++) {
//ERROR in next line
if (svm.predict(testVectors[i]) != testClasses[i]) {
error++;
}
}
导致
Exception in thread "main" java.lang.IllegalArgumentException: Arrays have different length
在标记的行中。
我试图找到一种API固有的方法来弥补长度上的差异,但是我找不到。我是否缺少某些东西/是否有使用API的标准方法?
我的其他想法是不使用LibsvmParser并编写一些自己的解析器 可以将这两个集合缩放到一个共同的长度,或者在数据集中引入一些虚拟变量,以表示每行中有一个共同的最大索引,但是这看起来难以置信,而且像浪费RAM,因为这可能会导致不必要的大矩阵。