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