File size: 10,494 Bytes
31b5d34
 
1f2c947
 
 
31b5d34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7199a12
 
 
31b5d34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b108b42
31b5d34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2c538d1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
---
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.