Я использую собственный пакет словесной модели вместо 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!

2
user66875 2 Янв 2018 в 13:53

2 ответа

Лучший ответ

Поскольку у вас есть как обучающий набор, так и набор для тестирования, вы должны обучить классификатор на обучающих данных, которые должны быть помечены, а затем использовать обученную модель для классификации немаркированных тестовых данных.

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

А затем, используя следующую строку, вы сможете классифицировать неизвестный экземпляр и получить прогноз:

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

Или вы можете использовать Evaluation, чтобы делать прогнозы для всего набора тестов.

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

Вы указали, что пытаетесь реализовать свою собственную перекрестную проверку, взяв случайное подмножество данных. Существует метод, который выполняет перекрестную проверку в k раз за вас в классе Evaluation (crossValidateModel).

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

Примечание. Перекрестная проверка используется, когда у вас нет набора тестов, путем взятия подмножества данных обучения и удержания его вне обучения и использования его для оценки производительности перекрестная проверка.

K-кратная перекрестная проверка разбивает обучающие данные на K подмножеств. Он откладывает один из подмножеств и использует оставшиеся для обучения классификатора, возвращаясь к подмножеству, выделенному для оценки модели. Затем он повторяет этот процесс до тех пор, пока не будет использовать каждое подмножество в качестве тестового набора.

1
Zachary 2 Янв 2018 в 11:33

При обучении вводите только экземпляры с заданным классом.

В этой строке:

cModel.buildClassifier(inst);

Вы тренируете наивный байесовский классификатор. Введите только обучающие примеры (!). Оцените по всем данным (с этикетками!). Оценка сравнивает предсказанную метку с фактической, если я правильно помню.

200 точек данных без метки класса кажутся бесполезными, для чего они нужны?

0
kutschkem 2 Янв 2018 в 11:09