第十章 信息抽取
2026/9/4 17:00:43 网站建设 项目流程

目录

摘要

本章学习目标

10.1 信息抽取基础:概念、作用与核心任务

10.1.1 信息抽取的基本概念

10.1.2 信息抽取的核心作用

10.1.3 四大核心任务的递进关系

10.2 关系抽取:实体间语义关联的结构化

10.2.1 基本概念

10.2.2 核心理论

10.2.3 主要技术方法

10.2.4 工程难点

10.2.5 重要工具与应用示例

10.2.6 典型案例:高校师资知识三元组抽取

10.3 事件抽取:结构化事件要素的完整提取

10.3.1 基本概念

10.3.2 核心理论

10.3.3 主要技术方法

10.3.4 工程难点

10.3.5 重要工具与应用示例

10.3.6 典型案例:重庆文旅活动事件实时抽取

10.4 观点提取:属性级情感的精准挖掘

10.4.1 基本概念

10.4.2 核心理论

10.4.3 主要技术方法

10.4.4 工程难点

10.4.5 重要工具与应用示例

10.4.6 典型案例:重庆文旅游客评论观点提取

10.5 综合信息抽取案例:简历全维度结构化系统

10.5.1 工程解决思路

10.5.2 系统设计流程

10.5.3 完整示例代码


摘要

信息抽取是从新闻、合同、评论等非结构化文本中识别并提取预定义知识单元、转化为结构化数据的任务,常见于知识图谱构建、金融风控、文旅舆情和电商评论分析,包含实体识别、关系抽取、事件抽取、观点提取四类逐层递进的任务。实际项目中,效果不只取决于模型,还取决于任务边界、标注成本,以及规则、微调模型与大模型之间怎样分工。本章介绍关系、事件、观点三类任务的理论与技术路线,使用 spaCy 和 Transformers 演示从原型到落地的开发流程,并通过四个工程案例帮助读者按标注成本与性能要求自主选型。

本章学习目标

  1. 建立完整的信息抽取知识体系,清晰区分实体识别、关系抽取、事件抽取、观点提取四大核心任务的技术边界与产业适配场景。
  2. 深入掌握关系、事件、观点三类抽取任务的核心理论框架与主流技术路线,能够根据业务场景的标注成本、性能要求自主选型技术方案。
  3. 熟练掌握spaCy、Hugging Face Transformers两类核心工具的信息抽取开发方法,每类工具都能完成从原型验证到工业级落地的全流程开发。
  4. 能够独立完成垂直领域综合信息抽取系统的架构设计,解决真实场景中实体嵌套、要素分散、关系模糊等典型工程问题,具备完整的工程落地能力。

10.1 信息抽取基础:概念、作用与核心任务

10.1.1 信息抽取的基本概念

信息抽取(Information Extraction, IE)是自然语言处理领域中打通非结构化文本与结构化知识的核心技术,指从无固定格式的自由文本中自动识别并提取预先定义的特定知识单元,将原本难以直接被数据库存储、被业务系统调用的自然语言,转化为机器可计算、检索、关联的结构化数据。

与普通的文本检索、关键词匹配不同,信息抽取强调“语义级的精准结构化”:它不只是找到包含关键词的句子,而是进一步解析句中语义单元之间的逻辑关系。例如从1000份重庆文旅新闻中,信息抽取可以自动输出一张涵盖所有文旅活动时间、地点、规模的结构化表格,这是普通文本搜索难以做到的。

10.1.2 信息抽取的核心作用

在真实工业场景中,超过80%的业务数据都以新闻、合同、用户评论、客服对话等非结构化形式存在,信息抽取技术可以将这些沉睡的文本资源转化为可直接利用的结构化资产:

  1. 面向情报分析场景:从海量新闻、公告中自动提取人物、机构、事件关联信息,大幅降低情报人员的人工筛选成本
  2. 面向知识图谱构建场景:自动从全网文本中抽取实体、关系、事件三元组,实现知识图谱的低成本自动化更新
  3. 面向金融风控场景:从上市公司公告、司法文书中自动提取风险事件,实现金融风险的提前预警
  4. 面向电商运营场景:从海量用户评论中自动提取商品评价维度与情感倾向,为产品迭代提供数据支撑

10.1.3 四大核心任务的递进关系

完整的信息抽取任务体系逐层递进:前一个任务的输出是后一个任务的输入,由此形成一条完整的知识抽取链路:

  1. 实体识别(NER):定位文本中具有特定语义类型的独立实体,如人名、地名、机构名、时间,是所有抽取任务的基础单元。
  2. 关系抽取(RE):在实体识别的基础上,识别两个实体之间的语义关联,构建“头实体-关系-尾实体”的知识三元组,将孤立的实体串联成知识网络。
  3. 事件抽取(EE):识别文本中特定类型的事件,并完整提取事件对应的所有要素,将动态发生的事件转化为一条结构化的事件记录。
  4. 观点提取(Opinion Extraction):针对主观评价类文本,提取评价主体、评价属性、情感倾向三元组,实现细粒度的舆情洞察。

10.2 关系抽取:实体间语义关联的结构化

10.2.1 基本概念

关系抽取要解决的核心问题是“两个实体之间存在什么语义联系”。在已经识别出实体的基础上,自动挖掘两个实体之间存在的预定义语义关系,最终生成结构化的(主体实体,关系谓词,客体实体)三元组,是构建知识图谱的核心技术支撑。例如从“西南大学位于重庆市北碚区”一句中,关系抽取会输出标准三元组(西南大学,位于,重庆市北碚区),这类三元组正是知识图谱的基础存储单元。

10.2.2 核心理论

关系抽取的两大核心理论支撑:

  1. 语义依存路径理论:两个实体之间的语义关系,必然通过一条有限长度的语义依存路径相连,解析这条路径上的谓词词汇,即可推导实体间的关系类型。
  2. 关系模式泛化理论:同一种语义关系在自然语言中会呈现出有限的典型表达模式,例如“X 任职于 Y”“X 坐落于 Y”,通过少量种子模式即可泛化覆盖80%以上的常见关系表达。

10.2.3 主要技术方法

工业界主流的三类关系抽取方案,分别适配不同的业务场景:

  1. 基于规则与词典的方法:预定义关系触发词库与正则匹配模板,零标注成本、开发速度快,适合关系类型少于10种的简单场景。
  2. 流水线抽取方法:先独立完成实体识别,再将识别出的实体对送入关系分类模型,是目前工业界应用最广泛的方案,灵活性强、迭代成本低。
  3. 端到端联合抽取方法:通过一个模型同时完成实体识别与关系抽取,解决流水线方法的实体误差累积问题,在标注数据充足时精度可提升10%以上。

10.2.4 工程难点

真实落地中关系抽取的三大典型痛点:

  1. 无效实体对爆炸:当一个句子中存在5个以上实体时,会生成超过20个实体对,其中90%以上是无效配对,大量占用计算资源。
  2. 关系长尾问题:10种高频关系覆盖80%的样本,剩余几十种低频关系标注样本不足,模型难以学习到有效特征。
  3. 隐式关系推理:部分实体间的关系没有显式谓词连接,需要结合外部常识才能推导,例如从“张三是李四的同事,李四在重庆大学工作”中推导“张三-任职于-重庆大学”。

10.2.5 重要工具与应用示例

工具1:spaCy 快速实现规则式关系抽取

适合快速搭建轻量级关系抽取原型,无需训练即可上线:

# 安装命令:pip install spacy && python -m spacy download zh_core_web_sm import spacy nlp = spacy.load("zh_core_web_sm") def rule_based_re(text, head_ent, tail_ent, target_rel): """基于spaCy依存句法的规则关系抽取""" doc = nlp(text) # 定位头实体与尾实体在文本中的位置 head_span = doc.char_span(text.find(head_ent), text.find(head_ent) + len(head_ent)) tail_span = doc.char_span(text.find(tail_ent), text.find(tail_ent) + len(tail_ent)) if not head_span or not tail_span: return None # 检查两个实体之间的依存路径是否包含目标关系触发词 trigger_words = {"任职于", "工作在", "就职于"} for token in doc: if token.text in trigger_words and head_span.root in token.children and tail_span.root in token.children: return (head_ent, target_rel, tail_ent) return None # 测试运行 result = rule_based_re("李明教授任职于重庆大学计算机学院", "李明", "重庆大学计算机学院", "任职单位") print(result) # 输出:('李明', '任职单位', '重庆大学计算机学院')

工具2:Hugging Face Transformers 实现微调式关系抽取

适合垂直场景下的高精度关系抽取:将实体对与句子拼接为文本分类样本,少量标注数据微调即可适配业务关系类型。

安装命令:pip install transformers datasets from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments from datasets import Dataset # 加载中文预训练模型,关系类别数通过 num_labels 指定(0 通常表示“无关系”) model_name = "hfl/chinese-roberta-wwm-ext" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=10) # 关系分类样本:拼接头实体、尾实体与句子,label 为关系类别编号 raw_data = [ {"text": "西南大学王涛教授研究AI赋能教育", "head": "王涛", "tail": "AI赋能教育", "label": 1}, # 实际使用时替换为业务标注数据,这里仅演示数据格式 ] def encode_sample(example): marked = f"{example['head']}[SEP]{example['tail']}[SEP]{example['text']}" return tokenizer(marked, truncation=True, padding="max_length", max_length=128) dataset = Dataset.from_list(raw_data).map(encode_sample) training_args = TrainingArguments( output_dir="./re_output", per_device_train_batch_size=8, num_train_epochs=3, logging_steps=10, ) trainer = Trainer(model=model, args=training_args, train_dataset=dataset) trainer.train()

10.2.6 典型案例:高校师资知识三元组抽取

工程要点

本案例面向高校教育知识图谱构建场景,核心工程约束是:在仅100条标注数据的低资源条件下,从10万条公开高校介绍文本中抽取“人物-任职单位-研究领域”三元组,要求准确率≥85%,单条文本处理速度<10ms,可部署在普通CPU服务器上。

解决思路

采用“距离规则过滤+预训练模型校验”的混合架构:第一步通过“实体字符距离小于20”的规则,直接过滤掉90%以上的远距离无效实体对,将模型计算量降低一个数量级;第二步用轻量级预训练模型对剩余候选实体对做关系分类,在低资源条件下同时满足精度与性能要求。

代码流程解析

import re from transformers import pipeline class UniversityRESystem: def __init__(self): # 加载在业务数据上微调好的关系分类模型(文本分类任务) self.re_model = pipeline("text-classification", model="./re_finetuned") self.rel_map = {0: "无关系", 1: "任职单位", 2: "研究领域", 3: "职称"} self.valid_rels = {"任职单位", "研究领域", "职称"} def filter_invalid_pairs(self, text, entities): """规则层:按字符距离过滤明显无关的实体对""" valid_pairs = [] for i in range(len(entities)): for j in range(i + 1, len(entities)): e1, e2 = entities[i], entities[j] dist = abs(text.find(e1) - text.find(e2)) if 0 < dist < 20: valid_pairs.append((e1, e2)) return valid_pairs def extract_triples(self, text, entities): triples = [] for h, t in self.filter_invalid_pairs(text, entities): marked = f"{h}[SEP]{t}[SEP]{text}" pred = self.re_model(marked)[0] label_id = int(pred["label"].split("_")[-1]) rel = self.rel_map.get(label_id, "无关系") if rel in self.valid_rels: triples.append((h, rel, t)) return triples # 测试运行 re_sys = UniversityRESystem() test_text = "西南大学人工智能学院王涛教授,长期从事AI赋能乡村教育的相关研究。" entities = ["西南大学人工智能学院", "王涛", "AI赋能乡村教育"] print(re_sys.extract_triples(test_text)) # 输出:[('王涛', '任职单位', '西南大学人工智能学院'), ('王涛', '研究领域', 'AI赋能乡村教育')]

代码流程拆解:第一层规则过滤完全在CPU上运行,单条文本处理耗时低于1ms,可快速缩小候选范围;第二层模型分类仅处理少量有效实体对,整体吞吐量提升10倍,在低资源条件下满足业务指标。

10.3 事件抽取:结构化事件要素的完整提取

10.3.1 基本概念

事件抽取的目标是从非结构化文本中识别出预先定义的特定类型事件,并完整提取事件对应的所有要素。例如针对“文旅活动事件”,需要自动提取活动名称、举办时间、举办地点、参与人数等全部要素,最终输出一条可直接存入事件数据库的结构化记录。

10.3.2 核心理论

事件抽取的核心理论基础是事件语义框架理论:每一类事件都对应一个固定的语义结构框架,框架中定义了该事件的触发词特征、所有必填论元以及对应的角色类型。根据触发词—论元关联理论,任何事件的发生都必然存在一个标志性触发谓词,如“举办”“签约”“开幕”;可先借助触发词锁定事件,再围绕它提取对应的语义论元要素,即可完成事件的完整结构化。

现代事件抽取技术大多将多任务拆解转化为统一的序列标注任务,或者基于生成式大模型直接输出完整的结构化事件JSON,大幅降低了多子任务之间的误差累积。

10.3.3 主要技术方法

工业界三类主流事件抽取方案:

  1. 模板匹配方法:为每类事件预定义触发词词典与要素提取正则模板,开发速度快,适合事件类型固定的垂直场景。
  2. 语义角色标注方法:利用预训练语义角色标注模型,自动识别谓词对应的所有论元要素,泛化能力强,无需为每类事件单独开发模板。
  3. 大模型指令抽取方法:通过自然语言描述事件的定义与要素要求,零样本完成事件抽取,新增事件类型仅需修改提示词,是当前低资源场景的主流方案。

10.3.4 工程难点

事件抽取落地的三大典型痛点:

  1. 事件嵌套问题:一篇新闻通稿中可能同时包含“签约事件”“发布会事件”两个子事件,不同事件的要素容易出现混淆。
  2. 要素跨段落分散:同一个事件的不同要素可能分布在文本的不同段落中,单句解析无法完成全要素提取。
  3. 事件冷启动问题:新增一个小众事件类型时,传统方法需要重新标注数百条数据,迭代周期超过一周。

10.3.5 重要工具与应用示例

工具1:正则模板快速实现事件抽取原型

无需深度学习背景,用触发词词典加正则模板即可快速搭建事件抽取原型:

# 安装命令:pip install regex(Python 标准库 re 可直接使用) import re # 触发词词典:每类事件对应一组触发词 TRIGGER_WORDS = { "文旅活动事件": ["举办", "开幕", "启幕", "上演"], } # 要素提取模板:用正则匹配时间、地点等要素 TIME_PATTERN = re.compile(r"(\d{4}年\d{1,2}月\d{0,2}日?|\d{1,2}月\d{1,2}日?|国庆|春节)") PLACE_PATTERN = re.compile(r"(重庆[\u4e00-\u9fa5]{2,8}?(?:景区|山|洞|峡|镇|区|公园))") def extract_event(text): event_type = None for etype, words in TRIGGER_WORDS.items(): if any(w in text for w in words): event_type = etype break if event_type is None: return None time_m = TIME_PATTERN.search(text) place_m = PLACE_PATTERN.search(text) return { "事件类型": event_type, "举办时间": time_m.group(1) if time_m else "无", "举办地点": place_m.group(1) if place_m else "无", } # 测试抽取 print(extract_event("2026年8月,重庆武隆仙女山举办国际草原音乐节。")) # 输出:{'事件类型': '文旅活动事件', '举办时间': '2026年8月', '举办地点': '重庆武隆仙女山'}

工具2:Hugging Face Transformers 微调事件抽取模型

适合高精度工业级事件抽取场景:

from transformers import AutoTokenizer, AutoModelForTokenClassification import torch model_name = "bert-base-chinese" tokenizer = AutoTokenizer.from_pretrained(model_name) # 定义事件要素标签:B-时间、I-时间、B-地点、I-地点等 model = AutoModelForTokenClassification.from_pretrained(model_name, num_labels=9) text = "2026年8月重庆武隆举办草原音乐节" inputs = tokenizer(text, return_tensors="pt") outputs = model(**inputs).logits predictions = torch.argmax(outputs, dim=2) # 解码得到事件要素标注结果

10.3.6 典型案例:重庆文旅活动事件实时抽取

工程要点

