# Стилометрия реплик Stardew Valley Проект для лабораторной работы по автоматическому анализу текстов. Задача — проверить, можно ли стилометрически различить персонажей игры, если все реплики написаны одним автором. Это не авторская атрибуция, а классификация **речевых масок персонажей** (character idiolect): автор намеренно наделяет героев разной лексикой, синтаксисом, междометиями и пунктуацией. Основная единица анализа — **одна реплика**. В текущем корпусе 2005 реплик, 34 персонажа. Классы неравномерны: от 15 реплик у Mister Qi до 139 у Abigail. Поэтому основная метрика — macro-F1, а не доля правильных ответов. ## Быстрый старт ```bash cd lab1 # 1. Установить зависимости (удобно в виртуальном окружении) python -m venv .venv source .venv/bin/activate pip install -r requirements.txt # 2. Скачать ресурсы NLTK в локальный каталог lab1/nltk_data python scripts/download_nltk_data.py # 3. Проверить корпус python -m stylometry.cli audit # 4. Построить ручные стилометрические признаки python -m stylometry.cli features # 5. Запустить кросс-валидацию python -m stylometry.cli run --preset stylometry_pos_lsa --model logreg --repeats 5 ``` Если виртуальное окружение уже создано в корне проекта (`/home/mermutef/PycharmProjects/nlp/.venv`), команды можно запускать так: ```bash cd lab1 ../.venv/bin/python -m stylometry.cli audit ``` Вместо `python -m stylometry.cli` можно использовать `python main.py`: ```bash python main.py audit python main.py run --preset stylometry_pos_lsa --model logreg --repeats 5 ``` ## Что уже реализовано | Компонент | Модуль | Назначение | |---|---|---| | Чтение корпуса | `stylometry/io.py` | CSV в cp1251, XLSX, проверка колонок, SHA-256 | | Нормализация | `stylometry/cleaning.py` | Unicode, плейсхолдеры, пробелы | | Токенизация и POS | `stylometry/tokenization.py` | NLTK: `word_tokenize`, `sent_tokenize`, `pos_tag`; резервный режим | | Ручные признаки | `stylometry/features/` | длина, лексика, словарное богатство, символы, пунктуация, функциональные слова, местоимения, POS, синтаксис, читаемость, разговорные маркеры | | LSA | `stylometry/lsa.py` | TF-IDF + `TruncatedSVD` для word/content/fw/char/pos | | Конвейеры | `stylometry/pipelines.py` | объединение блоков признаков, классификаторы, сетки гиперпараметров | | Кросс-валидация | `stylometry/cv.py` | повторная стратифицированная и вложенная CV | | Метрики | `stylometry/evaluation.py` | macro-F1, сбалансированная доля правильных ответов, MCC, каппа, top-k, логарифмическая потеря, оценка Брайера, бутстрэп | | Статистика | `stylometry/stats.py` | Мак-Немар, Уилкоксон, Фридман, Холм | | Дельта Барроуза | `stylometry/delta.py` | MFW, z-нормирование, манхэттенское и косинусное расстояние | | Верификация | `stylometry/verification.py` | «тот же персонаж / другой персонаж», ROC-AUC, EER, TAR@FAR | | Кластеризация | `stylometry/clustering.py` | иерархическая и k-means, ARI, NMI, силуэт | | Визуализация | `stylometry/plotting.py` | распределение классов, scree, матрица ошибок, PCA, t-SNE | ## Команды Все команды выполняются из каталога `lab1`. ```bash # Аудит: отчёт data/processed/audit.md и таблица lines.csv python -m stylometry.cli audit # Матрица ручных признаков: features/stylometric.csv и словарь признаков python -m stylometry.cli features # LSA одного варианта python -m stylometry.cli lsa --variant word --components 100 python -m stylometry.cli lsa --variant pos --components 50 python -m stylometry.cli lsa --variant char --components 50 # Одна модель python -m stylometry.cli run --preset stylometry_pos_lsa --model logreg --repeats 5 python -m stylometry.cli run --preset stylometry_pos --model linear_svc --repeats 5 python -m stylometry.cli run --preset stylometry --model random_forest --repeats 3 # Сравнение классификаторов python -m stylometry.cli benchmark --preset stylometry_pos_lsa \ --models logreg,linear_svc,random_forest,multinomial_nb,knn --repeats 3 # Вложенная кросс-валидация с настройкой гиперпараметров python -m stylometry.cli run --preset stylometry_pos_lsa --model logreg --nested # Поочерёдное исключение групп ручных признаков python -m stylometry.cli ablate --preset stylometry_pos_lsa --model logreg --repeats 3 # Перебор вариантов LSA и числа компонент python -m stylometry.cli lsa-sweep --variants word,pos,char --components 50,100,200 # Дельта Барроуза python -m stylometry.cli delta --features 100,200,500 --metrics manhattan,cosine # Верификация «свой/чужой» python -m stylometry.cli verify --preset stylometry_pos_lsa # Кластеризация персонажей python -m stylometry.cli cluster --preset stylometry_pos_lsa # Метрики по группам длины реплик (по сохранённому запуску) python -m stylometry.cli length-report --run-dir results/<каталог_запуска> # Парное сравнение двух запусков: Мак-Немар и бутстрэп-разница macro-F1 python -m stylometry.cli compare \ --run-a results/<каталог_запуска_A> \ --run-b results/<каталог_запуска_B> # Метрики по полу, возрасту и виду персонажей python -m stylometry.cli subgroup-report \ --run-dir results/<каталог_запуска> --group gender ``` Основные готовые наборы признаков (`--preset`): | Набор | Содержимое | |---|---| | `stylometry` | только ручные стилометрические признаки | | `stylometry_pos` | ручные признаки + символьные и POS n-граммы | | `stylometry_pos_lsa` | то же + LSA по словам и POS (основной набор) | | `all` | все блоки, включая все варианты LSA | | `char` | только символьные n-граммы | | `pos` | только POS n-граммы | | `fw` | функциональные слова и местоимения | | `lsa_word`, `lsa_pos` | только соответствующий вариант LSA | | `length` | только признаки длины (нижняя граница) | ## Презентация Есть две версии: - **`presentation/stardew_stylometry.pptx`** — редактируемая PPTX-версия (30 слайдов после ручных правок); - **`presentation/stardew_stylometry.pdf`** — PDF этой версии; - **`presentation/latex/stardew_stylometry.tex`** — академическая Beamer-версия; - **`presentation/latex/stardew_stylometry.pdf`** — собранный PDF LaTeX-версии (30 страниц). LaTeX-версия содержит три блока на трёх докладчиков, фон и курицу на каждом слайде, титульную заставку, изображение персонажей, две круговые диаграммы, матрицы ошибок, F-меры по персонажам, приложение с полной матрицей и финальный мем. Формул почти нет: одна компактная запись обозначений на слайде постановки задачи. Сборка LaTeX: ```bash cd presentation/latex xelatex stardew_stylometry.tex xelatex stardew_stylometry.tex ``` ## Конфигурация Файл `configs/default.toml` задаёт параметры по умолчанию: - `[cv]` — число блоков, повторов и seed; - `[experiment]` — набор признаков и классификатор; - `[features]` — диапазоны n-грамм, число компонент LSA, `min_df`, масштабирование. Параметры командной строки имеют приоритет над конфигурацией. Например: ```bash python -m stylometry.cli run --config configs/default.toml \ --preset stylometry_pos_lsa --model logreg --repeats 3 ``` ## Основные документы - **`RUNBOOK.md`** — пошаговая инструкция для запуска полной серии экспериментов: установка, проверка окружения, все команды, упаковка результатов и типичные ошибки. - **`EXPERIMENTS.md`** — подробный протокол экспериментов: гипотезы, признаки, схема валидации, матрица экспериментов, команды запуска, анализ ошибок, ограничения и чек-лист для следующего исследователя. - **`FEATURES.md`** — состав стилометрических признаков, формулы и обоснование выбора; дополняет машинно-читаемый `features/feature_dictionary.csv`. - **`TUNING.md`** — где менять параметры классификаторов, признаки, LSA и веса блоков; рекомендуемый порядок улучшения результатов. - **`RESULTS_ANALYSIS.md`** — независимый анализ follow-up результатов: ранжирование моделей, статистические сравнения, ошибки, ограничения и выводы. - **`FINAL_REPORT.md`** — итоговый отчёт по всей работе: методика, все серии экспериментов, результаты, обсуждение и выводы. - **`FINAL_RESULTS.csv`** — сводная таблица ключевых результатов. - **`FOLLOWUP_EXPERIMENTS.md`** — протокол и результаты follow-up серии, подготовленные коллегой. - **`METRICS_AND_CLASSIFIERS.md`** — методическое описание метрик и классификаторов: что показывает каждая метрика, как она считается, как интерпретировать значения, чем отличаются модели и как объяснять это на защите. - **`PRESENTATION_OUTLINE.md`** — рекомендуемая структура презентации на 14 слайдов с ключевыми тезисами и предложениями по визуализации. ## Структура проекта ```text lab1/ ├── data/ │ ├── dialogues.csv │ ├── dialogues.xlsx │ ├── stats_per_character.xlsx │ ├── metadata/characters.csv # пол, возраст, вид, роль │ └── processed/ # lines.csv, audit.md, tokenized.pkl ├── features/ # матрицы признаков и LSA ├── stylometry/ # основной пакет ├── experiments/ # место для отдельных сценариев ├── configs/default.toml ├── results/ # результаты запусков ├── tests/ # pytest ├── scripts/download_nltk_data.py ├── requirements.txt ├── README.md ├── EXPERIMENTS.md └── METRICS_AND_CLASSIFIERS.md ``` ## Воспроизводимость - Корпус читается из `data/dialogues.csv` в кодировке cp1251. SHA-256 файла сохраняется в отчёте и метаданных запуска. - Кэш токенизации `data/processed/tokenized.pkl` проверяется по SHA-256 исходного файла; при изменении корпуса пересобирается. - Все обучаемые преобразования (TF-IDF, SVD, масштабирование, отбор признаков) настраиваются только на обучающем блоке кросс-валидации. Ручные признаки и POS-теги не используют метки, поэтому могут считаться заранее. - Для каждого запуска сохраняются конфигурация, метрики по блокам, pooled out-of-fold предсказания, матрица ошибок, отчёт по классам и графики. - Случайность фиксируется параметром `--seed` (по умолчанию 42). ## Ограничения - Реплики короткие: в среднем около 19 слов. Признаки словарного богатства и читаемости на таких текстах нестабильны; они помечены как предварительные. - Все тексты написаны одним автором; результат характеризует различимость персонажей, а не авторский стиль. - Корпус прошёл ручную фильтрацию: короткие и общие фразы удалены. Точные правила очистки не воспроизводимы, это ограничение зафиксировано в отчёте. - Классы неравномерны (15–139 реплик). Основная метрика — macro-F1; по редким классам доверительные интервалы широкие. - NLTK-теггер обучен на внешнем корпусе и может ошибаться на разговорных конструкциях и коротких фрагментах. - LSA по всем словам может отражать тему, а не стиль. Поэтому в протоколе предусмотрено сравнение `lsa_word` с `lsa_pos`, `lsa_fw` и `lsa_char`. ## Тесты ```bash cd lab1 python -m pytest -q ``` Тесты проверяют чтение корпуса, нормализацию, NLTK-разметку, признаки, LSA, дельту, метрики и кросс-валидацию.