530 lines
22 KiB
Markdown
530 lines
22 KiB
Markdown
# Архив лабораторной работы №1
|
||
|
||
**Тема:** классификация текстов на основе стилометрических характеристик.
|
||
**Материал:** реплики персонажей игры Stardew Valley.
|
||
**Задача:** по одной реплике определить, какому из 34 персонажей она
|
||
принадлежит, и проверить, какие стилометрические признаки несут этот сигнал.
|
||
|
||
Это не авторская атрибуция: все реплики написаны одним автором. Мы различаем
|
||
**речевые маски персонажей** — намеренно созданные автором различия в лексике,
|
||
синтаксисе, пунктуации и разговорных маркерах.
|
||
|
||
---
|
||
|
||
## 1. Что в архиве
|
||
|
||
| Путь | Что это |
|
||
|---|---|
|
||
| `lab1/report/REPORT.pdf` | Итоговый отчёт, 21 страница. Главный документ. |
|
||
| `lab1/report/REPORT.docx` | Редактируемая версия отчёта. |
|
||
| `lab1/report/REPORT.md` | Исходник отчёта в Markdown. |
|
||
| `lab1/report/figures/` | Рисунки отчёта. |
|
||
| `lab1/presentation/stardew_stylometry.pdf` | Презентация для защиты. |
|
||
| `lab1/presentation/stardew_stylometry.pptx` | Редактируемая презентация. |
|
||
| `lab1/presentation/latex/` | LaTeX-исходник и PDF презентации. |
|
||
| `lab1/presentation/images/`, `generated/` | Исходные изображения и диаграммы. |
|
||
| `lab1/stylometry/` | Основной код проекта. |
|
||
| `lab1/scripts/` | Проверка окружения, запуск серий, сборка отчёта, упаковка. |
|
||
| `lab1/tests/` | 33 теста (`pytest`). |
|
||
| `lab1/configs/default.toml` | Конфигурация по умолчанию. |
|
||
| `lab1/data/dialogues.csv` | Корпус: 2005 реплик, cp1251, разделитель `;`. |
|
||
| `lab1/data/dialogues.xlsx` | Тот же корпус в Excel. |
|
||
| `lab1/data/stats_per_character.xlsx` | Статистика по персонажам. |
|
||
| `lab1/data/metadata/` | Метаданные персонажей для анализа ошибок. |
|
||
| `lab1/data/corpus_report_*.txt` | Отчёты о состоянии корпуса до/после очистки. |
|
||
| `lab1/FINAL_RESULTS.csv` | Сводная таблица финальных результатов. |
|
||
| `lab1/FINAL_REPORT.md` | Расширенная версия отчёта с деталями экспериментов. |
|
||
| `lab1/EXPERIMENTS.md` | Протокол экспериментов и команд. |
|
||
| `lab1/FEATURES.md` | Признаки, формулы, обоснование. |
|
||
| `lab1/METRICS_AND_CLASSIFIERS.md` | Метрики и классификаторы. |
|
||
| `lab1/TUNING.md` | Настройка гиперпараметров. |
|
||
| `lab1/RUNBOOK.md` | Подробная инструкция по запуску полной серии. |
|
||
| `lab1/RESULTS_ANALYSIS.md` | Анализ результатов и ошибок. |
|
||
| `lab1/FOLLOWUP_EXPERIMENTS.md` | Дополнительные эксперименты. |
|
||
| `lab1/PRESENTATION_OUTLINE.md` | Структура презентации. |
|
||
| `lab1/exports/nlp_lab1_final_results_20261026_120000.tar.gz` | Финальные результаты в компактном виде. |
|
||
| `lab1/requirements.txt` | Основные зависимости. |
|
||
| `lab1/requirements-report.txt` | Зависимости для пересборки отчёта. |
|
||
|
||
Полный список файлов с размерами и SHA-256 — в `MANIFEST.txt`.
|
||
Контрольные суммы ключевых файлов — в `CHECKSUMS.sha256`.
|
||
|
||
---
|
||
|
||
## 2. Требования
|
||
|
||
### 2.1. Обязательные
|
||
|
||
- Python **3.11+** (проверено на 3.14);
|
||
- Linux, macOS или Windows с WSL;
|
||
- около 1 ГБ свободного места с виртуальным окружением и NLTK;
|
||
- интернет — только для установки пакетов и скачивания NLTK.
|
||
|
||
### 2.2. Для пересборки отчёта
|
||
|
||
- `pandoc` 3.x;
|
||
- LibreOffice (`libreoffice --headless`);
|
||
- Python-пакеты `python-docx`, `PyMuPDF` (см. `requirements-report.txt`);
|
||
- шрифты с кириллицей: Times New Roman или Liberation Serif, Liberation Mono.
|
||
|
||
### 2.3. Для пересборки LaTeX-презентации
|
||
|
||
- XeLaTeX;
|
||
- пакеты Beamer, tcolorbox, TikZ, fontspec, babel-russian;
|
||
- шрифт Liberation Sans.
|
||
|
||
---
|
||
|
||
## 3. Установка
|
||
|
||
Все команды выполняются из каталога `lab1`:
|
||
|
||
```bash
|
||
cd lab1
|
||
```
|
||
|
||
### 3.1. Виртуальное окружение
|
||
|
||
```bash
|
||
python -m venv .venv
|
||
source .venv/bin/activate
|
||
```
|
||
|
||
Windows PowerShell:
|
||
|
||
```powershell
|
||
python -m venv .venv
|
||
.venv\Scripts\activate
|
||
```
|
||
|
||
Если окружение уже есть в корне проекта, можно использовать его:
|
||
|
||
```bash
|
||
source ../.venv/bin/activate
|
||
```
|
||
|
||
### 3.2. Зависимости
|
||
|
||
```bash
|
||
python -m pip install --upgrade pip
|
||
python -m pip install -r requirements.txt
|
||
```
|
||
|
||
Для пересборки отчёта дополнительно:
|
||
|
||
```bash
|
||
python -m pip install -r requirements-report.txt
|
||
```
|
||
|
||
### 3.3. Ресурсы NLTK
|
||
|
||
```bash
|
||
python scripts/download_nltk_data.py
|
||
```
|
||
|
||
Скрипт скачивает `punkt`, `punkt_tab`, `averaged_perceptron_tagger`,
|
||
`averaged_perceptron_tagger_eng`, `stopwords` в `lab1/nltk_data`.
|
||
|
||
Без этих ресурсов POS-признаки отключатся, а результаты будут неполными.
|
||
Если машина без интернета, скопируйте готовый каталог `nltk_data` в `lab1/`.
|
||
|
||
### 3.4. Проверка
|
||
|
||
```bash
|
||
python scripts/check_environment.py
|
||
python -m pytest -q
|
||
```
|
||
|
||
Ожидается:
|
||
|
||
```text
|
||
Окружение готово.
|
||
33 passed
|
||
```
|
||
|
||
`check_environment.py` печатает версии библиотек, SHA-256 корпуса, число
|
||
реплик, персонажей и словоупотреблений, проверяет токенизатор и POS-теггер.
|
||
|
||
---
|
||
|
||
## 4. Быстрый запуск
|
||
|
||
### 4.1. Аудит корпуса
|
||
|
||
```bash
|
||
python -m stylometry.cli audit
|
||
```
|
||
|
||
Создаёт:
|
||
|
||
- `data/processed/audit.md` — отчёт по корпусу;
|
||
- `data/processed/lines.csv` — нормализованные реплики;
|
||
- `data/processed/figures/class_distribution.png`.
|
||
|
||
Проверьте: 2005 реплик, 34 персонажа, 38 207 словоупотреблений, точных
|
||
дублей нет.
|
||
|
||
### 4.2. Ручные признаки
|
||
|
||
```bash
|
||
python -m stylometry.cli features
|
||
```
|
||
|
||
Создаёт:
|
||
|
||
- `features/stylometric.csv` — матрица 2005 × 454;
|
||
- `features/feature_dictionary.csv` — описание признаков.
|
||
|
||
### 4.3. Одна модель
|
||
|
||
```bash
|
||
python -m stylometry.cli run \
|
||
--preset stylometry_pos_lsa \
|
||
--model logreg \
|
||
--folds 5 \
|
||
--repeats 5
|
||
```
|
||
|
||
Результаты появятся в `results/<preset>_<model>_<timestamp>/`:
|
||
`summary.md`, `summary.json`, `fold_metrics.csv`, `pooled_metrics.csv`,
|
||
`per_class_report.csv`, `confusion_matrix.csv`, `oof_predictions.csv`.
|
||
|
||
### 4.4. Полная серия
|
||
|
||
```bash
|
||
bash scripts/run_all_experiments.sh
|
||
```
|
||
|
||
Скрипт последовательно запускает все стадии и пишет лог в
|
||
`results/logs/run_all_<timestamp>.log`. Ориентировочное время — 1,5–3 часа
|
||
на обычном ноутбуке. Быстрый режим без финальных чисел:
|
||
|
||
```bash
|
||
QUICK=1 bash scripts/run_all_experiments.sh
|
||
```
|
||
|
||
### 4.5. Финальные серии
|
||
|
||
```bash
|
||
python scripts/run_final_experiments.py \
|
||
--stages nested topic calibration ensemble extra \
|
||
--out results/final
|
||
```
|
||
|
||
Эта команда воспроизводит вложенный выбор конфигурации, контроль содержания,
|
||
коррекцию приоров, ансамбли и дополнительные конфигурации. Именно эти
|
||
результаты сведены в `FINAL_RESULTS.csv` и в отчёте.
|
||
|
||
---
|
||
|
||
## 5. Что делает каждый модуль
|
||
|
||
| Модуль | Назначение |
|
||
|---|---|
|
||
| `stylometry/io.py` | Чтение CSV/XLSX, проверка колонок, SHA-256 корпуса. |
|
||
| `stylometry/cleaning.py` | Unicode-нормализация, плейсхолдеры, пробелы. |
|
||
| `stylometry/tokenization.py` | NLTK: токенизация, предложения, POS; резервный режим. |
|
||
| `stylometry/features/` | 454 ручных признака в 11 группах. |
|
||
| `stylometry/lsa.py` | TF-IDF + TruncatedSVD для word/content/fw/char/pos. |
|
||
| `stylometry/pipelines.py` | Объединение блоков признаков, модели, сетки параметров. |
|
||
| `stylometry/cv.py` | Повторная стратифицированная и вложенная кросс-валидация. |
|
||
| `stylometry/evaluation.py` | Macro-F1, accuracy, balanced accuracy, MCC, каппа, top-k, log loss, Brier, бутстрэп. |
|
||
| `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. |
|
||
| `stylometry/metadata.py` | Метаданные персонажей, анализ подгрупп. |
|
||
| `stylometry/cli.py` | Единая точка входа для всех команд. |
|
||
| `main.py` | Короткая обёртка над `stylometry.cli`. |
|
||
|
||
### Группы ручных признаков
|
||
|
||
1. Длина.
|
||
2. Лексика.
|
||
3. Словарное богатство.
|
||
4. Символы.
|
||
5. Пунктуация.
|
||
6. Функциональные слова.
|
||
7. Местоимения.
|
||
8. Части речи.
|
||
9. Синтаксис.
|
||
10. Читаемость.
|
||
11. Разговорные маркеры.
|
||
|
||
Формулы и обоснование — в `FEATURES.md`.
|
||
|
||
---
|
||
|
||
## 6. Данные и разметка
|
||
|
||
### 6.1. Формат
|
||
|
||
`data/dialogues.csv`:
|
||
|
||
- кодировка cp1251;
|
||
- разделитель `;`;
|
||
- колонки `Реплика` и `Персонаж`;
|
||
- 2005 строк, 34 класса.
|
||
|
||
`data/dialogues.xlsx` — тот же корпус для Excel.
|
||
`data/stats_per_character.xlsx` — число реплик и длины по персонажам.
|
||
`data/metadata/` — пол, возраст, вид и роль для анализа ошибок; в признаки
|
||
классификатора эти поля не подаются.
|
||
|
||
### 6.2. Правила разметки
|
||
|
||
1. Одна реплика — один объект.
|
||
2. Метка — имя говорящего.
|
||
3. Один объект относится ровно к одному классу.
|
||
4. Соответствие реплики и метки проверено вручную.
|
||
5. Служебные метки `<PLAYER>`, `<FARM>`, `<PET>`, `<SPOUSE>`, `<TIME>`,
|
||
`<NOUN>`, `<NAME>` заменены нейтральными словами; их число сохранено
|
||
отдельным признаком.
|
||
|
||
### 6.3. Очистка и шум
|
||
|
||
Нормализуется только Unicode: варианты кавычек, тире, многоточий и пробелов.
|
||
Пунктуация, регистр и стоп-слова **сохраняются** — это стилометрический
|
||
сигнал.
|
||
|
||
Шумом считались точные дубликаты, технические артефакты, общие короткие
|
||
формулы и плейсхолдеры. Корпус прошёл ручную фильтрацию; точные правила
|
||
фильтрации не сохранились, поэтому исходное распределение восстановить
|
||
нельзя. Это ограничение зафиксировано в отчёте.
|
||
|
||
### 6.4. Ограничение по объёму
|
||
|
||
Формальные требования: не менее 90 текстов по 30 предложений и примерно
|
||
равные классы. В этом корпусе единица анализа — реплика (в среднем 19 слов),
|
||
классы неравномерны (15–139 реплик). По согласованию с преподавателем
|
||
эксперимент выполнен на уровне реплик; в отчёте раздел 2.5 честно описывает
|
||
это отклонение. Для компенсации используются веса классов и macro-F1.
|
||
|
||
---
|
||
|
||
## 7. Метрики и результаты
|
||
|
||
Основная метрика — **macro-F1**: средняя F-мера по 34 классам, каждый
|
||
персонаж весит одинаково. Дополнительно считаются accuracy, balanced
|
||
accuracy, top-3/top-5, MCC, каппа Коэна, log loss, Brier, матрица ошибок,
|
||
бутстрэп-интервалы.
|
||
|
||
| Конфигурация | Macro-F1 |
|
||
|---|---:|
|
||
| Мягкое голосование трёх моделей | **0,3036 ± 0,0189** |
|
||
| ExtraTrees, `char_max_features=10000` | 0,2757 ± 0,0219 |
|
||
| Вложенный выбор конфигурации | 0,2746 ± 0,0233 |
|
||
| ExtraTrees, полный набор | 0,2499 ± 0,0209 |
|
||
| Логистическая регрессия, lean + content-LSA | 0,2466 ± 0,0191 |
|
||
| Случайный лес, `char_max_features=10000` | 0,2583 ± 0,0066 |
|
||
| Только ручные признаки | 0,1051 ± 0,0038 |
|
||
| Случайный уровень | 0,029 |
|
||
|
||
На отложенной выборке 80/20 мягкое голосование дало 0,3333.
|
||
|
||
Контроль содержания: после замены существительных, глаголов, прилагательных,
|
||
наречий и числительных маркером `CONTENT` macro-F1 падает с 0,2483 до 0,1129.
|
||
Остаток всё ещё выше случайного уровня, но основной сигнал —
|
||
лексико-тематический.
|
||
|
||
---
|
||
|
||
## 8. Как пересобрать отчёт
|
||
|
||
Отчёт собирается из `report/REPORT.md`:
|
||
|
||
```bash
|
||
cd lab1
|
||
python scripts/build_report.py
|
||
```
|
||
|
||
Скрипт:
|
||
|
||
1. вызывает `pandoc` и делает `report/build/REPORT_raw.docx`;
|
||
2. оформляет стили, поля, колонтитулы, таблицы и рисунки;
|
||
3. сохраняет `report/REPORT.docx`;
|
||
4. конвертирует DOCX в `report/REPORT.pdf` через LibreOffice;
|
||
5. проверяет, что в PDF есть все основные разделы.
|
||
|
||
Только DOCX:
|
||
|
||
```bash
|
||
python scripts/build_report.py --skip-pdf
|
||
```
|
||
|
||
Требования: `pandoc`, `libreoffice`, `python-docx`, `PyMuPDF`.
|
||
Рисунки лежат в `report/figures/`; Markdown ссылается на них относительно
|
||
`report/`.
|
||
|
||
---
|
||
|
||
## 9. Как пересобрать презентацию
|
||
|
||
### 9.1. PPTX
|
||
|
||
В архиве лежит **финальная** версия `stardew_stylometry.pptx` (30 слайдов)
|
||
после ручных правок. Скрипт `build_deck.py` — генератор исходной версии
|
||
презентации; он создаёт 32 слайда и **перезапишет** финальный файл, если его
|
||
запустить. Не запускайте скрипт, если хотите сохранить ручные правки: для
|
||
изменений открывайте PPTX в PowerPoint или LibreOffice.
|
||
|
||
Если нужно пересобрать исходную версию с нуля:
|
||
|
||
```bash
|
||
cd lab1/presentation
|
||
python build_deck.py
|
||
```
|
||
|
||
Скрипт использует `python-pptx`, `Pillow` и `matplotlib`. Диаграммы уже лежат
|
||
в `presentation/generated/`; для их перегенерации нужны результаты серий
|
||
(`results/final/...`), которых нет в архиве — сначала запустите эксперименты
|
||
из раздела 4.
|
||
|
||
### 9.2. LaTeX/PDF
|
||
|
||
```bash
|
||
cd lab1/presentation/latex
|
||
xelatex stardew_stylometry.tex
|
||
xelatex stardew_stylometry.tex
|
||
```
|
||
|
||
Нужны XeLaTeX, Beamer, tcolorbox, TikZ и шрифт Liberation Sans. Готовый PDF —
|
||
`stardew_stylometry.pdf`. Изображения подтягиваются из `../images/` и
|
||
`../generated/`.
|
||
|
||
---
|
||
|
||
## 10. Где смотреть результаты
|
||
|
||
- `lab1/report/REPORT.pdf` — итоговый отчёт со всеми числами и выводами.
|
||
- `lab1/FINAL_RESULTS.csv` — сводная таблица всех финальных конфигураций.
|
||
- `lab1/FINAL_REPORT.md` — расширенное описание экспериментов.
|
||
- `lab1/RESULTS_ANALYSIS.md` — анализ ошибок, классов-аттракторов и длины.
|
||
- `lab1/exports/nlp_lab1_final_results_20261026_120000.tar.gz` — исходные
|
||
`summary.json`, `fold_metrics.csv`, `confusion_matrix.csv` и предсказания
|
||
финальных серий.
|
||
- `lab1/presentation/generated/` — диаграммы для отчёта и презентации.
|
||
|
||
---
|
||
|
||
## 11. Частые проблемы
|
||
|
||
### `check_environment.py` не находит POS-теггер
|
||
|
||
Повторите:
|
||
|
||
```bash
|
||
python scripts/download_nltk_data.py
|
||
```
|
||
|
||
Проверьте, что каталог `lab1/nltk_data` существует и не пуст. Если сеть
|
||
недоступна, скопируйте `nltk_data` с другой машины.
|
||
|
||
### `pytest` не устанавливается
|
||
|
||
Убедитесь, что активировано виртуальное окружение и версия Python не ниже
|
||
3.11:
|
||
|
||
```bash
|
||
python --version
|
||
python -m pip install -r requirements.txt
|
||
```
|
||
|
||
### `python -m stylometry.cli` не находит модуль
|
||
|
||
Команда должна выполняться из каталога `lab1`, а не из корня репозитория:
|
||
|
||
```bash
|
||
cd lab1
|
||
python -m stylometry.cli audit
|
||
```
|
||
|
||
### LibreOffice не собирает PDF
|
||
|
||
Проверьте:
|
||
|
||
```bash
|
||
libreoffice --version
|
||
```
|
||
|
||
На сервере без графической сессии используйте именно `--headless`
|
||
(это уже делает `build_report.py`). Если LibreOffice нет, отчёт можно
|
||
открыть в Word/LibreOffice вручную и экспортировать в PDF.
|
||
|
||
### Кириллица в PDF выглядит квадратами
|
||
|
||
Установите шрифты Liberation Serif/Sans и Liberation Mono. В отчёте
|
||
используются Times New Roman (с запасным Liberation Serif) и Liberation Mono.
|
||
|
||
### Полная серия идёт слишком долго
|
||
|
||
Запускайте в `tmux` или `nohup`, см. `RUNBOOK.md`, раздел 5.4. Для проверки
|
||
работоспособности используйте `QUICK=1`.
|
||
|
||
---
|
||
|
||
## 12. Что исключено из архива
|
||
|
||
Чтобы архив оставался компактным и воспроизводимым, в него не включены:
|
||
|
||
- `.venv/` — виртуальное окружение;
|
||
- `.git/` — история репозитория;
|
||
- `nltk_data/` — скачивается скриптом;
|
||
- `data/processed/` — аудит и промежуточные таблицы;
|
||
- `features/` — матрица признаков (создаётся `features`);
|
||
- `results/` — промежуточные результаты серий;
|
||
- большие `exports/*.tar.gz` — кроме компактного финального архива;
|
||
- `presentation/preview/` — PNG-превью слайдов;
|
||
- `__pycache__/`, `.pytest_cache/` — кэши;
|
||
- `presentation/stardew_stylometry.bak` — резервная копия;
|
||
- служебные файлы LaTeX (`.aux`, `.log`, `.nav`, `.out`, `.snm`, `.toc`).
|
||
|
||
Всё это восстанавливается командами из разделов 3–4.
|
||
|
||
---
|
||
|
||
## 13. Проверка целостности архива
|
||
|
||
```bash
|
||
sha256sum -c CHECKSUMS.sha256
|
||
```
|
||
|
||
`MANIFEST.txt` содержит список всех файлов архива с размерами и SHA-256.
|
||
Если контрольные суммы совпали, архив распакован полностью.
|
||
|
||
Минимальная проверка после распаковки:
|
||
|
||
```bash
|
||
cd lab1
|
||
python scripts/check_environment.py
|
||
python -m pytest -q
|
||
python -m stylometry.cli audit
|
||
```
|
||
|
||
---
|
||
|
||
## 14. Атрибуция
|
||
|
||
Диалоги Stardew Valley принадлежат ConcernedApe. Корпус используется
|
||
исключительно в учебных и исследовательских целях. Код проекта можно
|
||
использовать и изменять для учебных задач.
|
||
|
||
---
|
||
|
||
## 15. Шпаргалка команд
|
||
|
||
```bash
|
||
# из lab1
|
||
python scripts/check_environment.py # проверить окружение
|
||
python -m pytest -q # 33 теста
|
||
python -m stylometry.cli audit # аудит корпуса
|
||
python -m stylometry.cli features # 454 ручных признака
|
||
python -m stylometry.cli run \
|
||
--preset stylometry_pos_lsa --model logreg --repeats 5
|
||
bash scripts/run_all_experiments.sh # полная серия
|
||
python scripts/run_final_experiments.py \
|
||
--stages nested topic calibration ensemble extra --out results/final
|
||
python scripts/build_report.py # отчёт DOCX + PDF
|
||
```
|