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