【问题标题】:Weka classification and predicted classWeka分类和预测类
【发布时间】:2016-01-06 12:30:59
【问题描述】:

我正在尝试使用 Weka 对未标记的字符串进行分类,我不是数据挖掘方面的专家,所以我一直在为不同的术语而苦苦挣扎。我正在做的是在运行 M5Rules 分类器后提供训练数据并设置未标记的字符串,我实际上得到了一个输出,但我不知道这是什么意思:

run:
{17 1,35 1,64 1,135 1,205 1,214 1,215 1,284 1,288 1,309 1,343 1,461 1,493 1,500 1,552 1,806 -0.038168} | -0.03816793850062397
-0.03816793850062397 -> 

Results
======

Correlation coefficient                  0     
Mean absolute error                      0     
Root mean squared error                  0     
Relative absolute error                  0      %
Root relative squared error              0      %
Total Number of Instances                1     

BUILD SUCCESSFUL (total time: 1 second)

源码如下:

  public Categorizer(){

    try{

        //***  READ ARRF FILES *///////////////////////////////////////////////////////
        //BufferedReader trainReader = new BufferedReader(new FileReader("c:/Users/Yehia A.Salam/Desktop/dd/training-data.arff"));//File with text examples
        //BufferedReader classifyReader = new BufferedReader(new FileReader("c:/Users/Yehia A.Salam/Desktop/dd/test-data.arff"));//File with text to classify

        // Create trainning data instance
        TextDirectoryLoader loader = new TextDirectoryLoader();
        loader.setDirectory(new File("c:/Users/Yehia A.Salam/Desktop/dd/training-data"));
        Instances dataRaw = loader.getDataSet();

        StringToWordVector filter = new StringToWordVector();
        filter.setInputFormat(dataRaw);
        Instances dataTraining = Filter.useFilter(dataRaw, filter);
        dataTraining.setClassIndex(dataRaw.numAttributes() - 1);

        // Create test data instances
        loader.setDirectory(new File("c:/Users/Yehia A.Salam/Desktop/dd/test-data"));
        dataRaw = loader.getDataSet();
        Instances dataTest = Filter.useFilter(dataRaw, filter);
        dataTest.setClassIndex(dataTest.numAttributes() - 1);


        // Classify
        FilteredClassifier model = new FilteredClassifier();
        model.setFilter(new StringToWordVector());
        model.setClassifier(new M5Rules());
        model.buildClassifier(dataTraining);

        for (int i = 0; i < dataTest.numInstances(); i++) {
             dataTest.instance(i).setClassMissing();
             double cls = model.classifyInstance(dataTest.instance(i));
             dataTest.instance(i).setClassValue(cls);
             System.out.println(dataTest.instance(i).toString() + " | " + cls);
             System.out.println(cls + " -> " + dataTest.instance(i).classAttribute().value((int) cls));

            // evaluate classifier and print some statistics
             Evaluation eval = new Evaluation(dataTraining);
             eval.evaluateModelOnce(cls, dataTest.instance(i));
             System.out.println(eval.toSummaryString("\nResults\n======\n", false));
        }

    }
    catch(FileNotFoundException e){

      System.err.println(e.getMessage());
    }
    catch(IOException i){

      System.err.println(i.getMessage());
    }
     catch(Exception o){

      System.err.println(o.getMessage());
     }
  }

最后是几张截图,以防我在文件夹层次结构中出错:

【问题讨论】:

  • 我想帮助您,但缺少重要信息。你的数据到底是什么样的?有什么特点? (我猜只是字符串。)可能的标签是什么?您的输出表明您只有一个实例。我还认为您不应该从测试数据中删除类标签,因为没有它您将无法评估分类器的性能。
  • @Sentry 好的,基本上训练和测试数据都是描述交易的两三行句子,例如travel-1.txt 的内容是“购买我们的 L.E 1100 电子优惠券(原价 L.E 1850)并在壮观的 MinaMark 度假村以 HB 为基础在双人标准间获得 2 晚 3 晚住宿”,所以我认为这是唯一的功能。目前可能的标签是[旅行或健康]。我只是想预测一笔交易作为开始,所以我只尝试一个实例。

标签: weka


【解决方案1】:

tl;博士:

  • 您将类索引设置为随机特征
  • 您必须使用分类器,而不是回归算法

问题在于如何初始化数据集。虽然 weka 通常将类放在最后一列,但 TextDirectoryLoader 不会。其实不用手动设置类索引,已经设置好了,去掉那几行

dataTraining.setClassIndex(dataRaw.numAttributes() - 1);
dataTest.setClassIndex(dataTest.numAttributes() - 1);

(反正第一行是错的,因为你使用的是原始数据集中的属性数量,而是选择了已经过滤的数据集的列。)

如果你然后运行你的代码,你会得到这个:

weka.classifiers.functions.LinearRegression: Cannot handle binary class!

正如我已经猜到的,M5Rules 不是分类器,而是用于回归。如果你使用像J48RandomForest 这样的分类器,你会得到更合理的输出。换行就行了

model.setClassifier(new M5Rules());

model.setClassifier(new RandomForest());

至于你的输出,我是这样理解的:

{17 1,35 1,64 1,135 1,205 1,214 1,215 1,284 1,288 1,309 1,343 1,461 1,493 1,500 1,552 1,806 -0.038168} | -0.03816793850062397
-0.03816793850062397 -> 

是行的结果

System.out.println(dataTest.instance(i).toString() + " | " + cls);
System.out.println(cls + " -> " + dataTest.instance(i).classAttribute().value((int) cls));

因此,您会看到实例的功能序列化为 sparse ARFF,后跟 | 和类。

通常,该类应该是一个整数,但从M5Rules 的文档中我知道它是回归问题的分类器,所以你不会得到离散类,而是连续值,在你的情况下-0.03816793850062397

由于您(错误地)将数字特征设置为类标签,M5Rules 没有抱怨并给您一个输出。如果您使用实际的分类器,您将获得标签“健康”或“旅行”。

其余的是关于分类器性能的标准统计数据,但它们仅对一个分类器实例毫无用处。看起来一个样本被正确分类了,所以所有的错误都是零。

Correlation coefficient                  0     
Mean absolute error                      0     
Root mean squared error                  0     
Relative absolute error                  0      %
Root relative squared error              0      %
Total Number of Instances                1     

【讨论】:

  • 但是 M5rules 是在这里使用的正确算法吗?取决于我上面的问题?
  • @YehiaA.Salam 好吧,你想做什么?您可以使用任何分类器,BayesNet、SVM、kNN、J48 ...
  • @YehiaA.Salam 你能试试另一种算法,看看效果是否更好?
  • @YehiaA.Salam 啊,我找到了问题的原因,现在将更新我的答案。
【解决方案2】:

以防万一其他人在使用 M5P 时遇到同样的错误,请尝试查看 Arff 是否只是一个标题或空。

否则试试

model.buildClassifier(....) 

而不是

model.setClassifier(....); 

这为我解决了。

【讨论】:

    猜你喜欢
    • 2013-10-17
    • 2016-02-25
    • 2013-09-25
    • 2016-04-04
    • 2013-12-25
    • 2013-12-14
    • 2017-01-09
    • 2013-04-05
    • 2016-01-16
    相关资源
    最近更新 更多