Files
NLP/lab1/README.md

232 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Стилометрия реплик 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` | только признаки длины (нижняя граница) |
## Конфигурация
Файл `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`.
- **`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,
дельту, метрики и кросс-валидацию.