使用weka jar在java代码中加载NaïveBayes模型

时间:2017-01-24 06:51:09

标签: java weka naivebayes

我使用了 weka 并使用weka GUI制作了Naive Bayes分类器。然后我按照tutorial保存了这个模型。现在我想通过Java代码加载这个模型,但是我无法找到任何方法来使用weka加载已保存的模型。

这是我的要求,我必须单独制作模型,然后在单独的程序中使用它。

如果有人可以在这方面指导我,我将感激你。

1 个答案:

答案 0 :(得分:4)

您可以使用以下命令轻松地在java中加载已保存的模型:

Classifier myCls = (Classifier) weka.core.SerializationHelper.read(pathToModel);

对于Java中的完整工作流,我在SO文档中编写了以下文章,现在复制到这里:

Weka中的文本分类

使用LibLinear进行文本分类

  • 从.arff文件

    创建培训实例
    private static Instances getDataFromFile(String path) throws Exception{
    
        DataSource source = new DataSource(path);
        Instances data = source.getDataSet();
    
        if (data.classIndex() == -1){
            data.setClassIndex(data.numAttributes()-1);
            //last attribute as class index
        }
    
        return data;    
    }
    
Instances trainingData = getDataFromFile(pathToArffFile);
  • 使用 StringToWordVector 将字符串属性转换为数字表示形式:

    • 此过滤器的重要功能:

      1. tf-idf representation
      2. 词干
      3. 小写字词
      4. 停用词
      5. n-gram表示*

    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:trainingData = Filter.useFilter(trainingData, filter);

    • 创建LibLinear分类器

      1. 下面的SVMType 0对应于L2正则化逻辑回归
      2. 设置setProbabilityEstimates(true)以打印输出概率

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

    • .arff文件

      创建测试实例

      Instances trainingData = getDataFromFile(pathToArffFile);

    • 加载分类器

    Classifier myCls = (Classifier) weka.core.SerializationHelper.read(path+"mymodel.model");

    • 使用与上面相同的StringToWordVector过滤器或为testsData创建一个新过滤器,但请记住使用trainingData执行此命令:filter.setInputFormat(trainingData); 这将进行培训和测试实例兼容。 或者,您可以使用InputMappedClassifier

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

    • 分类<!/ p>

    1.获取测试集中每个实例的类值

    for(int j = 0; j&lt; testingData.numInstances(); j ++){     double res = myCls.classifyInstance(testingData.get(j));  } res是一个double值,对应于.arff文件中定义的名义类。要获得名义上的课程使用:testintData.classAttribute().value((int)res)

2.获取每个实例的概率分布

 for (int j = 0; j < testingData.numInstances(); j++) {
    double[] dist = first.distributionForInstance(testInstances.get(j));
 }

dist是一个双数组,包含.arff文件中定义的每个类的概率

注意。分类器应支持概率分布,并使用:myClassifier.setProbabilityEstimates(true);

启用它们
相关问题