SiameseUIE保姆级教程:test.py中正则规则扩展时间/机构字段

1. 引言

当你第一次接触信息抽取任务时,可能会被各种复杂的模型和配置搞得头晕眼花。特别是面对历史文档、新闻稿件或者社交媒体内容时,如何快速准确地提取出关键信息,一直是个让人头疼的问题。

今天我要介绍的SiameseUIE模型,就是一个专门解决这个问题的利器。它能够从杂乱无章的文本中,精准地抽取出人物、地点等关键信息,而且结果干净利落,没有冗余内容。

本教程的重点是教你如何在现有的test.py脚本中,扩展正则规则来支持时间和机构字段的抽取。无论你是刚入门的新手,还是有一定经验的开发者,都能通过这篇教程快速上手。

学完本教程你能掌握

  • 理解SiameseUIE模型的基本工作原理
  • 掌握test.py脚本中正则规则的扩展方法
  • 学会添加时间和机构字段的抽取功能
  • 能够自定义测试用例验证扩展效果

2. 环境准备与快速部署

2.1 环境确认

首先确保你已经部署了SiameseUIE模型镜像。这个镜像最大的优点就是开箱即用,不需要安装任何额外的依赖包。

登录你的云实例后,检查当前环境:

# 检查当前Python环境
python --version

# 检查PyTorch版本
python -c "import torch; print(torch.__version__)"

# 激活torch28环境(如果尚未激活)
source activate torch28

2.2 进入工作目录

按照镜像的默认路径设置,你需要依次执行以下命令:

# 回到上级目录
cd ..

# 进入模型工作目录
cd nlp_structbert_siamese-uie_chinese-base

# 查看目录内容
ls -la

你应该能看到以下核心文件:

  • vocab.txt - 分词器词典文件
  • pytorch_model.bin - 模型权重文件
  • config.json - 模型配置文件
  • test.py - 我们要修改的测试脚本

3. 理解test.py的核心结构

3.1 脚本整体架构

在开始修改之前,我们先来了解一下test.py脚本的基本结构:

# 依赖屏蔽部分(重要!不要修改)
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

# 模型加载部分
from transformers import BertTokenizer, BertModel
tokenizer = BertTokenizer.from_pretrained('.')
model = BertModel.from_pretrained('.')

# 实体抽取函数
def extract_pure_entities(text, schema, custom_entities=None):
    # 这里是核心的实体抽取逻辑
    pass

# 测试用例定义
test_examples = [
    # 现有的5个测试用例
]

# 主执行逻辑
if __name__ == '__main__':
    # 遍历测试用例并执行抽取
    for example in test_examples:
        results = extract_pure_entities(
            text=example['text'],
            schema=example['schema'],
            custom_entities=example.get('custom_entities')
        )
        print(f"抽取结果:{results}")

3.2 现有的正则规则

当前脚本中已经包含了一些基础的正则规则,主要用于抽取人物和地点:

# 在extract_pure_entities函数中查找这部分代码
if custom_entities is None:
    # 通用规则模式
    person_pattern = r'[^,。!?;]{2,3}(?=先生|女士|老师|教授|医生|院士)'
    location_pattern = r'[^,。!?;]+?(?:省|市|县|区|镇|乡|村|街道|路|巷)'
    
    # 应用正则规则进行抽取
    persons = re.findall(person_pattern, text)
    locations = re.findall(location_pattern, text)

4. 扩展时间和机构字段的正则规则

4.1 时间字段正则规则

时间信息的格式比较多样,我们需要设计能够覆盖常见情况的规则:

# 时间正则规则
time_pattern = r'''
    (?:
        # 年月日格式:2023年12月31日、2023-12-31、2023/12/31
        (?:\d{4}[-/年])?(?:\d{1,2})[-/月](?:\d{1,2})日?
        |
        # 相对时间:昨天、今天、明天、上周、下周
        (?:今天|明天|昨天|前天|后天|大后天|上周|本周|下周|上月|本月|下月|今年|明年|去年)
        |
        # 具体时间:10:30、下午3点、晚上8点半
        (?:(?:上午|下午|晚上|凌晨)?(?:\d{1,2}[:时]\d{1,2}(?:分|分钟)?)|(?:\d{1,2}点(?:\d{1,2}分)?))
        |
        # 日期范围:2023年至2024年、1月到3月
        (?:\d{4}年?(?:至|到|-)\d{4}年?|(?:\d{1,2}月?(?:至|到|-)\d{1,2}月))
    )
'''

4.2 机构字段正则规则

机构名称的识别相对复杂,需要结合常见后缀和上下文:

