【发布时间】:2017-10-16 19:59:22
【问题描述】:
使用 NLP 从给定的句子中,我可以使用 Core NLP 轻松提取所有形容词和名词。 但我正在努力做的实际上是从句子中提取短语。
例如我有以下句子:
- 此人值得信赖。
- 此人不具判断力。
- 这个人说得很好。
对于所有这些使用 NLP 的句子,我想提取值得信赖的、非判断性的、口语好的等短语。我想提取所有这些相关的词。
我该怎么做?
谢谢,
【问题讨论】:
标签: nlp stanford-nlp
使用 NLP 从给定的句子中,我可以使用 Core NLP 轻松提取所有形容词和名词。 但我正在努力做的实际上是从句子中提取短语。
例如我有以下句子:
对于所有这些使用 NLP 的句子,我想提取值得信赖的、非判断性的、口语好的等短语。我想提取所有这些相关的词。
我该怎么做?
谢谢,
【问题讨论】:
标签: nlp stanford-nlp
我认为您首先需要考虑这些具体示例,并考虑您想要提取的确切结构。例如,在您的情况下,您可以使用一些简单的启发式方法来查找 copular child 的任何实例及其所有修饰符。
如果您需要提取的范围比这更大,您可以回到绘图板并重新考虑一些基于基本语言特征的规则,例如斯坦福 CoreNLP,或另一张海报链接的 spaCy。
最后,如果您需要泛化到其他未知示例的能力,您可能需要训练一个分类器(可能从一个简单的逻辑回归分类器开始),方法是为其提供相关的语言特征并将句子中的每个标记标记为相关或不相关。
【讨论】:
要检查相似短语之间的相似性,您可以使用 GLOVE 等词嵌入。一些 NLP 库带有嵌入,例如 Spacy。 https://spacy.io/usage/vectors-similarity
注意:Spacy 在标记级别和短语级别都使用余弦相似度,Spacy 还为较大的短语/句子提供了便利的相似度函数。
例如: (使用 spacy 和 python)
doc1 = nlp(u"The person is trustworthy.")
doc2 = nlp(u"The person is non judgemental.")
cosine_similarity = doc1.similarity(doc2)
而 cosine_similarity 可用于显示两个短语/单词/句子的相似程度,范围从 0 到 1,其中 1 非常相似。
【讨论】:
对于您的特定用例,Open Information Extraction 似乎是一个合适的解决方案。它提取包含主题、关系和对象的三元组。你的关系似乎总是 be(is 的不定式),而你的主题似乎总是 person,所以我们只对宾语感兴趣.
import edu.stanford.nlp.ie.util.RelationTriple;
import edu.stanford.nlp.ling.CoreAnnotations;
import edu.stanford.nlp.ling.CoreAnnotations.TextAnnotation;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.naturalli.NaturalLogicAnnotations;
import edu.stanford.nlp.util.CoreMap;
import java.util.Collection;
import java.util.Properties;
public class OpenIE {
public static void main(String[] args) {
// Create the Stanford CoreNLP pipeline
Properties props = new Properties();
props.setProperty("annotators", "tokenize,ssplit,pos,lemma,depparse,natlog,openie");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
// Annotate your sentences
Annotation doc = new Annotation("This person is trust worthy. This person is non judgemental. This person is well spoken.");
pipeline.annotate(doc);
// Loop over sentences in the document
for (CoreMap sentence : doc.get(CoreAnnotations.SentencesAnnotation.class)) {
// Get the OpenIE triples for the sentence
Collection<RelationTriple> triples = sentence.get(NaturalLogicAnnotations.RelationTriplesAnnotation.class);
// Print the triples
for (RelationTriple triple : triples) {
triple.object.forEach(object -> System.out.print(object.get(TextAnnotation.class) + " "));
System.out.println();
}
}
}
}
输出如下:
trust
worthy
non judgemental
judgemental
well spoken
spoken
OpenIE 算法可能会在每个句子中提取多个三元组。对于您的用例,解决方案可能是只取对象中单词数量最多的三元组。
另一件事要提的是,您的第一句话的对象没有“正确”提取,至少不是以您想要的方式。这是因为 trust 是名词而 worthy 是形容词。 最简单的解决方案是用连字符 (trust-worthy) 编写它。 另一种可能的解决方案是检查Part of Speech 标签并在遇到名词后跟形容词时执行一些额外的步骤。
【讨论】: