基于大模型的长文本中文姓名精准提取

4 阅读4分钟

问题背景

某些数据因为要对外提供,所以对敏感信息要脱敏,电话号码、身份证等信息有规则可以匹配,但是姓名就比较难,特别是在一个长文本中提取姓名然后做到精准脱敏,就有点难度,不过现在大模型发展比较快,利用大模型来姓名提取就比较好用。

通过咨询市面上的大模型如何选择可以使用的姓名提取模型,并进行使用和比对,敲定了一个落地方案,就是使用RaNER(Robust Named Entity Recognition)模型,这是达摩院专为中文优化的命名实体识别框架,在准确率、鲁棒性和部署便捷性方面均表现突出,特别适合中文姓名识别场景。

现在介绍一下该模型的安装测试,供大家参考使用。

RaNER模型使用流程

我已经在本机电脑安装了Conda环境,所以测试环境就用Conda简单方便。

创建环境

conda创建虚拟环境

conda create -n chinese-ner python=3.9
conda activate chinese-ner

安装核心依赖

pip install modelscope transformers torch numpy

代码需要使用到依赖,安装一下

pip install addict==2.4.0

pip install datasets==2.21.0

pip install Pillow

pip install simplejson

pip install sortedcontainers

测试代码

from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks

# 初始化RaNER模型管道
ner_pipeline = pipeline(
    task=Tasks.named_entity_recognition,
    model='damo/nlp_raner_named-entity-recognition_chinese-base-news'
)

# 测试示例
text = "马云在杭州阿里巴巴总部宣布,公司将在上海设立新的研发中心,并与北京大学展开合作。"
result = ner_pipeline(input=text)

# 提取姓名实体
person_entities = [entity for entity in result['output'] if entity['type'] == 'PER']
print("识别到的姓名:", [entity['span'] for entity in person_entities])

返回结果

识别到的姓名: ['马云']

因为部分数据文本中存在HTML标签,所以还需要去除HTML标签,需要加入处理文本的函数。

安装beautifulsoup4来处理标签

pip install beautifulsoup4

测试代码

from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
from bs4 import BeautifulSoup
import re

# ==========================================
# 1. 初始化 NER 模型
# ==========================================
print("正在加载模型,请稍候...")
ner_pipeline = pipeline(
    task=Tasks.named_entity_recognition,
    model='damo/nlp_raner_named-entity-recognition_chinese-base-news'
)

# ==========================================
# 2. 定义 HTML 清洗函数
# ==========================================
def clean_html(html_text):
    """
    使用 BeautifulSoup 去除 HTML 标签,并规范化空白字符
    """
    # 使用 'html.parser' 解析器
    soup = BeautifulSoup(html_text, 'html.parser')
    
    # 获取文本内容
    text = soup.get_text(separator=' ')
    
    # 简单的后处理:去除多余的空行和空格
    # \s+ 匹配所有空白字符(空格、换行、制表符),替换为单个空格
    text = re.sub(r'\s+', ' ', text).strip()
    
    return text

# ==========================================
# 3. 定义长文本分段函数
# ==========================================
def split_text(text, max_length=500):
    """
    将长文本按句子分割,避免超过模型限制 (512)
    """
    # 按中文句号、感叹号、问号分割,保留分隔符
    sentences = re.split(r'(?<=[。!?])', text)
    
    chunks = []
    current_chunk = ""
    
    for sentence in sentences:
        if len(current_chunk) + len(sentence) <= max_length:
            current_chunk += sentence
        else:
            if current_chunk:
                chunks.append(current_chunk)
            current_chunk = sentence
            
    if current_chunk:
        chunks.append(current_chunk)
        
    return chunks

# ==========================================
# 4. 你的原始 HTML 数据
# ==========================================
text = """
<div style="font-family: 宋体;">
    <h2>中标通知书</h2>
    <p>项目编号:ZJ-2026-TEST</p>
    <p>项目名称:非常智慧的改造工程</p>
    <hr>
    <table border="1" style="border-collapse: collapse; width: 100%;">
        <thead>
            <tr>
                <th>中标单位</th>
                <th>项目经理</th>
                <th>中标金额</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>浙江大聪明有限公司</td>
                <td>章天</td>
                <td>1250.00万元</td>
            </tr>
        </tbody>
    </table>
    <p>
        特此通知。
        <br>
        招标人代表:<b>李大牛</b>
        <br>
        技术顾问:<b>陈三明</b>
    </p>
</div>
"""


# 1. 先清洗数据
cleaned_text = clean_html(text)
# 2. 再将清洗后的文本传入模型
result = ner_pipeline(input=cleaned_text)

# 提取姓名实体
person_entities = [entity for entity in result['output'] if entity['type'] == 'PER']
print("识别到的姓名:", [entity['span'] for entity in person_entities])

返回结果

识别到的姓名: ['章天 ', '李大牛', '陈三明']

传统方法 vs RaNER 对比

你可以直接加入这段,提升文章深度:

  • Jieba 分词:依赖词典,无法理解上下文,复姓、生僻名、昵称容易漏识,误报率高,不适合脱敏。
  • 正则表达式:只能匹配固定规则姓名,无法处理真实文本中的复杂情况,长文本基本不可用。
  • 大模型:基于深度学习,具备上下文理解能力,鲁棒性强,支持生僻姓名、复姓、长文本、HTML 文本,识别精度高,是企业级脱敏的最优选择。

总结

在中文长文本的姓名提取与脱敏场景中,传统基于规则、词典的方法(如正则、Jieba 词性标注)存在明显短板:漏识别、误识别、无法处理复杂文本、不支持 HTML 格式、难以适应真实业务数据。这些问题会直接导致脱敏不彻底,带来数据安全风险。

通过实测对比,达摩院的 RaNER 模型 在中文命名实体识别任务中表现出显著优势:识别精度高、鲁棒性强、支持长文本推理、兼容 HTML 等非结构化数据、部署简单、运行稳定。它能够在复杂业务文档、公告、合同、报告等真实场景中,精准提取人名实体,为后续的敏感信息脱敏提供可靠支撑。

本文提供的 Conda 环境部署、HTML 清洗、长文本分段等完整方案,已经可以直接应用于实际业务,实现开箱即用、低成本、高可靠的中文姓名提取服务。