【问题标题】:Java - Implementing Machine Learning methods on text miningJava - 在文本挖掘中实现机器学习方法
【发布时间】:2016-01-06 22:09:23
【问题描述】:

我有一些文本,我想通过使用 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|

那么,我该如何解释结果?你认为我在训练和测试集方面做得对吗? 我想获得给定文本文件的情绪百分比(正面、中性、负面)。如何从这些结果中推断出我的需求? 感谢阅读……

【问题讨论】:

    标签: java machine-learning weka text-mining sentiment-analysis


    【解决方案1】:

    不幸的是,您的代码有点混乱。

    首先,你在你的整个集合上训练你的模型:

    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());

    【讨论】:

    • 感谢代码,我很容易获得了类详细信息和类混淆矩阵。但是,我想问一下我做得对吗?因为一开始,我手动将我的数据集标记为正面、负面或中性。最后,我想通过图形显示 Swing 中每个分类器(其他分类器是 KNN 和 C4.5)的准确性
    • 这取决于你想要什么。 :) 你的目标是什么?如果要训练 ML 模型,则需要手动标记的数据库。正如你上面提到的,你做到了,但我认为有很多标记的 twitter 数据库可用,所以我认为没有必要。另一方面,要训练 ML 模型,您需要更大的数据集。
    • 知道了 :) 另一方面,从结果 a b c
    • 我还想知道您发布的代码会自动分离训练集和测试集并在此之后进行分类?如果是,如何?它分为哪一部分?如果你能回答我很感激谢谢:)
    • 是的,它分为测试集和训练集。您可以观看该方法的源代码,并检查它是如何实现的。 ;) 它与您的方法相似。
    【解决方案2】:

    你做了一些分类。默认情况下,Weka 总是从您的训练数据集中获取最后一列/属性,并尝试从所有其他属性中预测其值。 (除非你告诉它使用不同的)。

    在这里,我们无法判断这对您的情况是否有意义。可能不是。 (您没有向我们展示任何数据)。

    因此,您执行的朴素贝叶斯分类只有在最后一列已经包含一个情绪分类器(其值为正、中性、负)时才有用,该分类器是由前一个预处理步骤中的某种无监督学习方法创建的。 Weka 的分类算法不会为您推断这一点。

    现在你所做的结果与情绪分析无关。我也不能为你做这件事。

    顺便说一句,您只有 11 个实例。为什么不自己分类呢?

    【讨论】:

    • 那么,我怎样才能推断出这个结果呢?我的数据由推文(字符串)及其手写的情绪组成。我有 100-200 条推文,在那个例子中我使用了 10 个交叉验证,这就是它显示 11 个实例的原因。它可以改变。
    • 这很复杂,推文也很混乱。我想查找一些东西,但找不到我正在寻找的链接 - 也许,这有助于datascience.stackexchange.com/questions/9458/…
    猜你喜欢
    • 2017-03-20
    • 2010-12-22
    • 2011-11-22
    • 2013-04-01
    • 2011-03-25
    • 2011-10-29
    • 2021-12-09
    • 1970-01-01
    • 2014-10-24
    相关资源
    最近更新 更多