如何手动交叉折叠评估 weka 中的朴素贝叶斯?
How to manually cross fold evaluate naive bayes in 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!
Training时,只输入集合class的实例。
这一行:
cModel.buildClassifier(inst);
你正在训练一个朴素贝叶斯 classifier。仅输入训练示例(!)。评估所有数据(带标签!)。如果我没记错的话,评估会根据实际标签检查预测标签。
没有class标签的200个数据点好像没什么用,有什么用?
由于你既有训练集又有测试集,你应该在训练数据上训练classifier,训练数据应该被标记,然后使用训练好的模型classify未标记的测试数据。
Classifier cModel = new NaiveBayes();
cModel.buildClassifier(trainingData);
然后,通过使用以下行,您应该能够class验证未知实例并获得预测:
double clsLabel = cModel.classifyInstance(testData.instance(0));
或者您可以使用 Evaluation class 对整个测试集进行预测。
Evaluation evaluation = new Evaluation();
evaluation.evaluateModel(cModel, testData);
您已经指出,您正试图通过获取数据的随机子集来实现您自己的交叉验证 - 有一种方法可以在评估中为您进行 k 折交叉验证 class (crossValidateModel).
Evaluation evaluation = new Evaluation(trainingData);
evaluation.crossValidateModel(cModel, trainingData, 10, new Random(1));
注意: 当您没有测试集时使用交叉验证,方法是获取训练数据的子集并将其保留在训练之外并使用它来评估性能 cross-validation.
K 折交叉验证将训练数据分成 K 个子集。它将其中一个子集放在一边,并使用剩余的子集来训练 classifier,返回到放在一边的子集来评估模型。然后它重复这个过程,直到它使用每个子集作为测试集。
我正在使用自己的词袋模型而不是 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!
Training时,只输入集合class的实例。
这一行:
cModel.buildClassifier(inst);
你正在训练一个朴素贝叶斯 classifier。仅输入训练示例(!)。评估所有数据(带标签!)。如果我没记错的话,评估会根据实际标签检查预测标签。
没有class标签的200个数据点好像没什么用,有什么用?
由于你既有训练集又有测试集,你应该在训练数据上训练classifier,训练数据应该被标记,然后使用训练好的模型classify未标记的测试数据。
Classifier cModel = new NaiveBayes();
cModel.buildClassifier(trainingData);
然后,通过使用以下行,您应该能够class验证未知实例并获得预测:
double clsLabel = cModel.classifyInstance(testData.instance(0));
或者您可以使用 Evaluation class 对整个测试集进行预测。
Evaluation evaluation = new Evaluation();
evaluation.evaluateModel(cModel, testData);
您已经指出,您正试图通过获取数据的随机子集来实现您自己的交叉验证 - 有一种方法可以在评估中为您进行 k 折交叉验证 class (crossValidateModel).
Evaluation evaluation = new Evaluation(trainingData);
evaluation.crossValidateModel(cModel, trainingData, 10, new Random(1));
注意: 当您没有测试集时使用交叉验证,方法是获取训练数据的子集并将其保留在训练之外并使用它来评估性能 cross-validation.
K 折交叉验证将训练数据分成 K 个子集。它将其中一个子集放在一边,并使用剩余的子集来训练 classifier,返回到放在一边的子集来评估模型。然后它重复这个过程,直到它使用每个子集作为测试集。