测试和训练集中不同数量的特征

Posted

技术标签:

【中文标题】测试和训练集中不同数量的特征【英文标题】:Differing number of features in test and training set 【发布时间】:2015-01-17 19:44:19 【问题描述】:

我正在尝试构建一个线性 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));

数据2 arff

@data
'This is a string!','?'

无论如何我可以构建一个与当前模型具有相同数量属性的特征向量吗?或者除此之外还有什么解决办法。

【问题讨论】:

【参考方案1】:

我怀疑这是否可行,因为 SVM 只能处理数字数据。如果要使用字符串,要么必须使用another kernel,要么使用过滤器将字符串数据转换为数值数据。

我建议你试试StringToWordVector 过滤器:

将字符串属性转换为一组属性,这些属性表示来自字符串中包含的文本的单词出现(取决于标记器)信息。单词(属性)的集合由过滤的第一批(通常是训练数据)决定。

正如该过滤器的描述所说:您首先批量过滤训练数据,这将初始化过滤器。如果您随后将过滤器应用于您的测试数据(甚至是新的未知数据),则结果将始终与您过滤的训练数据兼容。

最大的问题是您的模型是否必须在程序终止后继续存在。如果没有,没问题。

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:过滤器是分类器的一部分,可以与它一起序列化,保留输入数据的转换。

【讨论】:

我确实将字符串应用于我的训练和测试数据的词向量过滤器,从而构建了模型。但是,我需要这个模型来处理新的未知测试数据而不重建模型。无论如何,我可以将任何新的未知数据适合此功能集。 它确实适用于未知的测试数据。我编辑了我的答案,使其更加清晰。

以上是关于测试和训练集中不同数量的特征的主要内容,如果未能解决你的问题,请参考以下文章

测试和训练数据集具有不同数量的特征

5 种不同模型的低训练 (~64%) 和测试准确率 (~14%)

Sklearn PCA:用于训练和测试的组件数量不同

测试数据特征与 OneHotEncoder 的训练数据特征不匹配

使用 TF-IDF 测试和训练具有不同数量特征的集

机器学习-KNN分类器