# 机构正则规则
organization_pattern = r'''
    (?:
        # 公司企业:科技有限公司、有限公司、集团公司
        [\u4e00-\u9fa5]{2,20}?(?:公司|集团|有限|科技|技术|信息|网络|互联|软件|数据)
        |
        # 政府机构:人民政府、市政府、公安局、教育局
        [\u4e00-\u9fa5]{2,20}?(?:政府|局|厅|部|委|办|处|所|院)
        |
        # 教育机构:大学、学院、中学、小学、幼儿园
        [\u4e00-\u9fa5]{2,20}?(?:大学|学院|学校|中学|小学|幼儿园)
        |
        # 医疗机构:医院、卫生院、诊所、疾控中心
        [\u4e00-\u9fa5]{2,20}?(?:医院|卫生院|诊所|疾控中心|保健院)
        |
        # 其他组织:协会、学会、基金会、委员会
        [\u4e00-\u9fa5]{2,20}?(?:协会|学会|基金会|委员会|联合会)
    )
'''

4.3 修改extract_pure_entities函数

现在我们需要修改核心的实体抽取函数,加入对新字段的支持:

def extract_pure_entities(text, schema, custom_entities=None):
    """
    增强版的实体抽取函数,支持时间、机构字段
    """
    import re
    
    results = {}
    
    if custom_entities is not None:
        # 自定义实体模式(原有逻辑)
        for entity_type, entity_list in custom_entities.items():
            if entity_list:
                found_entities = []
                for entity in entity_list:
                    if entity in text:
                        found_entities.append(entity)
                results[entity_type] = found_entities
    else:
        # 通用规则模式(扩展后的逻辑)
        # 人物抽取
        person_pattern = r'[^,。!?;]{2,3}(?=先生|女士|老师|教授|医生|院士)'
        persons = re.findall(person_pattern, text)
        if persons:
            results['人物'] = persons
        
        # 地点抽取  
        location_pattern = r'[^,。!?;]+?(?:省|市|县|区|镇|乡|村|街道|路|巷)'
        locations = re.findall(location_pattern, text)
        if locations:
            results['地点'] = locations
        
        # 时间抽取(新增)
        time_pattern = r'(?:\d{4}[-/年])?(?:\d{1,2})[-/月](?:\d{1,2})日?|(?:今天|明天|昨天|上周|下周|本月|下月)|(?:\d{1,2}[:时]\d{1,2}(?:分)?)|(?:\d{1,2}点(?:\d{1,2}分)?)'
        times = re.findall(time_pattern, text)
        if times:
            results['时间'] = times
        
        # 机构抽取(新增)
        organization_pattern = r'[\u4e00-\u9fa5]{2,20}?(?:公司|集团|有限|科技|政府|局|厅|部|大学|学院|学校|医院|协会|基金会)'
        organizations = re.findall(organization_pattern, text)
        if organizations:
            results['机构'] = organizations
    
    return results

5. 添加测试用例验证扩展效果

5.1 创建新的测试用例

为了验证我们的扩展是否有效,需要在test_examples中添加包含时间和机构的测试用例:

# 在test_examples列表中添加新的测试用例
test_examples = [
    # 原有的5个测试用例保持不变...
    
    # 新增:包含时间信息的用例
    {
        "name": "例子6:时间信息抽取",
        "text": "会议将于2023年12月15日下午2点在北京召开,请各位准时参加。",
        "schema": {"人物": None, "地点": None, "时间": None, "机构": None},
        "custom_entities": None
    },
    
    # 新增:包含机构信息的用例  
    {
        "name": "例子7:机构信息抽取",
        "text": "阿里巴巴集团和腾讯科技有限公司都是知名的互联网企业。",
        "schema": {"人物": None, "地点": None, "时间": None, "机构": None},
        "custom_entities": None
    },
    
    # 新增:混合信息用例
    {
        "name": "例子8:混合信息抽取",
        "text": "2023年10月1日,张三参加了清华大学举办的学术会议,会议地点在北京大学。",
        "schema": {"人物": None, "地点": None, "时间": None, "机构": None},
        "custom_entities": None
    }
]

5.2 修改输出显示逻辑

为了让输出结果更清晰,我们需要修改结果显示部分:

# 在主循环中修改输出格式
for i, example in enumerate(test_examples, 1):
    print(f"\n========== {i}. {example['name']} ==========")
    print(f"文本:{example['text']}")
    
    extract_results = extract_pure_entities(
        text=example["text"],
        schema=example["schema"],
        custom_entities=example.get("custom_entities")
    )
    
    print("抽取结果:")
    for entity_type, entities in extract_results.items():
        if entities:
            print(f"  - {entity_type}:{', '.join(entities)}")
    
    print("-" * 40)