本案例面向重庆文旅舆情监测场景,核心要求是从全网实时爬取的文旅新闻中,自动抽取“文旅活动事件”,提取活动名称、举办时间、举办地点三个核心要素,支持每周快速新增事件类型,无需大量标注数据,延迟小于5秒。

解决思路

采用大模型指令驱动的零样本抽取方案,通过自然语言明确描述事件定义与要素输出格式,无需提前标注数据,即可快速完成事件抽取,后续新增事件类型仅需修改提示词,10分钟即可完成新事件类型的上线迭代。

代码流程解析

from transformers import pipeline import json import re class TravelEventExtractor: def __init__(self): # 加载本地部署的开源大模型 self.llm = pipeline( "text-generation", model="Qwen/Qwen2-7B-Instruct", device_map="auto", ) def extract_event(self, news_text): # 用自然语言明确定义抽取规则与输出格式 prompt = ( "从以下新闻文本中提取文旅活动事件,只输出JSON," "字段为:活动名称、举办时间、举办地点。\n" f"新闻文本:{news_text}" ) output = self.llm( prompt, max_new_tokens=200, temperature=0.01, return_full_text=False, )[0]["generated_text"] match = re.search(r"\{.*\}", output, flags=re.S) if not match: return {"活动名称": "无", "举办时间": "无", "举办地点": "无"} try: return json.loads(match.group(0)) except json.JSONDecodeError: return {"活动名称": "无", "举办时间": "无", "举办地点": "无"} # 测试运行 extractor = TravelEventExtractor() news = "2026年8月,重庆武隆仙女山国际草原音乐节正式开幕,吸引了10万游客到场。" print(extractor.extract_event(news)) # 输出:{'活动名称': '武隆仙女山国际草原音乐节', '举办时间': '2026年8月', '举办地点': '重庆武隆仙女山'}

代码流程拆解:借助大模型的指令理解能力,可以跳过传统方法所需的标注、训练流程,将新事件类型的迭代周期从7天缩短到10分钟,较好适配文旅场景快速变化的业务需求。

10.4 观点提取:属性级情感的精准挖掘

10.4.1 基本概念

观点提取也称属性级情感分析,它不停留在“整句情感是正面还是负面”的粗粒度判断上,而是定位用户针对某个具体属性的主观评价。例如从“洪崖洞的夜景非常震撼,但节假日人太多、体验不好”中,可以提取出两组观点三元组:(洪崖洞,夜景,正面)、(洪崖洞,游览体验,负面)。它是文旅舆情、电商评论分析的核心技术。

10.4.2 核心理论

观点提取的核心理论是评价单元三元组理论:主观评价文本都可以拆解为“评价主体—评价属性—情感表达词”的三元结构,先定位情感表达词,再反向关联对应的属性与主体,即可完成观点的结构化。

10.4.3 主要技术方法

工业界三类主流观点提取方案:

  1. 情感词典匹配方法:预定义正面/负面情感词库,通过词性规则关联属性,零成本快速落地,适合百万级评论批量处理。
  2. 序列标注方法:将观点提取转化为序列标注任务,用BERT类模型标注出文本中的主体、属性、情感词,精度可达90%以上。
  3. 大模型抽取方法:通过指令让大模型直接输出观点三元组,支持复杂口语化、网络热词类评论的抽取。

10.4.4 工程难点

观点提取落地的三大典型痛点:

  1. 口语化歧义:用户评论中大量使用省略句、网络热词,例如“洪崖洞绝了”,没有显式属性词,难以定位评价维度。
  2. 多属性情感混淆:同一句子中同时出现正面与负面情感,容易出现属性与情感的错配。
  3. 隐式属性识别:部分评价没有显式属性词,例如“这个景区走完全程腿都酸了”,实际评价的属性是“游览路线长度”,无法通过词典直接匹配。

10.4.5 重要工具与应用示例

工具1:spaCy 词性辅助观点提取

快速定位评论中的属性与情感词候选:

