如何实现Python NLP中主语对应形容词的查找?
嘿,我来帮你搞定这个找名词对应形容词的问题!你之前用Spacy没得到预期结果,大概率是没抓对正确的依赖关系——其实Spacy完全能搞定这个需求,我给你一步步拆解实现方法:
核心逻辑
我们需要抓取两种类型的形容词:
- 直接前置修饰名词的形容词(比如示例里的
blue和car),对应Spacy里的amod依赖关系; - 定语从句中作为表语的形容词(比如示例里的
beautiful和wife),这类需要先找到修饰名词的关系从句(relcl依赖),再从句子里提取表语(attr或acomp依赖)。
具体代码实现
首先确保你已经安装了Spacy和英文模型:
pip install spacy python -m spacy download en_core_web_sm
然后是find_ADJ函数的实现:
import spacy # 加载Spacy英文模型 nlp = spacy.load("en_core_web_sm") def find_ADJ(target_noun, sentence): doc = nlp(sentence) target = target_noun.lower() results = [] for token in doc: # 匹配目标名词(支持原形/大小写匹配,用lemma_兼容复数形式) if token.text.lower() == target or token.lemma_.lower() == target: adj_list = [] # 1. 收集直接修饰名词的形容词(amod) adj_list.extend([child.text for child in token.children if child.dep_ == "amod"]) # 2. 收集定语从句中的表语形容词 for child in token.children: # 找到修饰当前名词的关系从句(relcl是关系从句的核心动词) if child.dep_ == "relcl": # 从句中的表语(attr)或补语(acomp)都是描述名词的形容词 clause_adjs = [gc.text for gc in child.children if gc.dep_ in ("attr", "acomp")] adj_list.extend(clause_adjs) if adj_list: results.append((target_noun, adj_list)) # 返回结果:单个匹配返回元组,多个返回列表 return results[0] if len(results) == 1 else results
测试你的示例
sentence = "I have a blue car that was a gift from my wife who is beautiful" print(find_ADJ("car", sentence)) # 输出: ('car', ['blue']) print(find_ADJ("wife", sentence)) # 输出: ('wife', ['beautiful'])
关键依赖关系说明
amod:Adjectival modifier,直接修饰名词的形容词,是最常见的名词-形容词对应关系;relcl:Relative clause modifier,修饰名词的关系从句的核心动词(比如示例里的is就是修饰wife的relcl节点);attr:Attribute,系动词后的表语(比如is beautiful里的beautiful就是is的attr);acomp:Adjectival complement,动词后的形容词补语(比如The car looks old里的old就是looks的acomp)。
扩展注意事项
- 如果句子里有多个相同名词(比如
I have a blue car and a red car),函数会返回两个结果,你可以根据需求合并形容词列表; - 对于更复杂的嵌套从句,比如
The car that I bought which is red,可以添加递归遍历关系从句的逻辑来覆盖; - 要是需要处理“名词在主句中做主语+系表结构”的情况(比如
The car is red),可以扩展逻辑:找到名词的head(主句谓语),再提取其attr节点。
内容的提问来源于stack exchange,提问作者Aibloy
相关产品推荐
相关产品推荐

