从文本中提取名词(Java)

13

有人知道从一段文本中提取名词的最简单方法吗?

我听说过TreeTagger工具,尝试使用它但无法让它正常工作。

有什么建议吗?

谢谢Phil

编辑:

 import org.annolab.tt4j.*; 
TreeTaggerWrapper tt = new TreeTaggerWrapper();
try { tt.setModel("/Nouns/english.par");
tt.setHandler(new TokenHandler() { void token(String token, String pos, String lemma) { System.out.println(token+"\t"+pos+"\t"+lemma); } }); tt.process(words); // words = list of words
} finally { tt.destroy(); }

这是我的代码,使用的是英语。我遇到了错误:The type new TokenHandler(){} must implement the inherited abstract method TokenHandler.token. 我做错了什么吗?


3
能否解释一下TreeTagger出了什么问题? - Maximilian Mayerl
1
你能具体说明一下你的问题吗?特别是需要知道使用的编程语言...比如德语,它有一个很好的优势,就是所有名词的首字母都是大写的。 - Chris
我不熟悉TreeTagger API,但我会从实例化TokenHandler到setHandler()之外开始 - 这可能会提供更清晰的消息。我猜TokenHandler是抽象的,但是... - peter.murray.rust
参见:https://dev59.com/G3RB5IYBdhLWcg3weXSX。这与专有名词有关。 - peter.murray.rust
7个回答

23

首先,您需要对文本进行分词。这可能看起来很琐碎(在任何空格处拆分可能对您有用),但从正式角度来说,它更难一些。然后,您必须确定什么是名词。"the car park" 包含一个名词 (car park)、两个名词 (car、park) 还是一个名词 (park) 和一个形容词 (car)?这是一个困难的问题,但是您可以通过不去纠结于此而获得进展。

"I saw the xyzzy" 中的单词 "xyzzy" 是否是一个字典中没有的名词?单词 "the" 可能将 xyzzy 识别为名词。

在 "time flies like an arrow" 中哪里有名词?与 "fruit flies like a banana" 相比较 (感谢 Groucho Marx)。

我们使用 OpenNLP 工具包 (opennlp.tools.lang.english.PosTagger;opennlp.tools.postag.POSDictionary 在 http://opennlp.sourceforge.net/ 上) 中的 Brown 标签器 (Java) (http://en.wikipedia.org/wiki/Brown_Corpus) 来查找普通英语中的名词,我建议您从那里开始 - 它可以为您大部分思考。否则,请查看任何一个 POSTagger (http://en.wikipedia.org/wiki/POS_tagger) 或 (http://www-nlp.stanford.edu/links/statnlp.html#Taggers)。

在计算机的词性标注中, 典型的是为英语区分出50到150个不同的词性,例如 NN 表示单数普通名词,NNS 表示复数普通名词,NP 表示单数专有名词 (请参阅 Brown Corpus 中使用的 POS 标签)

http://en.wikipedia.org/wiki/Natural_language_processing_toolkits中有一个非常完整的自然语言处理工具包列表。我强烈建议您使用其中之一,而不是尝试与Wordnet或其他收集进行匹配。


有些人似乎认为自然语言处理并不难,实际上它是计算机中最复杂的事情之一。这涉及到大量的特例问题,当要处理的语言突然改变时,所有的工作都将变得毫无用处。而且,在更理论的层面上,你还会遇到一个问题:名词、动词、代词等存在多个定义。+1 说明。 - Maximilian Mayerl
@Maximilian 感谢您的支持。我们同意这很困难。幸运的是,我们只是试图解释化学家写的语言,这要容易得多! - peter.murray.rust
非常好的帖子,谢谢。我正在下载Lingpipe,不过我用的是Windows系统,希望它没有太多讨厌的.sh脚本!哈哈 - Phil
我们曾经使用过LingPipe,但是它不是开源的,我们需要一个开放的系统来进行分发。如果你只是个人使用,我认为没有问题。 - peter.murray.rust
不幸的是,现在似乎没有证据表明格劳乔实际上说过这句话。 - peter.murray.rust

1
我的以下代码与TreeTagger一起工作:
public List<String> tag(String str) {
    final List<String> tagLemme = new ArrayList<String>();
    String[] tokens =tokenizer.tokenize(str);
      System.setProperty("treetagger.home", "parametresTreeTagger/TreeTagger");
    TreeTaggerWrapper tt = new TreeTaggerWrapper<String>();
    try {
        tt.setModel("parametresTreeTagger/english/english.par");
        tt.setHandler(new TokenHandler<String>(){
                public void token(String token, String pos, String lemma) {
                        tagLemme.add(token + "_" + pos + "_" + lemma);
                        //System.out.println(token + "_" + pos + "_" + lemma);
                }
        });
        tt.process(asList(tokens));
     } catch (IOException e) {
        e.printStackTrace();
      } catch (TreeTaggerException e) {
        e.printStackTrace();
    }
finally {
        tt.destroy();
}
    return tagLemme;
}

我甚至无法正确安装它 https://dev59.com/XG_Xa4cB1Zd3GeqP5tv_ - alvas

1

看看LingPipe。这个工具据说可以从英文文本中提取命名实体。但我必须承认,NLP不是我的专业领域。


1

根据您的编辑:

错误提示称您必须重写抽象方法"token",而您在匿名内部类中定义了"token",但是也许您的"token"重写签名与"TokenHandler"定义的抽象方法的签名不匹配?


0

看一下WordNet数据库。这个词汇数据库很有用。你可以尝试把每个单词与它进行匹配,然后检查它是否是名词。

不过我怀疑你不会有100%的准确率;因为该数据库并没有包含英语语言中所有可能的单词,但至少这是一个开始。


1
这并不是很准确。例如,拿句子“He is walking to school.”和“He said that walking is exhausting.”来比较。在第二个句子中,“walking”是一个名词(通过动名词化的方式将动词名化),但在第一个句子中,它是动词“to walk”的进行时形式。这只是一个例子,还有更多问题。 - Maximilian Mayerl

0

最简单的方法可能是将文本中的每个单词与名词字典进行比较。之后,您可能需要进行一些基础解析,并接受结果的大致正确性。有很多在线参考资料可用于解析自然语言。


0
找一个带有API(例如WS,RESTful)的词典网站,您可以使用它来运行搜索查询。
结果应以易于消耗的格式(例如XML,JSON)呈现,并且当然应包括单词的词汇类别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接