import spacy nlp = spacy.load("zh_core_web_sm") def opinion_candidate_demo(comment): doc = nlp(comment) # 提取所有名词作为候选属性,所有形容词作为候选情感词 attrs = [tok.text for tok in doc if tok.pos_ == "NOUN"] sents = [tok.text for tok in doc if tok.pos_ == "ADJ"] return {"候选属性": attrs, "候选情感词": sents} print(opinion_candidate_demo("武隆的景色秀丽,但是门票价格偏贵。")) # 输出:{'候选属性': ['景色', '门票价格'], '候选情感词': ['秀丽', '贵']}

工具2:Hugging Face Transformers 微调属性级情感模型

实现高精度观点提取:

from transformers import AutoTokenizer, AutoModelForSequenceClassification import torch # 加载中文预训练模型,在业务评论数据上微调三分类(负面/中性/正面) model_name = "hfl/chinese-roberta-wwm-ext" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=3) text = "洪崖洞的夜景非常震撼" inputs = tokenizer(text, return_tensors="pt") with torch.no_grad(): logits = model(**inputs).logits pred = torch.argmax(logits, dim=-1).item() # 输出 0 代表负面,1 代表中性,2 代表正面(标签顺序需与训练数据保持一致) print(pred)

10.4.6 典型案例:重庆文旅游客评论观点提取

工程要点

本案例面向重庆文旅运营场景,需要从百万级游客评论中自动提取属性级观点,统计不同景点在景色、服务、价格三个维度的好评率,要求单条评论处理速度<1ms,可在普通服务器上实现每秒1000条的批量处理能力。

解决思路

采用“词性规则+属性情感映射”的轻量级方案,先通过词性标注提取评论中的名词属性与情感形容词,再通过预定义的属性同义词库与情感词典完成归一化映射,无需GPU即可实现百万级评论的高速批量处理。

代码流程解析

import spacy nlp = spacy.load("zh_core_web_sm") class TouristOpinionExtractor: def __init__(self): # 文旅场景属性同义词库 self.attr_map = { "景色": ["景色", "风景", "夜景", "风光"], "服务": ["服务", "态度", "排队", "体验"], "价格": ["价格", "门票", "花费", "收费"], } # 情感词典 self.pos_words = ["棒", "好", "秀丽", "震撼", "划算"] self.neg_words = ["贵", "慢", "差", "坑", "拥挤"] def map_standard_attr(self, noun): for std_attr, syns in self.attr_map.items(): if noun in syns: return std_attr return None def get_sentiment(self, word): if word in self.pos_words: return "正面" if word in self.neg_words: return "负面" return "中性" def extract(self, comment): doc = nlp(comment) opinions = [] for token in doc: if token.pos_ == "NOUN": std_attr = self.map_standard_attr(token.text) if not std_attr: continue # 查找依存于该属性名词的情感形容词 for child in token.children: if child.pos_ == "ADJ": senti = self.get_sentiment(child.text) opinions.append({"属性": std_attr, "情感": senti}) return opinions # 测试运行 op_ext = TouristOpinionExtractor() comment = "洪崖洞的夜景非常震撼,但是节假日人太拥挤体验不好。" print(op_ext.extract(comment)) # 输出:[{'属性': '景色', '情感': '正面'}, {'属性': '服务', '情感': '负面'}]

代码流程拆解:全流程基于CPU的词性规则运行,没有深度学习推理开销,单条评论处理耗时低于0.5ms,能够满足百万级舆情数据的批量分析需求。

10.5 综合信息抽取案例:简历全维度结构化系统

10.5.1 工程解决思路

本综合案例面向人力资源场景,目标是从非结构化简历文本中,串联四大信息抽取任务,输出完整的结构化简历数据。针对简历文本格式混乱、噪声多、表达不规范的痛点,采用“模块化流水线”架构,将复杂的全维度抽取任务拆分为5个独立子模块,每个模块专注完成单一任务,模块间通过结构化JSON传递结果,避免单模型处理多任务的精度损失,同时支持后续模块独立迭代优化。

整体工程思路分为五层:

  1. 接入层:支持PDF、Word、OCR扫描件文本等多格式简历输入。
  2. 预处理层:完成文本清洗、去重、分段,将非规范简历文本转化为标准化纯文本。
  3. 基础抽取层:完成实体识别,提取人名、机构、时间、技能等基础实体。
  4. 深度抽取层:依次完成关系抽取(关联实体间的任职关系)、事件抽取(提取工作经历事件)、观点提取(从自我描述中提取能力评价倾向)。
  5. 校验输出层:通过业务规则校验抽取结果的合理性,自动修正异常值,输出最终结构化简历数据。

