You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用spaCy结合自定义数据集与标签实现NER,识别电影评论自定义实体

用spaCy提取电影评论中的自定义实体(ACTOR、DIRECTOR等)

方案一:基于规则的实体匹配(快速上手)

如果你的评论有固定表述模式(比如"导演XXX"、"主演XXX"、"上映日期:YYYY-MM-DD"),用spaCy的Matcher可以快速实现自定义实体提取,无需训练模型。

实现代码

import spacy
from spacy.matcher import Matcher

# 加载spaCy中文模型(英文评论替换为'en_core_web_sm')
nlp = spacy.load("zh_core_web_sm")

# 初始化匹配器
matcher = Matcher(nlp.vocab)

# 定义匹配规则
# 1. DIRECTOR:匹配"导演""执导"后的人名
director_patterns = [
    [{"TEXT": "导演"}, {"ENT_TYPE": "PERSON", "OP": "+"}],
    [{"TEXT": "执导"}, {"ENT_TYPE": "PERSON", "OP": "+"}]
]
# 2. ACTOR:匹配"主演""饰演"后的人名
actor_patterns = [
    [{"TEXT": "主演"}, {"ENT_TYPE": "PERSON", "OP": "+"}],
    [{"TEXT": "饰演"}, {"ENT_TYPE": "PERSON", "OP": "+"}]
]
# 3. DATE_OF_AIR:匹配"上映时间""播出日期"后的日期
date_patterns = [
    [{"TEXT": "上映时间"}, {"ENT_TYPE": "DATE", "OP": "+"}],
    [{"TEXT": "播出日期"}, {"ENT_TYPE": "DATE", "OP": "+"}]
]
# 4. AUTHOR:匹配"作者:""评论者:"后的用户名
author_patterns = [
    [{"TEXT": "作者"}, {"TEXT": ":"}, {"ENT_TYPE": "PERSON", "OP": "+"}],
    [{"TEXT": "评论者"}, {"TEXT": ":"}, {"ENT_TYPE": "PERSON", "OP": "+"}]
]

# 绑定规则与自定义实体标签
matcher.add("DIRECTOR", director_patterns)
matcher.add("ACTOR", actor_patterns)
matcher.add("DATE_OF_AIR", date_patterns)
matcher.add("AUTHOR", author_patterns)

# 实体提取函数
def extract_custom_entities(text):
    doc = nlp(text)
    matches = matcher(doc)
    entities = []
    for match_id, start, end in matches:
        entity_label = nlp.vocab.strings[match_id]
        # 跳过触发词,只提取实体内容
        if entity_label in ["DIRECTOR", "ACTOR"]:
            entity_text = doc[start+1:end].text
        elif entity_label in ["DATE_OF_AIR", "AUTHOR"]:
            entity_text = doc[start+2:end].text
        entities.append((entity_label, entity_text))
    return entities

# 测试示例
sample_review = "导演诺兰的新片《奥本海默》主演基里安·墨菲,上映时间2023年7月21日,作者:电影爱好者"
result = extract_custom_entities(sample_review)
print("提取到的自定义实体:")
for label, text in result:
    print(f"{label}: {text}")

方案二:训练自定义NER模型(适合无固定模式的大量数据)

如果评论表述无规律,需要让模型自主学习实体特征,就需要标注数据并训练spaCy的NER组件。

步骤1:准备标注数据

标注数据格式如下(可手动整理或用Prodigy工具辅助标注):

TRAIN_DATA = [
    (
        "导演张艺谋的《满江红》由沈腾、易烊千玺主演,2023年1月22日上映,评论者:影评人小李",
        {"entities": [(2,5,"DIRECTOR"), (11,13,"ACTOR"), (15,19,"ACTOR"), (22,32,"DATE_OF_AIR"), (36,41,"AUTHOR")]}
    ),
    (
        "我很喜欢卡梅隆执导的《阿凡达》,主演萨姆·沃辛顿,作者:科幻迷小王",
        {"entities": [(5,8,"DIRECTOR"), (16,22,"ACTOR"), (26,31,"AUTHOR")]}
    )
    # 补充更多标注数据,样本量越多模型效果越好
]

步骤2:训练模型代码

import spacy
from spacy.training import Example
from spacy.util import minibatch, compounding

# 加载基础模型
nlp = spacy.load("zh_core_web_sm")

# 获取或添加NER组件
if "ner" not in nlp.pipe_names:
    ner = nlp.add_pipe("ner", last=True)
else:
    ner = nlp.get_pipe("ner")

# 注册自定义实体标签
for label in ["DIRECTOR", "ACTOR", "DATE_OF_AIR", "AUTHOR"]:
    ner.add_label(label)

# 冻结其他组件,仅训练NER
other_pipes = [pipe for pipe in nlp.pipe_names if pipe != "ner"]
with nlp.disable_pipes(*other_pipes):
    optimizer = nlp.begin_training()
    # 训练循环
    for iteration in range(10):
        losses = {}
        # 打乱数据保证训练稳定性
        spacy.util.fix_random_seed(42)
        batches = minibatch(TRAIN_DATA, size=compounding(4.0, 32.0, 1.001))
        for batch in batches:
            for text, annotations in batch:
                doc = nlp.make_doc(text)
                example = Example.from_dict(doc, annotations)
                nlp.update([example], sgd=optimizer, losses=losses)
        print(f"迭代 {iteration+1},NER损失值:{losses['ner']:.4f}")

# 保存训练好的模型
nlp.to_disk("./custom_movie_ner_model")

# 测试模型效果
test_review = "冯小刚导演的《芳华》主演黄轩,2017年12月15日上映,作者:文艺青年小张"
doc = nlp(test_review)
print("\n训练后模型提取的实体:")
for ent in doc.ents:
    print(f"{ent.label_}: {ent.text}")

注意事项

  • 规则匹配适合句式固定的场景,训练模型适合复杂无规律的文本
  • 英文评论需替换为对应英文模型(如en_core_web_sm)
  • 标注数据建议至少几百条,才能保证模型泛化能力

内容的提问来源于stack exchange,提问作者mCs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:10:23