如何用Spacy识别英文名词性别?Python NLP新手技术求助
问题:Spacy无法识别名词性别,如何处理主语代词匹配?
我是Python Spacy NLP领域的新手,目前在处理主语对应代词的问题时遇到瓶颈:已实现I、we、they等代词的主语匹配,但无法处理he/she/it这类第三人称单数代词对应的名词性别判断。根据语法规则,第三人称单数主语需根据名词性别选择he/she/it,我编写了如下代码:
import spacy nlp = spacy.load("en_core_web_sm") def get_gender(sent:str): doc = nlp(sent) for token in doc: if token.dep_ == "nsubj": if token.morph.get("Gender") == ["Masc"]: return token.text + "-male" elif token.morph.get("Gender") == ["Fem"]: return token.text + "-female" else: return token.text + "-unknown" return "unknown" sent1="He is honest" sent2="She is honest" sent3="The man is honest" print(f"{sent1}: {get_gender(sent1)}") # Output: He is honest: He-male print(f"{sent2}: {get_gender(sent2)}") # Output: She is honest: She-female print(f"{sent3}: {get_gender(sent3)}") # Output: The man is honest: man-unknown
但该代码仅能识别代词的性别,无法识别名词(如man)的性别。我需要判断主语名词的性别(如Father-阳性、Mother-阴性、Table-中性、Student-通用),请问Spacy是否有内置方法?若没有,能否提供分性别的名词词典?
回答:
1. Spacy内置能力说明
Spacy的默认模型(比如en_core_web_sm)没有内置的名词性别识别功能,它的morph属性仅针对代词(如he/she/it)提供性别标记,对普通名词不会返回性别信息。这是因为英文中大部分名词本身没有语法性别,语义性别需要额外的词典或规则来判断。
2. 解决方案:自定义性别词典
你可以通过构建自定义性别词典来实现名词性别判断,结合Spacy的主语识别逻辑即可解决问题。以下是优化后的代码示例:
import spacy nlp = spacy.load("en_core_web_sm") # 自定义性别词典,可根据需求扩展 GENDER_DICT = { # 阳性名词 "man": "male", "father": "male", "son": "male", "brother": "male", "uncle": "male", "king": "male", # 阴性名词 "woman": "female", "mother": "female", "daughter": "female", "sister": "female", "aunt": "female", "queen": "female", # 中性名词 "table": "neutral", "chair": "neutral", "book": "neutral", "computer": "neutral", # 通用名词(无特定性别) "student": "neutral", "teacher": "neutral", "doctor": "neutral", "person": "neutral" } def get_gender(sent: str): doc = nlp(sent) for token in doc: if token.dep_ == "nsubj": # 先检查代词的morph性别 morph_gender = token.morph.get("Gender") if morph_gender == ["Masc"]: return f"{token.text}-male" elif morph_gender == ["Fem"]: return f"{token.text}-female" elif morph_gender == ["Neut"]: return f"{token.text}-neutral" # 再检查词典中的名词性别 elif token.text.lower() in GENDER_DICT: return f"{token.text}-{GENDER_DICT[token.text.lower()]}" # 未匹配到的情况返回unknown else: return f"{token.text}-unknown" return "unknown" # 测试用例 sent1 = "He is honest" sent2 = "She is honest" sent3 = "The man is honest" sent4 = "My mother is kind" sent5 = "The table is wooden" sent6 = "The student studies hard" print(f"{sent1}: {get_gender(sent1)}") # Output: He is honest: He-male print(f"{sent2}: {get_gender(sent2)}") # Output: She is honest: She-female print(f"{sent3}: {get_gender(sent3)}") # Output: The man is honest: man-male print(f"{sent4}: {get_gender(sent4)}") # Output: My mother is kind: mother-female print(f"{sent5}: {get_gender(sent5)}") # Output: The table is wooden: table-neutral print(f"{sent6}: {get_gender(sent6)}") # Output: The student studies hard: student-neutral
3. 扩展建议
- 可以通过添加更多名词到
GENDER_DICT来覆盖更多场景,比如职业、亲属称谓等。 - 对于模糊性的名词(如"doctor"),可根据需求定义为通用中性或保留为unknown。
- 如果需要更全面的语义性别识别,可以手动整理WordNet等语义库中的性别标记来扩展词典。
内容的提问来源于stack exchange,提问作者Shahriar Zarir
相关产品推荐
相关产品推荐

