【问题标题】:How to manually cross fold evaluate naive bayes in weka?如何在weka中手动交叉折叠评估朴素贝叶斯?
【发布时间】:2018-01-02 19:33:08
【问题描述】:

我正在使用自己的词袋模型而不是 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 会自动尝试确定类属性没有值的实例的类属性。但相反,它告诉我weka.filters.supervised.attribute.Discretize: Cannot handle missing class values!

【问题讨论】:

  • 您想训练模型然后在未知数据上对其进行评估?交叉折叠验证需要一个已知的类标签,因为您无法在未知数据上进行训练。
  • 嗯,但是如果我为测试数据分配一个类标签,wekas 评估如何区分测试数据和训练数据?请记住,我不能使用在 CrossFold 评估中内置的 wekas
  • 如果你有一个测试集,无论如何你都不想使用交叉折叠验证 - What is cross-fold validation。您是否能够毫无问题地训练模型

标签: java weka


【解决方案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 折交叉验证 (crossValidateModel) .

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

注意:当您没有测试集时使用交叉验证,方法是获取训练数据的子集并将其排除在训练之外并使用它来评估性能cross-validation

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

【讨论】:

  • 我去试试,谢谢。 PS。我实际上也没有特定的测试集;我只使用 2000 条带标签评论的 1/10 作为测试集,所以基本上我正在尝试构建自己的 k 折交叉验证。
  • @user66875 那将是 10% 的交叉验证。 k-fold 交叉验证将分割成 k 个子集,并使用每个分割的子集作为测试集,而其他 k-1 个集用于评估(我会将其添加到答案中)。
  • 关于您的注释:不幸的是,我不能让 weka 对数据进行分区,因为我已经用我自己的评论分区构建了我的 BagOfWord 模型。那是我最初的问题。如果我用所有 2000 条评论的单词出现 (BagOfWord) 来构建字典,这对我来说似乎是某种欺骗。我认为模型不应该了解 200 条测试评论的内容。或者也许我误解了什么。
  • @user66875 这很公平。 k 折交叉验证通常会重新应用用于为每次迭代制作词袋的过滤器。我只是注意到差异,如果传统交叉验证提供的性能是合适的,那么您使用的方法应该没问题。不过,由于这是一个学校项目,我高度怀疑您采用的方法已经过火了。
【解决方案2】:

Training 时,只输入设置类的实例。

在这一行:

cModel.buildClassifier(inst);

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

没有标签类的200个数据点看起来没什么用,它们是干什么用的?

【讨论】:

  • 针对所有数据进行评估,或者只评估测试数据。
  • 好的,所以我只使用训练实例构建分类器,然后将Evaluation eTest = new Evaluation(inst); eTest.evaluateModel(cModel, inst); 用于所有 2000?
  • @user66875 现在我考虑了一下,可能是 200 个测试示例,而不是 2000 个完整集。假设你也有这些标签。
猜你喜欢
  • 2013-04-13
  • 2014-11-03
  • 2013-04-13
  • 2012-04-09
  • 2019-11-26
  • 2014-11-27
  • 2015-09-24
  • 2016-02-05
  • 2012-11-22
相关资源
最近更新 更多