如何训练最大分类器

时间:2014-04-14 16:23:22

标签: twitter sentiment-analysis opennlp maxent

[项目堆栈:Java,Opennlp,Elasticsearch(数据存储),twitter4j从twitter读取数据]

我打算使用maxent分类器来对推文进行分类。我知道最初的步骤是训练模型。从文档中我发现我们有一个基于GISTrainer的训练方法来训练模型。我设法编写了一段简单的代码,利用opennlp的maxent分类器来训练模型并预测结果。

我使用了两个文件postive.txt和negative.txt来训练模型

positive.txt的内容

positive    This is good
positive    This is the best
positive    This is fantastic
positive    This is super
positive    This is fine 
positive    This is nice

negative.txt的内容

negative    This is bad
negative    This is ugly
negative    This is the worst
negative    This is worse
negative    This sucks

下面的java方法会产生结果。

@Override
public void trainDataset(String source, String destination) throws Exception {
    File[] inputFiles = FileUtil.buildFileList(new File(source)); // trains both positive and negative.txt
    File modelFile = new File(destination);
    Tokenizer tokenizer = SimpleTokenizer.INSTANCE;
    CategoryDataStream ds = new CategoryDataStream(inputFiles, tokenizer);
    int cutoff = 5;
    int iterations = 100;
    BagOfWordsFeatureGenerator bowfg = new BagOfWordsFeatureGenerator();
    DoccatModel model = DocumentCategorizerME.train("en", ds, cutoff,iterations, bowfg);
    model.serialize(new FileOutputStream(modelFile));
}

@Override
public void predict(String text, String modelFile) {
    InputStream modelStream = null;
    try{
        Tokenizer tokenizer = SimpleTokenizer.INSTANCE;
        String[] tokens = tokenizer.tokenize(text);
        modelStream = new FileInputStream(modelFile);
        DoccatModel model = new DoccatModel(modelStream);
        BagOfWordsFeatureGenerator bowfg = new BagOfWordsFeatureGenerator(); 
        DocumentCategorizer categorizer = new DocumentCategorizerME(model, bowfg);
        double[] probs   = categorizer.categorize(tokens);
        if(null!=probs && probs.length>0){
            for(int i=0;i<probs.length;i++){
                System.out.println("double[] probs index  " + i + " value " + probs[i]);
            }
        }
        String label = categorizer.getBestCategory(probs);
        System.out.println("label " + label);
        int bestIndex = categorizer.getIndex(label);
        System.out.println("bestIndex " + bestIndex);
        double score = probs[bestIndex];
        System.out.println("score " + score);
    }
    catch(Exception e){
        e.printStackTrace();
    }
    finally{
        if(null!=modelStream){
            try {
                modelStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

public static void main(String[] args) {
    try {
        String outputModelPath = "/home/**/sd-sentiment-analysis/models/trainPostive";
        String source = "/home/**/sd-sentiment-analysis/sd-core/src/main/resources/datasets/";
        MaximunEntropyClassifier me = new MaximunEntropyClassifier();
        me.trainDataset(source, outputModelPath);
        me.predict("This is bad", outputModelPath);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我有以下问题。

1)如何迭代训练模型?另外,如何在模型中添加新的句子/单词?是否有数据文件的特定格式?我发现文件需要至少有两个由制表符分隔的单词。我的理解有效吗? 2)是否有可用于训练模型的公开数据集?我找到了一些电影评论的来源。我正在进行的项目不仅涉及电影评论,还涉及其他事项,如产品评论,品牌情绪等。 3)This在一定程度上有所帮助。公开可用的某个工作示例吗?我无法找到maxent的文档。

请帮帮我。我很善良,因此受阻。

2 个答案:

答案 0 :(得分:0)

1)您可以将样本存储在数据库中。为此,我曾经使用了一次累积。然后在某个时间间隔重建模型并重新处理数据。 2)格式为:categoryname space sample newline。没有标签 3)听起来你想要将一般情绪与主题或实体结合起来。您可以使用名称查找器或仅使用正则表达式查找实体或将实体添加到您的类标签中以获取doccat包含产品名称等,然后您的样本必须非常具体

答案 1 :(得分:0)

AFAIK,如果要添加新的训练样本,则必须完全重新训练 MaxEnt模型。 无法以增量方式联机。

opennlp maxent的默认输入格式是文本文件,其中每行代表一个样本。 样本由由空格分隔的标记(特征)组成。在训练期间,第一个标记代表结果。

在这里看看我的最小工作示例: Training models using openNLP maxent