You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Python的Stanza库提取小说中特定角色对应的形容词并统计频率?

如何使用Python的Stanza库提取小说中特定角色对应的形容词并统计频率?

嘿,作为Python新手能想到用字典存形容词和频率,这个思路完全没问题!既然你要把原来的NLTK方案换成Stanza,我给你调整了一套适配的实现步骤,一步步来很容易上手~

先做准备工作

  • 首先得安装Stanza库,打开终端跑这个命令:
    pip install stanza
    
  • 然后下载Stanza的英文模型(如果你的小说是其他语言,替换成对应代码即可,比如中文是'zh'):
    import stanza
    stanza.download('en')  # 下载英文分词&词性标注模型
    

完整代码实现

下面的代码完全适配你的需求,我还额外加了频率统计的功能,比单纯存列表更实用:

import stanza
from collections import Counter

# 1. 初始化Stanza的NLP管道,指定处理英文
nlp = stanza.Pipeline('en', processors='tokenize,pos')

# 2. 替换成你的小说文本变量(这里用你原来的verga_eros举例)
novel_text = verga_eros

# 3. 让Stanza处理文本,得到标注后的文档
doc = nlp(novel_text)

# 4. 初始化存储形容词的字典,以及后续统计频率用的Counter
character_adjectives = {
    "Marie": [],
    "Lucy": [],
    "Ella": []
}
character_adj_freq = {
    "Marie": Counter(),
    "Lucy": Counter(),
    "Ella": Counter()
}

# 5. 遍历每个句子,逐个检查单词
for sentence in doc.sentences:
    words = sentence.words
    for idx, word in enumerate(words):
        # Stanza里形容词的POS标签是'ADJ'(和NLTK的JJ不一样,这点要注意!)
        if word.upos == 'ADJ':
            # 情况1:形容词在角色名后面,比如"Marie is happy" → 前前词是Marie
            if idx >= 2 and words[idx-2].text in character_adjectives.keys():
                char_name = words[idx-2].text
                character_adjectives[char_name].append(word.text)
            # 情况2:形容词在角色名前面,比如"happy Marie" → 后一个词是Marie
            elif idx < len(words)-1 and words[idx+1].text in character_adjectives.keys():
                char_name = words[idx+1].text
                character_adjectives[char_name].append(word.text)

# 6. 统计每个角色的形容词频率
for char in character_adjectives:
    character_adj_freq[char] = Counter(character_adjectives[char])

# 7. 输出结果
print("=== 各角色对应的形容词及频率 ===")
for char, freq in character_adj_freq.items():
    print(f"\n{char}的形容词统计:")
    for adj, count in freq.most_common():  # 按频率从高到低排序
        print(f"- {adj}: {count}次")

一些实用小贴士

  • 大小写问题:如果小说里角色名有时候大写有时候小写,可以把比较的文本统一转成小写,比如words[idx-2].text.lower() == 'marie',避免漏抓描述
  • 扩展匹配逻辑:原来的逻辑只覆盖了前后紧邻的情况,如果你想抓更远的描述(比如"Marie, who is kind and gentle..."),可以调整判断逻辑,比如先定位句子里的角色名,再收集同一句子里的所有形容词
  • 模型选择:Stanza有不同精度的模型,如果你需要更准确的POS标注,可以在初始化Pipeline时指定model='en_core_web_trf'(Transformer模型),不过速度会稍慢一些

备注:内容来源于stack exchange,提问作者30user08

火山引擎 最新活动