如何在MaxEntTagger中保留不可识别的字符?

时间:2012-06-16 04:34:03

标签: stanford-nlp

我使用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代码。但该程序将显示以下警告消息: 无法辨认:Σ(十进制的第一个字符:931)

,标记的输出是: 设/ VB为/ VB a / DT有限/ JJ设置/ NN / IN函数/ NN符号/ NNS,/,/ DT签名/ NN ./.

我得到的分句是: 设为一组有限的函数符号,即签名。

我的问题是如何保留这些不可言说的角色?

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

  tagger training invoked at Sun Sep 21 23:03:26 PDT 2008 with arguments:
                    model = left3words-wsj-0-18.tagger
                     arch = left3words,naacl2003unknowns,wordshapes(3)
                trainFile = /u/nlp/data/pos-tagger/train-wsj-0-18 ...
                 encoding = Big5
            initFromTrees = false

有什么建议吗?

感谢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)); 

不起作用。

1 个答案:

答案 0 :(得分:5)

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

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

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

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

}