我正在尝试构建一个线性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!','?'
无论如何我可以使用当前模型构建具有相同数量属性的特征向量吗?或者除此之外还有其他解决方案。
答案 0 :(得分:1)
我怀疑这会起作用,因为SVM只能处理数字数据。如果要使用字符串,则必须使用another kernel,或使用过滤器将字符串数据转换为数字数据。
我建议你试试StringToWordVector过滤器:
将String属性转换为一组属性,表示字符串中包含的文本中出现的单词(取决于tokenizer)信息。单词集(属性)由第一批过滤(通常是训练数据)确定。
正如该过滤器的描述所示:您首先批量过滤训练数据,这将初始化过滤器。然后,如果您将过滤器应用于测试数据(甚至是新的未知数据),结果将始终与您过滤的培训数据兼容。
最大的问题是,如果您的模型必须在程序终止后继续存在。如果没有,没问题。
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
(source)
由于您的过滤器已在您的训练数据上初始化,您现在可以通过重复最后一行将其应用于任何看似未经过滤的训练集的数据集
Instances newTest2 = Filter.useFilter(test2, filter); // create another new test set
如果您想要保存模型并在多次运行应用程序时反复应用它,则应使用FilteredClassifier
。 (看看this answer,我解释了FilteredClassifier
的用法。)tl; dr:过滤器是分类器的一部分,可以与它一起序列化,保留输入数据的转换