CoolFace
Apppublic

marry1908/topic-classification

sourceHugging Faceupdated 7mo agoView on Hugging Face
0likes
app.py279 linesDownload Raw Back to root
1import gradio as gr2import time3import pandas as pd4from datetime import datetime5import numpy as np6 7# Импортируем transformers с обработкой ошибок8try:9    from transformers import pipeline10    transformers_available = True11except ImportError:12    transformers_available = False13    print("Transformers not available, using mock mode")14 15# История запросов16history = []17MAX_HISTORY = 1018 19# Темы для классификации20PREDEFINED_TOPICS = [21    "спорт", "политика", "наука", "технологии", 22    "здоровье", "образование", "культура", "экономика",23    "путешествия", "развлечения", "погода", "происшествия"24]25 26 27TOPIC_DESCRIPTIONS = {28    "спорт": "🏀 Спорт",29    "политика": "🏛️ Политика", 30    "наука": "🔬 Наука",31    "технологии": "💻 Технологии",32    "здоровье": "🏥 Здоровье",33    "образование": "📚 Образование",34    "культура": "🎭 Культура",35    "экономика": "💰 Экономика",36    "путешествия": "✈️ Путешествия",37    "развлечения": "🎬 Развлечения",38    "погода": "☀️ Погода",39    "происшествия": "🚨 Происшествия"40}41 42 43def simple_classifier(text, topics):44    """Простой классификатор на основе ключевых слов"""45    text_lower = text.lower()46    scores = []47    48    # Ключевые слова для каждой темы49    keywords = {50        "спорт": ["матч", "игра", "команда", "победил", "счёт", "футбол", "хоккей", "соревнование"],51        "политика": ["президент", "правительство", "закон", "выборы", "парламент", "министр", "депутат"],52        "наука": ["учёный", "исследование", "открытие", "лаборатория", "эксперимент", "научный"],53        "технологии": ["компьютер", "смартфон", "интернет", "программа", "гаджет", "робот", "искусственный интеллект"],54        "здоровье": ["врач", "больница", "лечение", "болезнь", "пациент", "медицина", "здоровый"],55        "образование": ["школа", "университет", "студент", "учитель", "экзамен", "урок", "образование"],56        "культура": ["фильм", "музыка", "театр", "выставка", "художник", "писатель", "книга"],57        "экономика": ["деньги", "банк", "компания", "рынок", "цена", "экономика", "финансы"],58        "путешествия": ["отпуск", "отель", "пляж", "горы", "путешествие", "турист", "страна"],59        "развлечения": ["кино", "сериал", "игра", "концерт", "развлечение", "отдых"],60        "погода": ["температура", "дождь", "снег", "солнце", "погода", "климат", "ветер"],61        "происшествия": ["авария", "пожар", "происшествие", "инцидент", "катастрофа", "чрезвычайная ситуация"]62    }63    64    for topic in topics:65        score = 066        for keyword in keywords.get(topic, []):67            if keyword in text_lower:68                score += 169        scores.append(score / max(len(keywords.get(topic, [])), 1))70    71    return scores72 73def classify_topic(text, show_top_n=3):74    """Классифицирует текст по темам"""75    76    # Проверка ошибок77    if not text or text.strip() == "":78        return "⚠️ Пожалуйста, введите текст для анализа", "", []79    80    if len(text) > 2000:81        return "⚠️ Текст слишком длинный (максимум 2000 символов)", "", []82    83    try:84        # Измеряем время выполнения85        start_time = time.time()86        87        # Пытаемся использовать трансформеры, если доступны88        if transformers_available:89            try:90                classifier = pipeline("zero-shot-classification", 91                                     model="MoritzLaurer/mDeBERTa-v3-base-mnli-xnli",92                                     device=-1)93                94                results = classifier(95                    text, 96                    candidate_labels=PREDEFINED_TOPICS,97                    multi_label=False98                )99                100                labels = results['labels']101                scores = results['scores']102                103            except Exception as model_error:104                # Если не получилось с трансформерами, используем простой классификатор105                print(f"Model error: {model_error}, using simple classifier")106                scores = simple_classifier(text, PREDEFINED_TOPICS)107                labels = PREDEFINED_TOPICS108        else:109            # Если трансформеры не установлены110            scores = simple_classifier(text, PREDEFINED_TOPICS)111            labels = PREDEFINED_TOPICS112        113        elapsed_time = time.time() - start_time114        115        # Сортируем результаты116        if isinstance(scores, list):117            sorted_indices = np.argsort(scores)[::-1][:show_top_n]118        else:119            # Если scores уже numpy array120            sorted_indices = scores.argsort()[::-1][:show_top_n]121        122        # Форматируем результаты123        output_text = f"📊 **Тематическая классификация:**\n\n"124        125        for i, idx in enumerate(sorted_indices, 1):126            topic = labels[idx]127            score = scores[idx] * 100128            description = TOPIC_DESCRIPTIONS.get(topic, topic)129            130            # Прогресс-бар131            bar_length = 20132            filled = int(score * bar_length / 100)133            progress_bar = "█" * filled + "░" * (bar_length - filled)134            135            output_text += f"{i}. **{description}** - {score:.1f}%\n"136            output_text += f"   {progress_bar}\n\n"137        138        output_text += f"\n⏱️ **Время обработки:** {elapsed_time:.2f} секунд"139        140        # Сохраняем в историю141        timestamp = datetime.now().strftime("%H:%M:%S")142        top_topic = labels[sorted_indices[0]]143        history.insert(0, {144            'time': timestamp,145            'text': text[:50] + ("..." if len(text) > 50 else ""),146            'topic': TOPIC_DESCRIPTIONS.get(top_topic, top_topic),147            'confidence': f"{scores[sorted_indices[0]]*100:.1f}%"148        })149        150        # Ограничиваем историю151        if len(history) > MAX_HISTORY:152            history.pop()153        154        # Создаём DataFrame для таблицы155        df = pd.DataFrame(history)156        157        return output_text, f"✅ Текст успешно обработан за {elapsed_time:.2f} сек", df158        159    except Exception as e:160        return f"❌ **Ошибка:** {str(e)}", "", []161 162def clear_history():163    """Очищает историю запросов"""164    global history165    history = []166    return pd.DataFrame()167 168# Создаём интерфейс169with gr.Blocks(title="Тематический классификатор текста", theme=gr.themes.Soft()) as demo:170    gr.Markdown("# 🏷️ Тематический классификатор текста")171    gr.Markdown("Определяет основную тему текста: спорт, политика, наука, технологии и другие")172    173    with gr.Row():174        with gr.Column(scale=2):175            # Входные элементы176            text_input = gr.Textbox(177                label="📝 Введите текст для анализа",178                placeholder="Например: 'Сегодня на матче сборная России победила со счётом 3:1...'",179                lines=5,180                max_lines=10181            )182            183            with gr.Row():184                top_n_slider = gr.Slider(185                    minimum=1,186                    maximum=5,187                    value=3,188                    step=1,189                    label="🔢 Количество топ-тем для показа"190                )191            192            analyze_btn = gr.Button("🚀 Определить тему", variant="primary", size="lg")193            clear_btn = gr.Button("🧹 Очистить историю", variant="secondary")194            195            # Примеры для ТЕМАТИЧЕСКОЙ классификации196            gr.Markdown("### 📌 Готовые примеры")197            examples = gr.Examples(198                examples=[199                    ["Сегодня на стадионе «Лужники» прошёл финальный матч чемпионата России по футболу. Команда «Спартак» одержала победу со счётом 2:1 над ЦСКА."],200                    ["Парламент принял новый закон о цифровой экономике, который регулирует использование криптовалют и блокчейн-технологий."],201                    ["Учёные из МГУ открыли новый метод лечения рака с помощью наночастиц. Клинические испытания показали эффективность в 85% случаев."],202                    ["Компания Apple представила новый iPhone с революционной камерой и процессором собственной разработки. Продажи начнутся с следующей недели."],203                    ["Врачи рекомендуют увеличить потребление овощей и фруктов для профилактики сердечно-сосудистых заболеваний. Исследования подтвердили снижение риска на 30%."],204                    ["Министерство образования анонсировало реформу ЕГЭ. Изменения коснутся формата экзаменов по математике и русскому языку."],205                    ["В Эрмитаже открылась выставка французских импрессионистов. В экспозиции представлены работы Моне, Ренуара и Дега."]206                ],207                inputs=text_input,208                label="Кликните на любой пример"209            )210        211        with gr.Column(scale=3):212            # Результаты213            output_md = gr.Markdown(label="📊 Результаты классификации")214            status_text = gr.Textbox(label="✅ Статус", interactive=False)215            216            gr.Markdown("### 📋 История запросов")217            history_table = gr.Dataframe(218                headers=["Время", "Текст", "Тема", "Уверенность"],219                datatype=["str", "str", "str", "str"],220                interactive=False,221            )222    223    # Обработчики событий224    analyze_btn.click(225        fn=classify_topic,226        inputs=[text_input, top_n_slider],227        outputs=[output_md, status_text, history_table]228    )229    230    clear_btn.click(231        fn=clear_history,232        inputs=[],233        outputs=[history_table]234    )235    236    # Информационный блок237    gr.Markdown("---")238    with gr.Accordion("📚 Подробная информация о модели", open=False):239        gr.Markdown("""240        **Используемая модель:** `MoritzLaurer/mDeBERTa-v3-base-mnli-xnli`241        242        **Почему эта модель:**243        - **Лёгкая** (300 МБ вместо 1.6 ГБ)244        - **Мультиязычная** с хорошей поддержкой русского245        - **Быстро загружается** на бесплатном CPU246        247        **Определяемые темы:**248        - 🏀 **Спорт** - спортивные события, соревнования, команды249        - 🏛️ **Политика** - политические новости, выборы, законы250        - 🔬 **Наука** - научные открытия, исследования251        - 💻 **Технологии** - IT, гаджеты, программы252        - 🏥 **Здоровье** - медицина, лечение, здоровье253        - 📚 **Образование** - обучение, экзамены, школы254        - 🎭 **Культура** - искусство, музыка, кино255        - 💰 **Экономика** - финансы, бизнес, рынки256        - ✈️ **Путешествия** - туризм, страны257        - 🎬 **Развлечения** - фильмы, игры, шоу258        - ☀️ **Погода** - климат, температура259        - 🚨 **Происшествия** - аварии, криминал260        261        **Технические детали:**262        - Модель на основе DeBERTa-v3263        - Поддерживает 12 предопределённых тем264        - Работает на CPU за 1-3 секунды265        - Поддерживает тексты до 2000 символов266        """)267    268    gr.Markdown("---")269    gr.Markdown("""270    ### ⚠️ Ограничения и примечания271    1. Максимальная длина текста: **2000 символов**272    2. Поддерживает русский и английский языки273    3. Может определять только одну основную тему274    4. Для сложных текстов может потребоваться ручная проверка275    5. Точность: ~70-80% на новостных текстах276    """)277 278if __name__ == "__main__":279    demo.launch(debug=False)