关于 Entity Extractor
Entity Extractor 是用于设计和实现命名实体识别流程的技能,面向处理通用或领域文本的 NLP 从业者。内容涵盖方法选择、自定义模型训练、评估、规范化及相关抽取任务。
主要功能
- 01选择 NER 方法
- 02实现抽取流程
- 03训练自定义实体模型
- 04评估抽取质量
- 05实体规范化与链接
- 06关系抽取方法
适用场景
- 01为特定领域选择 NER 方法
- 02构建自定义实体识别器
- 03分析各类实体的抽取错误
- 04将抽取实体链接到知识库
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jmsktm/ claude-settings --skill entity-extractor安装后在 Claude Code 中输入/entity-extractor确认已加载。
详细介绍
实体抽取
实体抽取技能将引导你实现命名实体识别(NER)系统,用于识别和分类文本中的实体。从人物和组织到特定领域的实体,例如产品、医学术语或金融工具,本技能涵盖从简单模式匹配到高级神经网络模型的各种抽取方法。
实体抽取是基础的 NLP 任务,为搜索引擎、知识图谱等应用提供支持。要做好这项任务,需要了解你的领域、选择合适的技术,并处理自然语言固有的歧义。
无论你需要抽取标准实体类型、为你的领域定义自定义实体,还是基于实体识别构建关系抽取,本技能都能帮助你打造准确且易于维护的抽取流水线。
核心工作流
工作流 1:选择抽取方法
- 定义目标实体:
- 标准类型:PERSON、ORG、LOCATION、DATE、MONEY
- 特定领域:PRODUCT、SYMPTOM、GENE、CONTRACT
- 关系:实体之间的联系
- 评估可用资源:
- 标注训练数据
- 领域专业知识
- 计算资源限制
- 选择方法:
方法 训练数据 准确度 速度 自定义能力 spaCy(预训练) 无 良好 非常快 有限 基于规则 无 不定 快 高 微调 BERT 100s-1000s 优秀 中等 完全 LLM(零样本) 无 良好 慢 基于提示词 LLM(少样本) 少量示例 很好 慢 基于提示词 - 规划实现和评估
工作流 2:实现实体抽取流水线
- 设置抽取流程:
import spacy class EntityExtractor: def __init__(self, model="en_core_web_trf"): self.nlp = spacy.load(model) def extract(self, text): doc = self.nlp(text) entities = [] for ent in doc.ents: entities.append({ "text": ent.text, "type": ent.label_, "start": ent.start_char, "end": ent.end_char, "confidence": getattr(ent, "confidence", None) }) return entities def extract_batch(self, texts): docs = list(self.nlp.pipe(texts)) return [self.extract_from_doc(doc) for doc in docs] - 后处理实体:
- 规范化不同写法(IBM 与 I.B.M.)
- 消解缩写
- 链接到知识库
- 验证抽取质量
- 处理边缘情况
工作流 3:构建自定义实体识别器
- 准备训练数据:
# Format for spaCy training TRAIN_DATA = [ ("Apple released the new iPhone today.", { "entities": [(0, 5, "ORG"), (24, 30, "PRODUCT")] }), ("Dr. Smith prescribed metformin for diabetes.", { "entities": [(0, 9, "PERSON"), (21, 30, "DRUG"), (35, 43, "CONDITION")] }) ] - 配置训练:
# spaCy config for NER training config = { "training": { "optimizer": {"learn_rate": 0.001}, "batch_size": {"@schedules": "compounding", "start": 4, "stop": 32} }, "components": { "ner": { "factory": "ner", "model": {"@architectures": "spacy.TransitionBasedParser"} } } } - 训练模型:
python -m spacy train config.cfg --output ./models --paths.train ./train.spacy --paths.dev ./dev.spacy - 在留出数据上评估
- 根据错误迭代改进
快速参考
| 操作 | 命令/触发语 |
|---|---|
| 抽取实体 | “从 [text] 中抽取实体” |
| 选择 NER 模型 | “[domain] 领域最适合的 NER” |
| 自定义实体 | “训练自定义实体识别器” |
| 评估 NER | “评估实体抽取质量” |
| 处理歧义 | “消解有歧义的实体” |
| 实体链接 | “将实体链接到知识库” |
最佳实践
-
从预训练模型开始:不要在没有必要时从头训练
- spaCy、Hugging Face 和云 API 可覆盖常见实体
- 先测试预训练模型
- 仅在需要时微调
-
制定明确的指南:实体边界可能存在歧义
- “Dr. John Smith”——一个实体还是两个?
- “New York Times”——ORG 还是 GPE?
- 制定并遵循一致的标注指南
-
处理嵌套实体:某些实体包含其他实体
- “Bank of America headquarters”(LOCATION 中包含 ORG)
- 提前决定嵌套策略
- 有些模型仅支持扁平实体;其他模型可以处理嵌套实体
-
规范化抽取出的实体:原始文本中存在不同写法
- “IBM”、“I.B.M.”、“International Business Machines”
- 规范为标准形式
- 尽可能链接到知识库 ID
-
细致评估:汇总指标会掩盖问题
- 按实体类型报告精确率/召回率
- 分析错误模式
- 明确测试边缘情况
-
考虑上下文窗口:模型有上下文限制
- 长文档可能需要分块
- 尽可能在各块之间保留上下文
- 如果实体可能跨块边界,则在边界处重新运行
高级技术
基于 LLM 的实体抽取
使用语言模型进行灵活抽取:
def llm_extract_entities(text, entity_types):
prompt = f"""Extract named entities from the following text.
Text: "{text}"
Entity types to extract:
{chr(10).join(f"- {t}: {desc}" for t, desc in entity_types.items())}
Return a JSON array of entities:
[{{"text": "entity text", "type": "ENTITY_TYPE", "start": 0, "end": 10}}]
Only include entities that clearly match the specified types.
"""
response = llm.complete(prompt, response_format={"type": "json_object"})
return json.loads(response)["entities"]
# Example usage
entity_types = {
"COMPANY": "Business organizations",
"PRODUCT": "Commercial products or services",
"PERSON": "Individual people's names"
}
entities = llm_extract_entities(text, entity_types)
规则 + ML 混合方法
结合模式匹配与神经网络抽取:
class HybridExtractor:
def __init__(self):
self.ml_extractor = spacy.load("en_core_web_trf")
self.patterns = load_pattern_rules()
def extract(self, text):
# ML extraction
ml_entities = self.ml_extractor(text).ents
# Pattern-based extraction
pattern_entities = apply_patterns(text, self.patterns)
# Merge with priority rules
merged = merge_entities(
ml_entities,
pattern_entities,
priority="pattern" # Patterns override ML when overlap
)
return merged
def add_pattern(self, pattern, entity_type):
"""Add domain-specific pattern."""
self.patterns.append({
"pattern": pattern,
"type": entity_type
})
实体链接
将提取出的实体关联到知识库:
def link_entity(entity_text, entity_type, knowledge_base):
"""
Link extracted entity to canonical entry in knowledge base.
"""
# Generate candidates
candidates = knowledge_base.search(
query=entity_text,
type_filter=entity_type,
limit=10
)
if not candidates:
return {"entity": entity_text, "linked": None}
# Score candidates
scored = []
for candidate in candidates:
score = compute_linking_score(
entity_text,
candidate.name,
candidate.aliases
)
scored.append((candidate, score))
# Select best match
best = max(scored, key=lambda x: x[1])
if best[1] > LINKING_THRESHOLD:
return {
"entity": entity_text,
"linked": best[0].id,
"canonical_name": best[0].name,
"confidence": best[1]
}
else:
return {"entity": entity_text, "linked": None}
关系抽取
提取实体之间的关系:
def extract_relations(text, entities):
"""
Given extracted entities, find relations between them.
"""
prompt = f"""Given this text and extracted entities, identify relationships.
Text: "{text}"
Entities found:
{json.dumps(entities, indent=2)}
Identify relationships between entities. Return JSON:
[{{
"subject": "entity text",
"relation": "relationship type",
"object": "entity text",
"confidence": 0.9
}}]
Common relation types: WORKS_FOR, LOCATED_IN, FOUNDED, ACQUIRED, PARTNER_OF
"""
response = llm.complete(prompt)
return json.loads(response)
NER 主动学习
通过有针对性的标注,高效改进抽取效果:
def active_learning_sample(unlabeled_texts, model, n_samples=100):
"""
Select texts that would be most valuable to label.
"""
uncertainties = []
for text in unlabeled_texts:
doc = model(text)
# Calculate uncertainty (various strategies)
uncertainty = calculate_ner_uncertainty(doc)
uncertainties.append((text, uncertainty))
# Select most uncertain
uncertainties.sort(key=lambda x: x[1], reverse=True)
return [text for text, _ in uncertainties[:n_samples]]
def calculate_ner_uncertainty(doc):
"""
Calculate uncertainty based on entity confidence scores.
"""
if not doc.ents:
return 0.5 # No entities - medium uncertainty
confidences = [ent._.confidence for ent in doc.ents if hasattr(ent._, "confidence")]
if not confidences:
return 0.5
# High uncertainty = low confidence entities
return 1 - min(confidences)
应避免的常见问题
- 标注指南不一致,导致训练数据含噪
- 未处理实体边界歧义(实体在哪里结束?)
- 忽略重要的嵌套或重叠实体
- 未进行数据增强,就使用小型数据集进行训练
- 在下游使用前未对实体进行规范化
- 未经测试就假定预训练模型适用于你的领域
- 未评估各实体类型的性能
- 忘记通过实体链接进行消歧
评论
支持 Markdown