我正在使用自己的单词模型而不是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!
由于您同时拥有训练集和测试集,您应该在训练数据上训练分类器,应该对其进行标记,然后使用训练的模型对未标记的测试数据进行分类。
Classifier cModel = new NaiveBayes();
cModel.buildClassifier(trainingData);
然后,通过使用以下行,您应该能够对未知实例进行分类并获得预测:
double clsLabel = cModel.classifyInstance(testData.instance(0));
或者您可以使用Evaluation类对整个测试集进行预测。
Evaluation evaluation = new Evaluation();
evaluation.evaluateModel(cModel, testData);
您已经指出,您正在尝试通过获取数据的随机子集来实现自己的交叉验证 - 有一种方法可以在评估类(crossValidateModel)中为您进行k折叠交叉验证。
Evaluation evaluation = new Evaluation(trainingData);
evaluation.crossValidateModel(cModel, trainingData, 10, new Random(1));
注意:当您没有测试集时,使用交叉验证是通过获取训练数据的一部分并将其保留在训练之外并使用它来评估性能cross-validation。
K折交叉验证将训练数据分成K个子集。它将一个子集放在一边,并使用剩余的子集来训练分类器,返回预留的子集来评估模型。然后重复此过程,直到它将每个子集用作测试集。
训练时,仅输入设置类的实例。
在这一行:
cModel.buildClassifier(inst);
你正在训练一个天真的贝叶斯分类器。仅输入训练样例(!)。评估所有数据(带标签!)。如果我没记错的话,评估会根据实际标签检查预测的标签。
没有类标签的200个数据点似乎没用,它们用于什么?