|
|
--- |
|
|
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. |