SlerpE's picture
Update README.md
7199a12 verified
---
license: apache-2.0
language:
- ru
pipeline_tag: text-classification
---
# Классификатор опасного контента для детей
Этот проект представляет собой модель машинного обучения, предназначенную для автоматического определения потенциально опасного контента для детей в русскоязычных текстах. Модель классифицирует текст на две категории: `safe` (безопасный) и `dangerous` (опасный).
Система построена на двухкомпонентной архитектуре:
1. **Векторизация текста:** Используется мощная модель `Qwen/Qwen3-Embedding-4B` для преобразования текста в числовые векторы (эмбеддинги), которые улавливают семантический смысл.
2. **Классификация:** Поверх эмбеддингов работает простая и быстрая модель **логистической регрессии**, обученная различать "опасные" и "безопасные" векторы.
## 🎯 Назначение модели
Модель обучена выявлять следующие категории опасного контента на русском языке:
1. **Кибербуллинг и оскорбления:** Прямые угрозы, унижения и травля в чатах.
2. **Опасные челленджи:** Призывы к участию в рискованных для жизни и здоровья действиях.
3. **Жестокое обращение с животными:** Тексты, оправдывающие или поощряющие насилие над животными.
4. **Пропаганда РПП:** Контент, пропагандирующий нездоровое пищевое поведение (анорексия, булимия).
5. **Насилие и жестокость:** Описание сцен насилия, нанесения увечий.
## 🛠️ Технический стек
* **Python 3.8+**
* **PyTorch:** для работы нейросетевой модели эмбеддингов.
* **Transformers (Hugging Face):** для загрузки и использования модели Qwen.
* **Scikit-learn:** для использования обученного классификатора логистической регрессии.
* **Joblib:** для загрузки файла с классификатором.
## 🚀 Установка
1. **Клонируйте репозиторий:**
```bash
git clone https://huggingface.co/SlerpE/Dangerous_Content_Classifier
cd Dangerous_Content_Classifier
```
2. **Создайте и активируйте виртуальное окружение:**
```bash
python -m venv venv
source venv/bin/activate
```
3. **Установите зависимости:**
```bash
pip install -r requirements.txt
```
4. **Пример использования:**
```python
import torch
from transformers import AutoModel, AutoTokenizer
import numpy as np
import joblib
# --- КОНФИГУРАЦИЯ ---
QWEN_MODEL_NAME = "Qwen/Qwen3-Embedding-4B"
CLASSIFIER_PATH = 'logistic_regression_classifier.joblib'
print("Загрузка моделей... Это может занять некоторое время.")
# --- ШАГ 1: ЗАГРУЗКА ВСЕХ НЕОБХОДИМЫХ МОДЕЛЕЙ ---
# 1.1 Загружаем модель Qwen для получения эмбеддингов
device = "cuda" if torch.cuda.is_available() else "cpu"
qwen_tokenizer = AutoTokenizer.from_pretrained(QWEN_MODEL_NAME, trust_remote_code=True)
qwen_model = AutoModel.from_pretrained(QWEN_MODEL_NAME, trust_remote_code=True).to(device)
qwen_model.eval()
if qwen_tokenizer.pad_token is None:
qwen_tokenizer.pad_token = qwen_tokenizer.eos_token
# 1.2 Загружаем обученный классификатор
classifier = joblib.load(CLASSIFIER_PATH)
print(f"Модели загружены. Используется устройство: {device}")
print("-" * 30)
def classify_text(text: str):
"""
Классифицирует один текст, определяя, является ли он "опасным".
Args:
text (str): Входной текст для классификации.
Returns:
dict: Словарь с предсказанной меткой и уверенностью модели.
"""
# --- Этап 1: Получение эмбеддинга для текста ---
with torch.no_grad():
inputs = qwen_tokenizer(text, return_tensors="pt", truncation=True, max_length=512).to(device)
outputs = qwen_model(**inputs)
# Усредняем эмбеддинги
embedding = outputs.last_hidden_state.mean(dim=1).cpu().numpy()
# --- Этап 2: Предсказание с помощью классификатора ---
# scikit-learn ожидает на вход 2D-массив (список примеров),
# поэтому мы преобразуем наш 1D-вектор в массив из одного элемента
# (из [e1, e2, ...] в [[e1, e2, ...]])
embedding_2d = embedding.reshape(1, -1)
# Получаем предсказание (0 или 1)
prediction = classifier.predict(embedding_2d)[0]
# Получаем вероятность принадлежности к каждому классу
probabilities = classifier.predict_proba(embedding_2d)[0]
# Определяем метку и уверенность
if prediction == 1:
label = "dangerous"
confidence = probabilities[1]
else:
label = "safe"
confidence = probabilities[0]
return {
"text": text,
"predicted_label": label,
"confidence": f"{confidence:.2%}" # Форматируем в проценты
}
# --- ПРИМЕР ИСПОЛЬЗОВАНИЯ ---
if __name__ == "__main__":
test_texts = [
"Мальчик играл с котенком на зеленой лужайке.",
"Это просто ужасно, ты никому не нужен, лучше бы тебя не было.",
"Давай дружить и вместе строить замки из песка!",
"Если не перестанешь, я тебя найду и тебе не поздоровится.",
"Попробуй челлендж - не есть 3 дня. Если ты его пройдёшь - получишь 5 тысяч рублей",
"Сейчас тебе придёт код в СМС, ты должен срочно сообщить его мне. Ты меня понял?! Иначе я тебя забаню на этом сервере!"
]
for text_to_check in test_texts:
result = classify_text(text_to_check)
print(f"Текст: \"{result['text']}\"")
print(f" -> Вердикт: {result['predicted_label']} (Уверенность: {result['confidence']})")
print("-" * 20)
```
**Пример вывода в консоль:**
```
------------------------------
Текст: "Мальчик играл с котенком на зеленой лужайке."
-> Вердикт: safe (Уверенность: 100.00%)
--------------------
Текст: "Это просто ужасно, ты никому не нужен, лучше бы тебя не было."
-> Вердикт: dangerous (Уверенность: 99.98%)
--------------------
Текст: "Давай дружить и вместе строить замки из песка!"
-> Вердикт: safe (Уверенность: 100.00%)
--------------------
Текст: "Если не перестанешь, я тебя найду и тебе не поздоровится."
-> Вердикт: dangerous (Уверенность: 99.74%)
--------------------
Текст: "Попробуй челлендж - не есть 3 дня. Если ты его пройдёшь - получишь 5 тысяч рублей"
-> Вердикт: dangerous (Уверенность: 99.38%)
--------------------
Текст: "Сейчас тебе придёт код в СМС, ты должен срочно сообщить его мне. Ты меня понял?! Иначе я тебя забаню на этом сервере!"
-> Вердикт: dangerous (Уверенность: 92.71%)
--------------------
```
## ⚠️ Ограничения
* **Контекст:** Модель анализирует только предоставленный текст и может не улавливать сложный контекст, сарказм или иронию.
* **Новые угрозы:** Модель обучена на известных ей типах угроз. Новые виды угроз могут быть не распознаны.
* **Только русский язык:** Модель была обучена и протестирована исключительно на русскоязычных данных.
* **Не является заменой модерации:** Данный инструмент следует рассматривать как вспомогательное средство для предварительной фильтрации контента, а не как полную замену ручной модерации.
## 📄 Лицензия
Этот проект распространяется под лицензией Apache 2.0.