如何在 Weka 中使用新数据创建的模型

How to use created model with new data in Weka

我正在尝试对 weka 进行一些测试,希望有人能帮助我,我可以说清楚。

第 1 步:标记我的数据

@attribute text string
@attribute @@class@@ {derrota,empate,win}

@data
'O Grêmio perdeu para o Cruzeiro por 1 a 0',derrota
'O Grêmio venceu o Palmeiras em um grande jogo de futebol, nesta quarta-feira na Arena',vitoria

第 2 步:在标记化数据上构建模型

加载后,我应用了 StringToWordVector。应用此过滤器后,我保存了一个新的 arff 文件,其中包含单词 tokenized。有点像..

@attribute @@class@@ {derrota,vitoria,win}
@attribute o numeric
@attribute grêmio numeric
@attribute perdeu numeric
@attribute venceu numeric
@ and so on .....

@data
{0 derrota, 1 1, 2 1, 3 1, 4 0, ...}
{0 vitoria, 1 1, 2 1, 3 0, 4 1, ...}

好的!现在基于这个 arff 我建立了我的分类器模型并保存它。

第 3 步:使用 "simulated new data"

进行测试

如果我想用 "simulated new data" 测试我的模型,我实际上正在做的是编辑最后一个 arff 并制作一行

{0 ?, 1 1, 2 1, 3 1, 4 0, ...}

第 4 步(我的问题):如何使用真正的新数据进行测试

到目前为止一切顺利。我的问题是当我需要将此模型与 'really' 新数据一起使用时。 例如,如果我有一个带有 "O Grêmio caiu diante do Palmeiras" 的字符串。我的模型中有 4 个不存在的新词和 2 个存在的新词。

我如何使用可以适合我的模型的新数据创建一个 arff 文件? (好吧,我知道这 4 个新词不会出现,但我该如何处理它?)

提供不同的测试数据后出现以下信息

如果您以编程方式使用 Weka,那么您可以很容易地做到这一点。

  • 创建你的训练文件(例如training.arff)
  • 从训练文件创建实例。 Instances trainingData = ..
  • 使用 StringToWordVector 将字符串属性转换为数字表示形式:

示例代码:

    StringToWordVector() filter = new StringToWordVector(); 
    filter.setWordsToKeep(1000000);
    if(useIdf){
        filter.setIDFTransform(true);
    }
    filter.setTFTransform(true);
    filter.setLowerCaseTokens(true);
    filter.setOutputWordCounts(true);
    filter.setMinTermFreq(minTermFreq);
    filter.setNormalizeDocLength(new SelectedTag(StringToWordVector.FILTER_NORMALIZE_ALL,StringToWordVector.TAGS_FILTER));
    NGramTokenizer t = new NGramTokenizer();
    t.setNGramMaxSize(maxGrams);
    t.setNGramMinSize(minGrams);    
    filter.setTokenizer(t);  
    WordsFromFile stopwords = new WordsFromFile();
    stopwords.setStopwords(new File("data/stopwords/stopwords.txt"));
    filter.setStopwordsHandler(stopwords);
    if (useStemmer){
        Stemmer s = new /*Iterated*/LovinsStemmer();
        filter.setStemmer(s);
    }
    filter.setInputFormat(trainingData);
  • 将过滤器应用于训练数据:trainingData = Filter.useFilter(trainingData, filter);

  • Select 创建模型的分类器

LibLinear 分类器的示例代码

        Classifier cls = null;
        LibLINEAR liblinear = new LibLINEAR();
        liblinear.setSVMType(new SelectedTag(0, LibLINEAR.TAGS_SVMTYPE));
        liblinear.setProbabilityEstimates(true);
        // liblinear.setBias(1); // default value
        cls = liblinear;
        cls.buildClassifier(trainingData);
  • 保存模型

示例代码

    System.out.println("Saving the model...");
    ObjectOutputStream oos;
    oos = new ObjectOutputStream(new FileOutputStream(path+"mymodel.model"));
    oos.writeObject(cls);
    oos.flush();
    oos.close();
  • 创建测试文件(例如testing.arff)

  • 从训练文件创建实例:Instances testingData=...

  • 加载分类器

示例代码

Classifier myCls = (Classifier) weka.core.SerializationHelper.read(path+"mymodel.model");
  • 使用与上面相同的 StringToWordVector 过滤器或为 testingData 创建一个新过滤器,但请记住为该命令使用 trainingData:filter.setInputFormat(trainingData); 这将保持训练集的格式,不会添加不在训练集中的单词。

  • 将过滤器应用于测试数据:testingData = Filter.useFilter(testingData, filter);

  • 分类!

示例代码

 for (int j = 0; j < testingData.numInstances(); j++) {
    double res = myCls.classifyInstance(testingData.get(j));
 }

  1. 不确定这是否可以通过 GUI 完成。
  2. 保存和加载步骤是可选的。

编辑:在深入研究 Weka GUI 之后,我认为可以做到这一点。在 classify 选项卡中,在 Supply test set 字段中设置您的测试集。之后你的集合通常应该是不兼容的。要修复此问题,请在以下对话框中单击“是”

一切顺利。