← Назад к вопросам
Как построить классификатор для распознавания чувствительных данных в чат-боте?
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)
Практические рекомендации
- Начни с regex для быстрого прототипа
- Комбинируй regex + ML для лучшей точности
- Используй NER для выделения сущностей
- BERT для критичных приложений
- Регулярно переобучай на новых примерах
- Мониторь false positives — они портят UX
Ключ к успеху — балансировка между точностью и скоростью.