6. 完整测试与验证

6.1 运行测试脚本

保存所有修改后,运行测试脚本查看效果:

python test.py

你应该能看到类似这样的输出:

========== 6. 例子6:时间信息抽取 ==========
文本:会议将于2023年12月15日下午2点在北京召开,请各位准时参加。
抽取结果:
  - 时间:2023年12月15日, 下午2点
  - 地点:北京
----------------------------------------

========== 7. 例子7:机构信息抽取 ==========
文本:阿里巴巴集团和腾讯科技有限公司都是知名的互联网企业。
抽取结果:
  - 机构:阿里巴巴集团, 腾讯科技有限公司
----------------------------------------

========== 8. 例子8:混合信息抽取 ==========
文本:2023年10月1日,张三参加了清华大学举办的学术会议,会议地点在北京大学。
抽取结果:
  - 人物:张三
  - 时间:2023年10月1日
  - 机构:清华大学, 北京大学
----------------------------------------

6.2 常见问题排查

如果遇到抽取结果不准确的情况,可以按照以下步骤排查:

  1. 正则规则太严格或太宽松:调整正则表达式中的匹配模式
  2. 文本格式特殊:检查是否需要添加新的匹配规则
  3. 编码问题:确保文本使用UTF-8编码
# 调试用的正则测试代码
test_text = "你的测试文本"
pattern = "你的正则表达式"

import re
matches = re.findall(pattern, test_text)
print(f"匹配结果:{matches}")

7. 进阶使用建议

7.1 优化正则规则

根据实际应用场景,你可以进一步优化正则规则:

# 更精确的时间匹配规则
advanced_time_pattern = r'''
    (?:
        # 完整日期:2023年12月31日 14:30
        \d{4}年\d{1,2}月\d{1,2}日\s*\d{1,2}[:时]\d{1,2}
        |
        # 日期范围:2023-2024年度
        \d{4}[-至到]\d{4}年?
        |
        # 季度信息:第一季度、Q2
        (?:第[一二三四]季度|Q[1-4])
    )
'''

# 更准确的机构识别
advanced_org_pattern = r'''
    (?:
        # 排除常见误匹配
        (?!公司简介|公司公告|公司动态)
        [\u4e00-\u9fa5]{2,20}?
        (?:公司|集团|有限|科技|研究院|研究所|实验室|中心)
    )
'''

7.2 处理复杂场景

对于更复杂的场景,可以考虑使用规则组合的方式:

def enhance_entity_recognition(text):
    """
    增强的实体识别函数,结合多种规则
    """
    results = {}
    
    # 第一轮:基础正则匹配
    base_results = extract_pure_entities(text, None, None)
    
    # 第二轮:上下文修正
    for entity_type, entities in base_results.items():
        filtered_entities = []
        for entity in entities:
            if is_valid_entity(entity, entity_type, text):
                filtered_entities.append(entity)
        results[entity_type] = filtered_entities
    
    return results

def is_valid_entity(entity, entity_type, context):
    """
    基于上下文验证实体是否有效
    """
    if entity_type == '时间':
        # 检查时间实体的合理性
        return len(entity) >= 3  # 时间实体通常至少3个字符
    
    elif entity_type == '机构':
        # 检查机构名称的常见特征
        return not any(word in entity for word in ['的', '了', '在', '和'])
    
    return True

8. 总结

通过本教程,你已经学会了如何在SiameseUIE模型的test.py脚本中扩展正则规则,新增时间和机构字段的抽取功能。让我们回顾一下重点:

主要收获

  • 理解了test.py脚本的基本结构和运行原理
  • 学会了编写针对时间和机构的正则匹配规则
  • 掌握了如何修改实体抽取函数来支持新字段
  • 能够创建测试用例来验证扩展效果

实用建议

  1. 正则规则要循序渐进,从简单到复杂逐步优化
  2. 多准备一些测试用例,覆盖各种边界情况
  3. 在实际应用中,可以根据具体领域调整规则
  4. 记得备份原文件,避免修改出错无法恢复

下一步学习方向

  • 探索更复杂的实体识别算法
  • 学习如何评估抽取结果的准确性
  • 了解如何将抽取结果保存到数据库或文件中
  • 研究如何与其他NLP技术结合使用

现在你已经具备了扩展信息抽取功能的能力,可以尝试在自己的项目中应用这些技术了。记得多实践、多调试,逐步优化你的正则规则,让抽取效果越来越精准。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