Weka分类和预测类

时间:2013-03-07 19:30:59

标签: weka

我正在尝试使用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());
     }
  }

最后是一些屏幕截图,以防我在文件夹层次结构中出错: unlabeled string training data for the health class training data for the travel class

2 个答案:

答案 0 :(得分:1)

TL; DR:

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

问题是如何初始化数据集。尽管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的文档中我得到它是回归问题的分类器,所以你不会得到离散类,而是连续的值,在你的情况下{ {1}}

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

其余的是关于分类器性能的标准统计信息,但它们对于一个分类器实例来说几乎没用。看起来一个样本被正确分类,因此所有错误都为零。

-0.03816793850062397

答案 1 :(得分:0)

以防其他人在M5P上遇到同样的错误,试着看看Arff只是一个标题还是空的。

否则尝试

String json = getPrefs().getUserJson();

而不是

model.buildClassifier(....) 

这解决了我。