如何手动交叉折叠评估weka中的朴素贝叶斯?

时间:2018-01-02 10:53:42

标签: java weka

我正在使用自己的单词模型而不是wekas StringToWordVector(结果是一个错误,但由于它只是一个学校项目,我想用我的方法完成它),所以我不能使用它CrossFoldEvaluation,因为我的BoW词典也包含训练数据的单词。

for (int n = 0; n < folds; n++) {
   List<String> allData = getAllReviews(); // 2000 reviews
   List<String> trainingData = getTrainingReviews(n, folds); // random 1800 reviews
   List<String> testData = getTestReviews(n, folds); // random 200 reviews

   bagOfWordsModel.train(trainingData);  //  builds a vocabulary of 1800 training reviews
   Instances inst = bagOfWordsModel.vectorize(allData); // returns 1800 instances with the class attribute set to positive or negative, and 200 without 

   // todo: evaluate
   Classifier cModel = (Classifier) new NaiveBayes();
   cModel.buildClassifier(inst);

   Evaluation eTest = new Evaluation(inst);
   eTest.evaluateModel(cModel, inst);

   // print results
   String strSummary = eTest.toSummaryString();
   System.out.println(strSummary);
}

我现在如何评价这个?我想,weka会自动尝试确定没有class属性值的实例的class属性。但相反,它告诉我weka.filters.supervised.attribute.Discretize: Cannot handle missing class values!

2 个答案:

答案 0 :(得分:1)

由于您同时拥有训练集和测试集,因此您应该在训练数据上训练分类器(应该标记),然后使用训练的模型对未标记的测试数据进行分类。

Classifier cModel = new NaiveBayes();
cModel.buildClassifier(trainingData);

然后,通过使用以下行,您应该能够对未知实例进行分类并获得预测:

double clsLabel = cModel.classifyInstance(testData.instance(0));

或者您可以使用Evaluation类对整个测试集进行预测。

Evaluation evaluation = new Evaluation();
evaluation.evaluateModel(cModel, testData);

您已经指出您正在尝试通过获取数据的随机子集来实现您自己的交叉验证 - 有一种方法可以在评估类中对您进行k次交叉验证({{3} })。

 Evaluation evaluation = new Evaluation(trainingData);
 evaluation.crossValidateModel(cModel, trainingData, 10, new Random(1));

注意:如果没有测试集,则会使用交叉验证,方法是获取一部分培训数据并将其保留在培训数据之外并使用它来评估性能{{3} }。

K折叠交叉验证将训练数据分成K个子集。它将一个子集放在一边,并使用剩余的子集来训练分类器,返回预留的子集来评估模型。然后重复此过程,直到它将每个子集用作测试集。

答案 1 :(得分:0)

训练时,仅输入设置类的实例。

在这一行:

cModel.buildClassifier(inst);

你正在训练一个天真的贝叶斯分类器。仅输入训练样例(!)。评估所有数据(带标签!)。如果我没记错的话,评估会根据实际标签检查预测的标签。

没有类标签的200个数据点似乎没用,它们用于什么?