Java - 在文本挖掘上实施机器学习方法
Java - Implementing Machine Learning methods on text mining
我有一些文本,我想通过使用 Weka 库在 Java 中实施 机器学习 方法来挖掘这些文本。为此,到目前为止我已经做了一些事情,但由于整个代码太长,我只想展示一些关键方法并了解如何训练和测试我的数据集,以及解释结果等。
仅供参考,我正在使用 Twitter4J 处理推文。
首先,我获取推文并保存在文本文件中(当然是 ARFF 格式)。然后我根据他们的情绪(正面、中性、负面)手动标记他们。基于选定的分类器,由于交叉验证,我从我的训练集中创建了测试集。最后我对它们进行了分类并打印了摘要和混淆矩阵。
这是我的分类器之一:朴素贝叶斯代码:
public static void ApplyNaiveBayes(Instances data) throws Exception {
System.out.println("Applying Naive Bayes \n");
data.setClassIndex(data.numAttributes() - 1);
StringToWordVector swv = new StringToWordVector();
swv.setInputFormat(data);
Instances dataFiltered = Filter.useFilter(data, swv);
//System.out.println("Filtered data " +dataFiltered.toString());
System.out.println("\n\nFiltered data:\n\n" + dataFiltered);
Instances[][] split = crossValidationSplit(dataFiltered, 10);
Instances[] trainingSets = split[0];
Instances[] testingSets = split[1];
NaiveBayes classifier = new NaiveBayes();
FastVector predictions = new FastVector();
classifier.buildClassifier(dataFiltered);
System.out.println("\n\nClassifier model:\n\n" + classifier);
// Test the model
for (int i = 0; i < trainingSets.length; i++) {
classifier.buildClassifier(trainingSets[i]);
// Test the model
Evaluation eTest = new Evaluation(trainingSets[i]);
eTest.evaluateModel(classifier, testingSets[i]);
// Print the result to the Weka explorer:
String strSummary = eTest.toSummaryString();
System.out.println(strSummary);
// Get the confusion matrix
double[][] cmMatrix = eTest.confusionMatrix();
for(int row_i=0; row_i<cmMatrix.length; row_i++){
for(int col_i=0; col_i<cmMatrix.length; col_i++){
System.out.print(cmMatrix[row_i][col_i]);
System.out.print("|");
}
System.out.println();
}
}
}
仅供参考,crossValidationSplit 方法在这里:
public static Instances[][] crossValidationSplit(Instances data, int
numberOfFolds) {
Instances[][] split = new Instances[2][numberOfFolds];
for (int i = 0; i < numberOfFolds; i++) {
split[0][i] = data.trainCV(numberOfFolds, i);
split[1][i] = data.testCV(numberOfFolds, i);
}
return split;
}
最后,我得到了 10 个不同的结果(因为 k=10)。其中之一是:
Correctly Classified Instances 4 36.3636 %
Incorrectly Classified Instances 7 63.6364 %
Kappa statistic 0.0723
Mean absolute error 0.427
Root mean squared error 0.5922
Relative absolute error 93.4946 %
Root relative squared error 116.5458 %
Total Number of Instances 11
2.0|0.0|1.0|
1.0|1.0|2.0|
3.0|0.0|1.0|
那么,我该如何解释结果?你认为我在训练和测试集方面做得对吗?
我想获得给定文本文件的情绪百分比(正面、中性、负面)。如何从这些结果中推断出我的需求?
感谢阅读...
你做了一些分类。默认情况下,Weka 始终从您的训练数据集中获取最后一个 column/attribute,并尝试从所有其他属性中预测它的值。 (除非你告诉它使用不同的)。
在这里,我们无法判断这对您的情况是否有意义。可能不会。 (您没有向我们展示任何数据)。
因此,您执行的 Naive-Bayes 分类只有在最后一列已包含值为正、中性、负的情绪分类器时才有用,该分类器由先前预处理步骤中的某种无监督学习方法创建。 Weka 的分类算法不会为您推断这一点。
现在你所做的结果与情感分析无关。我也帮不了你。
顺便说一下,您只有 11 个实例。为什么不自己分类?
很遗憾,您的代码有点混乱。
首先,你在你的完整集合上训练你的模型:
classifier.buildClassifier(dataFiltered);
然后在 for 循环中重新训练模型:
for (int i = 0; i < trainingSets.length; i++) {
classifier.buildClassifier(trainingSets[i]);
...
}
比你计算的混乱mtx还多。我觉得没必要。
在我看来,您需要应用 Evaluation.crossValidateModel()
方法,如下所示:
//set the class index
dataFiltered.setClassIndex(dataFiltered.numAttributes() - 1);
//build a model -- choose a classifier as you want
classifier.buildClassifier(dataFiltered);
Evaluation eval = new Evaluation(dataFiltered);
eval.crossValidateModel(classifier, dataFiltered, 10, new Random(1));
//print stats -- do not require to calculate confusion mtx, weka do it!
System.out.println(classifier);
System.out.println(eval.toSummaryString());
System.out.println(eval.toMatrixString());
System.out.println(eval.toClassDetailsString());
我有一些文本,我想通过使用 Weka 库在 Java 中实施 机器学习 方法来挖掘这些文本。为此,到目前为止我已经做了一些事情,但由于整个代码太长,我只想展示一些关键方法并了解如何训练和测试我的数据集,以及解释结果等。
仅供参考,我正在使用 Twitter4J 处理推文。
首先,我获取推文并保存在文本文件中(当然是 ARFF 格式)。然后我根据他们的情绪(正面、中性、负面)手动标记他们。基于选定的分类器,由于交叉验证,我从我的训练集中创建了测试集。最后我对它们进行了分类并打印了摘要和混淆矩阵。
这是我的分类器之一:朴素贝叶斯代码:
public static void ApplyNaiveBayes(Instances data) throws Exception {
System.out.println("Applying Naive Bayes \n");
data.setClassIndex(data.numAttributes() - 1);
StringToWordVector swv = new StringToWordVector();
swv.setInputFormat(data);
Instances dataFiltered = Filter.useFilter(data, swv);
//System.out.println("Filtered data " +dataFiltered.toString());
System.out.println("\n\nFiltered data:\n\n" + dataFiltered);
Instances[][] split = crossValidationSplit(dataFiltered, 10);
Instances[] trainingSets = split[0];
Instances[] testingSets = split[1];
NaiveBayes classifier = new NaiveBayes();
FastVector predictions = new FastVector();
classifier.buildClassifier(dataFiltered);
System.out.println("\n\nClassifier model:\n\n" + classifier);
// Test the model
for (int i = 0; i < trainingSets.length; i++) {
classifier.buildClassifier(trainingSets[i]);
// Test the model
Evaluation eTest = new Evaluation(trainingSets[i]);
eTest.evaluateModel(classifier, testingSets[i]);
// Print the result to the Weka explorer:
String strSummary = eTest.toSummaryString();
System.out.println(strSummary);
// Get the confusion matrix
double[][] cmMatrix = eTest.confusionMatrix();
for(int row_i=0; row_i<cmMatrix.length; row_i++){
for(int col_i=0; col_i<cmMatrix.length; col_i++){
System.out.print(cmMatrix[row_i][col_i]);
System.out.print("|");
}
System.out.println();
}
}
}
仅供参考,crossValidationSplit 方法在这里:
public static Instances[][] crossValidationSplit(Instances data, int
numberOfFolds) {
Instances[][] split = new Instances[2][numberOfFolds];
for (int i = 0; i < numberOfFolds; i++) {
split[0][i] = data.trainCV(numberOfFolds, i);
split[1][i] = data.testCV(numberOfFolds, i);
}
return split;
}
最后,我得到了 10 个不同的结果(因为 k=10)。其中之一是:
Correctly Classified Instances 4 36.3636 %
Incorrectly Classified Instances 7 63.6364 %
Kappa statistic 0.0723
Mean absolute error 0.427
Root mean squared error 0.5922
Relative absolute error 93.4946 %
Root relative squared error 116.5458 %
Total Number of Instances 11
2.0|0.0|1.0|
1.0|1.0|2.0|
3.0|0.0|1.0|
那么,我该如何解释结果?你认为我在训练和测试集方面做得对吗? 我想获得给定文本文件的情绪百分比(正面、中性、负面)。如何从这些结果中推断出我的需求? 感谢阅读...
你做了一些分类。默认情况下,Weka 始终从您的训练数据集中获取最后一个 column/attribute,并尝试从所有其他属性中预测它的值。 (除非你告诉它使用不同的)。
在这里,我们无法判断这对您的情况是否有意义。可能不会。 (您没有向我们展示任何数据)。
因此,您执行的 Naive-Bayes 分类只有在最后一列已包含值为正、中性、负的情绪分类器时才有用,该分类器由先前预处理步骤中的某种无监督学习方法创建。 Weka 的分类算法不会为您推断这一点。
现在你所做的结果与情感分析无关。我也帮不了你。
顺便说一下,您只有 11 个实例。为什么不自己分类?
很遗憾,您的代码有点混乱。
首先,你在你的完整集合上训练你的模型:
classifier.buildClassifier(dataFiltered);
然后在 for 循环中重新训练模型:
for (int i = 0; i < trainingSets.length; i++) {
classifier.buildClassifier(trainingSets[i]);
...
}
比你计算的混乱mtx还多。我觉得没必要。
在我看来,您需要应用 Evaluation.crossValidateModel()
方法,如下所示:
//set the class index
dataFiltered.setClassIndex(dataFiltered.numAttributes() - 1);
//build a model -- choose a classifier as you want
classifier.buildClassifier(dataFiltered);
Evaluation eval = new Evaluation(dataFiltered);
eval.crossValidateModel(classifier, dataFiltered, 10, new Random(1));
//print stats -- do not require to calculate confusion mtx, weka do it!
System.out.println(classifier);
System.out.println(eval.toSummaryString());
System.out.println(eval.toMatrixString());
System.out.println(eval.toClassDetailsString());