SVM 加载的训练模型的准确性明显降低;我们还需要保存 TokenCountVectorizer 吗?
SVM loaded training model is significantly less accurate; do we need to save TokenCountVectorizer too?
在 Liblinear 或 Libsvm 上,我加载数据,将其拆分为训练和测试,这使我获得了 95% 的准确率。此时,我保存模型和标签以备后用。
现在的问题是,当我将保存的数据加载到我的模型中并测试预测方法时 即使在训练它的相同数据上,准确度也下降到 53% !
用于构建模型的代码:
$vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer());
$tfIdfTransformer = new TfIdfTransformer();
$vectorizer->fit($samples);
$vectorizer->transform($samples);
$tfIdfTransformer->fit($samples);
$tfIdfTransformer->transform($samples);
$dataset = new ArrayDataset($samples, $labels);
$randomSplit = new StratifiedRandomSplit($dataset, 0.1);
$classifier = new SVC(
Kernel::LINEAR, // $kernel
8.0, // $cost
3, // $degree
null, // $gamma
0.0, // $coef0
0.001, // $tolerance
100, // $cacheSize
true, // $shrinking
true // $probabilityEstimates, set to true
);
$classifier->train($randomSplit->getTrainSamples(), $randomSplit->getTrainLabels());
$classifier->save($modelFile); // save the model and lables (everything in the classifier)
$predictedLabels = $classifier->predict($randomSplit->getTestSamples());
echo 'Accuracy: '.Accuracy::score($randomSplit->getTestLabels(), $predictedLabels); // this gives 0.95
用于预测新数据的代码:
$classifier = new SVC();
$classifier->load($modelFile);
$vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer());
$tfIdfTransformer = new TfIdfTransformer();
$vectorizer->fit($samples);
$vectorizer->transform($samples);
$tfIdfTransformer->fit($samples);
$tfIdfTransformer->transform($samples);
$dataset = new ArrayDataset($samples, $labels);
$predictedLabels = $classifier->predict($samples);
echo 'Accuracy: '.Accuracy::score($labels, $predictedLabels); // this gives 0.53
注意: $samples 和 $labels 对于这两种情况都是相同的 - 只有在测试中它们是 100,而在训练中它们是 400 个实例。
我看到的唯一区别是,在训练期间,我对训练数据和测试数据使用了相同的矢量化器和变换器,而在测试期间,我使用了新的矢量化器和变换器。
那么,我是否也应该以某种方式保存矢量化器和变换器并在以后重新加载它们?
是的。
用于测试或生产的数据必须按照与初始训练相同的方式进行转换。
因此,您需要使用相同的特征、相同的缩放机制和相同的转换过程来获得更好的预测结果。
在 Liblinear 或 Libsvm 上,我加载数据,将其拆分为训练和测试,这使我获得了 95% 的准确率。此时,我保存模型和标签以备后用。
现在的问题是,当我将保存的数据加载到我的模型中并测试预测方法时 即使在训练它的相同数据上,准确度也下降到 53% !
用于构建模型的代码:
$vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer());
$tfIdfTransformer = new TfIdfTransformer();
$vectorizer->fit($samples);
$vectorizer->transform($samples);
$tfIdfTransformer->fit($samples);
$tfIdfTransformer->transform($samples);
$dataset = new ArrayDataset($samples, $labels);
$randomSplit = new StratifiedRandomSplit($dataset, 0.1);
$classifier = new SVC(
Kernel::LINEAR, // $kernel
8.0, // $cost
3, // $degree
null, // $gamma
0.0, // $coef0
0.001, // $tolerance
100, // $cacheSize
true, // $shrinking
true // $probabilityEstimates, set to true
);
$classifier->train($randomSplit->getTrainSamples(), $randomSplit->getTrainLabels());
$classifier->save($modelFile); // save the model and lables (everything in the classifier)
$predictedLabels = $classifier->predict($randomSplit->getTestSamples());
echo 'Accuracy: '.Accuracy::score($randomSplit->getTestLabels(), $predictedLabels); // this gives 0.95
用于预测新数据的代码:
$classifier = new SVC();
$classifier->load($modelFile);
$vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer());
$tfIdfTransformer = new TfIdfTransformer();
$vectorizer->fit($samples);
$vectorizer->transform($samples);
$tfIdfTransformer->fit($samples);
$tfIdfTransformer->transform($samples);
$dataset = new ArrayDataset($samples, $labels);
$predictedLabels = $classifier->predict($samples);
echo 'Accuracy: '.Accuracy::score($labels, $predictedLabels); // this gives 0.53
注意: $samples 和 $labels 对于这两种情况都是相同的 - 只有在测试中它们是 100,而在训练中它们是 400 个实例。
我看到的唯一区别是,在训练期间,我对训练数据和测试数据使用了相同的矢量化器和变换器,而在测试期间,我使用了新的矢量化器和变换器。
那么,我是否也应该以某种方式保存矢量化器和变换器并在以后重新加载它们?
是的。
用于测试或生产的数据必须按照与初始训练相同的方式进行转换。
因此,您需要使用相同的特征、相同的缩放机制和相同的转换过程来获得更好的预测结果。