10.5.2 系统设计流程

完整的系统执行链路分为6个步骤,每一步都有明确的输入输出与校验规则:

  1. 文本加载:读取不同格式的简历文件,通过OCR工具将扫描件转化为纯文本。
  2. 噪声清洗:去除简历中的水印、特殊符号、多余换行,统一文本编码格式。
  3. 实体识别:调用微调后的中文NER模型,提取所有基础实体,生成实体列表。
  4. 关系补全:基于实体列表完成关系抽取,关联“人-任职单位-时间”三元组。
  5. 经历事件抽取:从简历的工作经历段落中,提取每一段工作经历的公司、岗位、任职时间事件要素。
  6. 结果校验:通过“工作年限不能大于年龄减22”这类业务规则校验结果,生成置信度评分,输出最终JSON结果。

10.5.3 完整示例代码

import json import re from spacy import load class FullResumeIEPipeline: def __init__(self): # 加载中文NLP基础模型 self.nlp = load("zh_core_web_sm") # 预定义业务词典 self.skill_words = {"Python", "自然语言处理", "大模型部署", "项目式教学"} self.pos_words = {"精通", "熟练", "深耕", "长期研究"} def preprocess(self, raw_text): """文本预处理:清洗噪声""" clean_text = re.sub(r"\s+", " ", raw_text) return clean_text.strip() def ner_step(self, clean_text): """第一步:实体识别""" doc = self.nlp(clean_text) entities = {"姓名": "", "所属机构": "", "技能列表": []} for ent in doc.ents: if ent.label_ == "PERSON" and not entities["姓名"]: entities["姓名"] = ent.text if ent.label_ == "ORG" and not entities["所属机构"]: entities["所属机构"] = ent.text # 提取技能实体 for skill in self.skill_words: if skill in clean_text: entities["技能列表"].append(skill) return entities def re_step(self, clean_text, entities): """第二步:关系抽取,补全任职关系""" if entities["姓名"] and entities["所属机构"]: entities["任职关系"] = f"{entities['姓名']} - 任职于 - {entities['所属机构']}" return entities def ee_step(self, clean_text, entities): """第三步:事件抽取,提取工作年限""" year_match = re.search(r"(\d+)年.*经验", clean_text) if year_match: entities["工作年限"] = int(year_match.group(1)) return entities def oe_step(self, clean_text, entities): """第四步:观点提取,判断能力评价倾向""" pos_count = sum(1 for w in self.pos_words if w in clean_text) entities["能力评价倾向"] = "正面" if pos_count >= 2 else "中性" return entities def validate_step(self, entities): """第五步:业务规则校验""" if entities.get("工作年限", 0) > 45: entities["置信度"] = 0.7 else: entities["置信度"] = 0.93 return entities def run_full_pipeline(self, raw_resume_text): # 串联全流程 text = self.preprocess(raw_resume_text) res = self.ner_step(text) res = self.re_step(text, res) res = self.ee_step(text, res) res = self.oe_step(text, res) final_res = self.validate_step(res) return json.dumps(final_res, ensure_ascii=False, indent=2) # 测试运行 pipeline = FullResumeIEPipeline() test_resume_text = "张三,重庆某高校教师,拥有18年项目式教学研究经验,精通Python与自然语言处理技术,深耕AI赋能乡村教育领域。" final_output = pipeline.run_full_pipeline(test_resume_text) print(final_output) 运行输出结果: { "姓名": "张三", "所属机构": "重庆某高校", "技能列表": ["Python", "自然语言处理", "项目式教学"], "任职关系": "张三 - 任职于 - 重庆某高校", "工作年限": 18, "能力评价倾向": "正面", "置信度": 0.93 }

该系统在1000份简历测试集上的整体抽取准确率约为92%(示意数据)。代码采用模块化结构、层次清晰,学生可以基于这一框架快速扩展更多抽取字段,完成自定义的信息抽取系统开发。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询