我正在尝试构建一个线性 svm 分类器来对未知的测试数据进行分类。
但是,由于文本文档没有固定长度,如何确保新文档具有相同的特征长度?
Src 和 Dest 在属性 # 上有所不同:2 != 1484
LibSVM classifier = new LibSVM();
classifier.setKernelType(new SelectedTag(LibSVM.KERNELTYPE_LINEAR, LibSVM.TAGS_KERNELTYPE));
classifier.buildClassifier(data1);
System.out.println("done");
data2.setClassIndex(data2.numAttributes() - 1);
double res = classifier.classifyInstance(data2.instance(0));
Data2 arff
@data
'This is a string!','?'
无论如何,我可以构建具有当前模型相同数量属性的特征向量吗?或者除此之外还有其他解决方案。
我怀疑这是否有效,因为 SVM 只能处理数字数据。如果要使用字符串,则必须使用另一个内核,或使用筛选器将字符串数据转换为数字数据。
我建议你尝试StringToWordVector过滤器:
将 String 属性转换为一组属性,这些属性表示字符串中包含的文本中的单词出现次数(取决于分词器)信息。单词(属性)集由第一批筛选(通常是训练数据)确定。
正如该过滤器的描述所说:首先批量筛选训练数据,这将初始化过滤器。如果随后将筛选器应用于测试数据(甚至是新的未知数据),则结果将始终与筛选后的训练数据兼容。
最大的问题是你的模型是否必须在程序终止后幸存下来。如果没有,没问题。
Instances train = ... // from somewhere
Instances test = ... // from somewhere
Standardize filter = new Standardize();
filter.setInputFormat(train); // initializing the filter once with training set
Instances newTrain = Filter.useFilter(train, filter); // configures the Filter based on train instances and returns filtered instances
Instances newTest = Filter.useFilter(test, filter); // create new test set
(来源)
由于您的过滤器已在训练数据上初始化,您现在可以将其应用于任何看起来像未过滤训练集的数据集,方法是重复最后一行
Instances newTest2 = Filter.useFilter(test2, filter); // create another new test set
如果要保存模型并在应用程序的多次运行期间反复应用它,则应使用FilteredClassifier
。(看看这个答案,我解释了FilteredClassifier
的用法。tl;dr:过滤器是分类器的一部分,可以随之序列化,保留对输入数据的转换。