← Назад к вопросам

Как построить классификатор для распознавания чувствительных данных в чат-боте?

1.3 Junior🔥 151 комментариев
#NLP и обработка текста#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Построение классификатора для распознавания чувствительных данных (ПИ) — критическая задача безопасности. Нужно обнаруживать номера карт, ФИО, пароли, адреса и другую приватную информацию.

Данные для обучения

Сначала нужен размеченный датасет:

texts = [
    "Меня зовут Иван Петров",
    "Мой номер 8-900-123-45-67",
    "Карта 4532-1234-5678-9012",
    "Привет, как дела?",
    "Я живу на ул. Пушкина, д. 10",
]
labels = [1, 1, 1, 0, 1]  # 1 = содержит ПИ

Подход 1: Регулярные выражения

Для быстрого решения используются паттерны:

import re

class SensitiveDataDetector:
    def __init__(self):
        self.patterns = {
            "credit_card": r"\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}",
            "phone": r"\+?[78][-\s]?\d{3}[-\s]?\d{3}[-\s]?\d{2}[-\s]?\d{2}",
            "email": r"[\w\.-]+@[\w\.-]+\.\w+",
            "passport": r"\d{10}",
        }
    
    def detect(self, text):
        for data_type, pattern in self.patterns.items():
            if re.search(pattern, text):
                return True, data_type
        return False, None

Плюсы: быстро, не требует обучения. Минусы: много ложных срабатываний.

Подход 2: NER (Named Entity Recognition)

Используем готовые NER модели:

import spacy

nlp = spacy.load("ru_core_news_sm")

def detect_sensitive_ner(text):
    doc = nlp(text)
    sensitive_labels = {"PERSON", "ORG", "GPE"}
    
    for ent in doc.ents:
        if ent.label_ in sensitive_labels:
            return True
    return False

Плюсы: учитывает контекст. Минусы: пропускает числовые коды.

Подход 3: Комбинированный классификатор

Комбинируем правила с ML:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import RandomForestClassifier
import re

class HybridSensitiveDataClassifier:
    def __init__(self):
        self.vectorizer = TfidfVectorizer(max_features=1000, ngram_range=(1, 2))
        self.model = RandomForestClassifier(n_estimators=100)
        self.regex_patterns = {
            "card": r"\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}",
            "phone": r"\+?[78][-\s]?\d{3}",
        }
    
    def extract_features(self, text):
        tfidf_features = self.vectorizer.transform([text])
        
        regex_features = [
            int(bool(re.search(pattern, text)))
            for pattern in self.regex_patterns.values()
        ]
        
        return tfidf_features, regex_features
    
    def fit(self, texts, labels):
        from scipy import sparse
        features_list = []
        for text in texts:
            tfidf, regex = self.extract_features(text)
            combined = sparse.hstack([tfidf, regex.reshape(1, -1)])
            features_list.append(combined)
        
        X = sparse.vstack(features_list)
        self.model.fit(X, labels)

Подход 4: Трансформер (BERT)

Для максимальной точности используем fine-tuned BERT:

from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch

class BERTSensitiveDataClassifier:
    def __init__(self, model_name="xlm-roberta-base"):
        self.tokenizer = AutoTokenizer.from_pretrained(model_name)
        self.model = AutoModelForSequenceClassification.from_pretrained(
            model_name, num_labels=2
        )
    
    def predict(self, text):
        inputs = self.tokenizer(
            text, return_tensors="pt", truncation=True, max_length=512
        )
        with torch.no_grad():
            outputs = self.model(**inputs)
        logits = outputs.logits
        predictions = torch.argmax(logits, dim=-1)
        return predictions[0].item()

Интеграция в чат-бот

class SafeChatBot:
    def __init__(self):
        self.classifier = HybridSensitiveDataClassifier()
        self.classifier.fit(train_texts, train_labels)
    
    def process_message(self, user_message):
        if self.classifier.predict(user_message) == 1:
            return "Обнаружены чувствительные данные. Не отправляйте ПИ."
        
        return generate_response(user_message)

Практические рекомендации

  1. Начни с regex для быстрого прототипа
  2. Комбинируй regex + ML для лучшей точности
  3. Используй NER для выделения сущностей
  4. BERT для критичных приложений
  5. Регулярно переобучай на новых примерах
  6. Мониторь false positives — они портят UX

Ключ к успеху — балансировка между точностью и скоростью.