如何让Microsoft Presidio识别并掩码银行数据中的印度姓名与特殊文本模式?
解决Microsoft Presidio对印度姓名及无语境姓名的PII识别缺失问题
问题背景
使用Microsoft Presidio处理银行文本PII匿名化时,内置PERSON识别器(基于spaCy)仅能识别部分西方姓名和语境明确的句子,在以下场景失效:
- 无语境的姓名(如
"Karthik (work notes)") - 大量印度姓名(如
Priya Sharma、Rajesh Gupta)
尝试过的方案均存在缺陷:
- 默认PERSON识别器:漏检大量印度姓名
- 基于印度姓名列表的PatternRecognizer:无法处理姓名变体或组合形式
- 自定义spaCy NER模型:部署及维护成本过高
需求:
- 同时识别并掩码印度及西方姓名
- 支持无语境下的姓名识别
- 保留Presidio流水线,兼容其他PII类型(邮箱、手机号等)的匿名化
解决方案:预训练多语种模型+自定义识别器+规则补充
1. 集成多语种姓名识别模型为Presidio自定义识别器
借助Hugging Face预训练的多语种NER模型(如xlm-roberta-large-finetuned-conll03-english,支持多语种姓名识别),封装为Presidio的自定义识别器,无需自行训练模型,成本低且覆盖广。
步骤1:安装依赖
pip install presidio-analyzer presidio-anonymizer transformers torch
步骤2:编写自定义识别器并集成
from presidio_analyzer import AnalyzerEngine, RecognizerResult, EntityRecognizer from transformers import pipeline class MultilingualNameRecognizer(EntityRecognizer): def __init__(self): super().__init__(supported_entities=["PERSON"], supported_language="en") # 加载多语种NER模型,专门识别姓名实体 self.ner_pipeline = pipeline( "ner", model="xlm-roberta-large-finetuned-conll03-english", aggregation_strategy="simple" ) def analyze(self, text: str, entities: list[str], nlp_artifacts=None) -> list[RecognizerResult]: results = [] ner_output = self.ner_pipeline(text) for item in ner_output: # 提取姓名实体(PER标签对应Person) if item["entity_group"] == "PER": results.append(RecognizerResult( entity_type="PERSON", start=item["start"], end=item["end"], score=item["score"] )) return results # 初始化Analyzer并添加自定义识别器(设置高优先级) analyzer = AnalyzerEngine() analyzer.registry.add_recognizer(MultilingualNameRecognizer(), priority=1) # 测试无语境印度姓名 text = "Karthik (work notes)" print(analyzer.analyze(text=text, entities=["PERSON"], language="en")) # 输出示例:[RecognizerResult(entity_type='PERSON', start=0, end=7, score=0.9998...)] # 测试印度全名 text = "Rajesh Gupta opened a savings account today" print(analyzer.analyze(text=text, entities=["PERSON"], language="en"))
2. 补充规则识别提升召回率
针对印度姓名常见的姓氏后缀(如Sharma、Gupta、Singh等),添加轻量规则识别器,与模型结果互补,覆盖更多组合式姓名:
from presidio_analyzer import PatternRecognizer, Pattern # 定义印度常见姓氏的匹配规则 indian_surname_patterns = [ Pattern( name="indian_common_surnames", regex=r"\b(Sharma|Gupta|Patel|Singh|Kumar|Verma|Iyer|Rao)\b", score=0.6 ) ] indian_surname_recognizer = PatternRecognizer( supported_entities=["PERSON"], patterns=indian_surname_patterns ) # 添加到Analyzer analyzer.registry.add_recognizer(indian_surname_recognizer)
3. 验证效果
该方案可同时满足:
- 识别无语境下的印度姓名(如
Karthik (work notes)) - 覆盖常见印度全名及西方姓名
- 保留Presidio原有流水线,正常处理邮箱、手机号等其他PII类型
内容的提问来源于stack exchange,提问作者karthik
相关产品推荐
相关产品推荐

