Осваиваем Microsoft Presidio: детекция и анонимизация персональных данных в тексте с практическими примерами
Изучите возможности Microsoft Presidio для обнаружения и анонимизации персональных данных в тексте с практическими примерами на Python, включая создание кастомных распознавателей и хеш-анонимизацию.
Введение в Microsoft Presidio
Microsoft Presidio — это открытая платформа для обнаружения, анализа и анонимизации персональных данных (PII) в неструктурированном тексте. Построенная на основе мощной библиотеки обработки естественного языка spaCy, Presidio имеет легковесную и модульную архитектуру, что позволяет легко интегрировать её в приложения и конвейеры обработки данных в реальном времени.
Установка Presidio и зависимостей
Для начала работы установите библиотеки presidio-analyzer и presidio-anonymizer, а также рекомендуемую модель spaCy для английского языка:
pip install presidio-analyzer presidio-anonymizer
python -m spacy download en_core_web_lgПри необходимости перезапустите рабочее окружение, особенно если вы используете Jupyter или Google Colab.
Базовое обнаружение PII с помощью Presidio Analyzer
AnalyzerEngine загружает NLP-пайплайн spaCy и встроенные распознаватели для поиска чувствительных данных, например, телефонных номеров. Пример обнаружения номера телефона в тексте с подавлением лишних логов:
import logging
logging.getLogger("presidio-analyzer").setLevel(logging.ERROR)
from presidio_analyzer import AnalyzerEngine
analyzer = AnalyzerEngine()
results = analyzer.analyze(text="My phone number is 212-555-5555",
entities=["PHONE_NUMBER"],
language='en')
print(results)Создание кастомных распознавателей с помощью deny-листов
Presidio позволяет создавать собственные распознаватели. Например, можно определить распознаватель для академических титулов, используя deny-лист:
from presidio_analyzer import AnalyzerEngine, PatternRecognizer, RecognizerRegistry
academic_title_recognizer = PatternRecognizer(
supported_entity="ACADEMIC_TITLE",
deny_list=["Dr.", "Dr", "Professor", "Prof."]
)
registry = RecognizerRegistry()
registry.load_predefined_recognizers()
registry.add_recognizer(academic_title_recognizer)
analyzer = AnalyzerEngine(registry=registry)
text = "Prof. John Smith is meeting with Dr. Alice Brown."
results = analyzer.analyze(text=text, language="en")
for result in results:
print(result)Также можно создавать распознаватели на основе регулярных выражений или использовать внешние модели, как описано в официальной документации.
Анонимизация PII с помощью Presidio Anonymizer
После обнаружения PII их можно анонимизировать. Пример замены имен на плейсхолдер:
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import RecognizerResult, OperatorConfig
engine = AnonymizerEngine()
result = engine.anonymize(
text="My name is Bond, James Bond",
analyzer_results=[
RecognizerResult(entity_type="PERSON", start=11, end=15, score=0.8),
RecognizerResult(entity_type="PERSON", start=17, end=27, score=0.8),
],
operators={"PERSON": OperatorConfig("replace", {"new_value": "BIP"})},
)
print(result)Доступны и другие методы анонимизации, включая редактирование, хеширование и псевдонимизацию.
Расширенные возможности: кастомные сущности и консистентная реанонимизация
Можно определить свои PII-сущности с помощью регулярных выражений и создать пользовательский анонимизатор, который хеширует данные и сохраняет сопоставления для консистентности.
Кастомный хеш-анонимайзер
Этот оператор использует SHA-256 и хранит соответствия для одинаковых значений:
from presidio_anonymizer.operators import Operator, OperatorType
import hashlib
from typing import Dict
class ReAnonymizer(Operator):
"""
Анонимайзер, заменяющий текст на повторно используемый SHA-256 хеш,
сохранённый в общем словаре сопоставлений.
"""
def operate(self, text: str, params: Dict = None) -> str:
entity_type = params.get("entity_type", "DEFAULT")
mapping = params.get("entity_mapping")
if mapping is None:
raise ValueError("Отсутствует параметр `entity_mapping` в params")
if entity_type in mapping and text in mapping[entity_type]:
return mapping[entity_type][text]
hashed = "<HASH_" + hashlib.sha256(text.encode()).hexdigest()[:10] + ">"
mapping.setdefault(entity_type, {})[text] = hashed
return hashed
def validate(self, params: Dict = None) -> None:
if "entity_mapping" not in params:
raise ValueError("Необходимо передать словарь 'entity_mapping'.")
def operator_name(self) -> str:
return "reanonymizer"
def operator_type(self) -> OperatorType:
return OperatorType.AnonymizeКастомные распознаватели для PAN и Aadhaar
Регулярные распознаватели для индийских номеров PAN и Aadhaar:
from presidio_analyzer import AnalyzerEngine, PatternRecognizer, Pattern
pan_recognizer = PatternRecognizer(
supported_entity="IND_PAN",
name="PAN Recognizer",
patterns=[Pattern(name="pan", regex=r"\b[A-Z]{5}[0-9]{4}[A-Z]\b", score=0.8)],
supported_language="en"
)
aadhaar_recognizer = PatternRecognizer(
supported_entity="AADHAAR",
name="Aadhaar Recognizer",
patterns=[Pattern(name="aadhaar", regex=r"\b\d{4}[- ]?\d{4}[- ]?\d{4}\b", score=0.8)],
supported_language="en"
)
analyzer = AnalyzerEngine()
analyzer.registry.add_recognizer(pan_recognizer)
analyzer.registry.add_recognizer(aadhaar_recognizer)
anonymizer = AnonymizerEngine()
anonymizer.add_anonymizer(ReAnonymizer)
entity_mapping = {}Консистентный анализ и анонимизация нескольких текстов
from pprint import pprint
text1 = "My PAN is ABCDE1234F and Aadhaar number is 1234-5678-9123."
text2 = "His Aadhaar is 1234-5678-9123 and PAN is ABCDE1234F."
results1 = analyzer.analyze(text=text1, language="en")
anon1 = anonymizer.anonymize(
text1,
results1,
{"DEFAULT": OperatorConfig("reanonymizer", {"entity_mapping": entity_mapping})}
)
results2 = analyzer.analyze(text=text2, language="en")
anon2 = anonymizer.anonymize(
text2,
results2,
{"DEFAULT": OperatorConfig("reanonymizer", {"entity_mapping": entity_mapping})}
)
print(" Оригинал 1:", text1)
print(" Анонимизировано 1:", anon1.text)
print(" Оригинал 2:", text2)
print(" Анонимизировано 2:", anon2.text)
print("\n Используемая карта сопоставлений:")
pprint(entity_mapping)Такой подход позволяет сохранять согласованность псевдонимизации в разных документах — важная функция для анализа данных и соблюдения требований конфиденциальности.
Presidio предоставляет гибкий и мощный инструмент для обнаружения и анонимизации PII, позволяя разработчикам надежно защищать чувствительную информацию с помощью настраиваемых процессов.
Switch Language
Read this article in English