1

我正在使用 MaxEntTagger 通过使用以下代码进行 pos-tagging 和句子拆分:

MaxentTagger tagger = new MaxentTagger("models/left3words-wsj-0-18.tagger");

@SuppressWarnings("unchecked")
List<Sentence<? extends HasWord>> sentences = MaxentTagger.tokenizeText(new BufferedReader(new StringReader(out2)));

for (Sentence<? extends HasWord> sentence : sentences) {
    content.append(sentence + "\n");
    Sentence<TaggedWord> tSentence = MaxentTagger.tagSentence(sentence);
    out.append(tSentence.toString(false) + "\n");
}

问题是它会抱怨文本中有不可标记的字符。并且标记的输出将省略那些不可标记的字符。所以比如原文是:设Σ为函数符号的有限集合,即签名。

其中 Σ 在 big5 代码中。但是程序会显示以下警告信息: Untokenizable: Σ (first char in decimal: 931)

并且标记的输出是:设/VB 是/VB a/DT 有限/JJ 集/NN of/IN 函数/NN 符号/NNS ,/,/DT 签名/NN ./。

我得到的拆分后的句子是: Let be afinite set of function symbols , the signature 。

我的问题是如何保留这些不可标记的字符?

我试过修改模式的道具文件,但没有运气:

  标注器训练在 2008 年 9 月 21 日星期日 23:03:26 PDT 2008 调用,参数如下:
                    模型 = left3words-wsj-0-18.tagger
                     拱 = left3words,naacl2003unknowns,wordshapes(3)
                trainFile = /u/nlp/data/pos-tagger/train-wsj-0-18 ...
                 编码 = Big5
            initFromTrees = 假

有什么建议吗?

感谢Manning教授的帮助。但是我在使用解析器树时遇到了同样的问题。

续集

我需要得到一个句子的解析器树,所以我使用了以下代码:

PTBTokenizer<Word> ptb = PTBTokenizer.newPTBTokenizer(new StringReader(sentences));            
List<Word> words = ptb.tokenize(); 
Tree parseTree2 = lp.apply(words); 
TreebankLanguagePack tlp = new PennTreebankLanguagePack(); 
GrammaticalStructureFactory gsf = tlp.grammaticalStructureFactory(); 
GrammaticalStructure gs = gsf.newGrammaticalStructure(parseTree2); 

但是这次我不知道如何设置 PTBTokenizer 来解决不可标记字符的问题。如果使用工厂方法生成 PTBTokenizer 对象,我不知道如何将其连接到 StringReader。

List<Word> words = ptb.getTokenizer(new StringReader(sentences)); 

不起作用。

4

1 回答 1

5

斯坦福分词器接受多种选项来控制分词,包括如何处理它不知道的字符。但是,要设置它们,您当前必须实​​例化您自己的标记器。但这并不比你上面的难多少。以下完整程序使用选项制作标记器,然后使用它进行标记。

“noneKeep”选项意味着它不记录有关未知字符的消息,但保留它们并将每个消息转换为单个字符标记。您可以在 PTBTokenizer 类 javadoc 中了解其他选项。

注意:您似乎使用的是相当旧版本的标记器。(大约 2 年前,我们摆脱了 Sentence 类并开始使用 List 的标记,可能与这些选项被添加到标记器的时间差不多。)所以您可能必须升级到最新版本。无论如何,下面的代码只能针对更新版本的标记器正确编译。

import java.io.*;
import java.util.*;

import edu.stanford.nlp.ling.*;
import edu.stanford.nlp.process.*;
import edu.stanford.nlp.objectbank.TokenizerFactory;
import edu.stanford.nlp.tagger.maxent.MaxentTagger;

/** This demo shows user-provided sentences (i.e., {@code List<HasWord>}) 
 *  being tagged by the tagger. The sentences are generated by direct use
 *  of the DocumentPreprocessor class. 
 */
class TaggerDemo2 {

  public static void main(String[] args) throws Exception {
    if (args.length != 2) {
      System.err.println("usage: java TaggerDemo modelFile fileToTag");
      return;
    }
    MaxentTagger tagger = new MaxentTagger(args[0]);
    TokenizerFactory<CoreLabel> ptbTokenizerFactory = 
    PTBTokenizer.factory(new CoreLabelTokenFactory(), "untokenizable=noneKeep");
    BufferedReader r = 
        new BufferedReader(new InputStreamReader(new FileInputStream(args[1]), "utf-8"));
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out, "utf-8"));
    DocumentPreprocessor documentPreprocessor = new DocumentPreprocessor(r);
    documentPreprocessor.setTokenizerFactory(ptbTokenizerFactory);
    for (List<HasWord> sentence : documentPreprocessor) {
      List<TaggedWord> tSentence = tagger.tagSentence(sentence);
      pw.println(Sentence.listToString(tSentence, false));
    }
  }

}
于 2012-06-20T16:05:22.753 回答