Add research 27: chapter detection across formats and languages, standards-first cascade with corpus-validated data patterns, design not yet ratified
This commit is contained in:
parent
87247e2e97
commit
026ded0bc1
1 changed files with 35 additions and 0 deletions
35
docs/research/27-chapter-detection.md
Normal file
35
docs/research/27-chapter-detection.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# 27. Определение глав в загружаемых книгах: стандарты · практика · алгоритмы
|
||||
|
||||
**Оркестратор №15, 09.08.2026.** Веб-ресёрч по заказу владельца 09.08 (контекст: фактограф приёмки пака блокеров показал, что ingest-слой границ глав захардкожен под CJK-форму, выведенную из одной стенд-книги, — не-CJK txt молча становится одной главой, epub режется по spine с игнором оглавления, print-TOC порождает главы-огрызки). Три веб-агента: стандарты форматов · практика инструментов · алгоритмы; каждый факт с URL. **Статус: ФАКТУРА СОБРАНА; дизайн-решение владельцем НЕ принято — этот док не ратифицирует стройку.** Носители работ — строки бэклога (заводятся лендингом пака блокеров).
|
||||
|
||||
## §1. Ответы на вопросы владельца
|
||||
|
||||
1. **«Есть ли алгоритмы, умеющие парсить главы, или всё эвристика?»** Надёжного не-эвристического алгоритма для голого txt НЕ существует, и это доказано числами: Chapter Captor (EMNLP 2020, 9126 романов Gutenberg) — распознавание ЗАГОЛОВКОВ гибридом regex+BERT даёт F1=0.77, а предсказание границ БЕЗ заголовков (семантическая сегментация) — F1=0.453 [arxiv.org/abs/2011.04163]. Главы — авторская разметка, а не тематический сдвиг; TextTiling/C99/BERT-сегментация спроектированы под другое и как основа непригодны. Все зрелые инструменты (Calibre, chapterize, kaf-cli, AozoraEpub3) — каскад «статистика формата строк → языковые паттерны → структурные fallback'и → пороги правдоподобия».
|
||||
2. **«У epub по стандарту оглавления нет?»** ЕСТЬ И ОБЯЗАТЕЛЬНО. EPUB 3: публикация «MUST contain an EPUB navigation document» с toc nav — иерархия ol/li/a с заголовками и ссылками файл#якорь [w3.org/TR/epub-33/#sec-nav-toc]. EPUB 2: обязательный NCX (navMap/navPoint, вложенность томов/глав, navLabel+ с xml:lang — единственный стандартный носитель МУЛЬТИЯЗЫЧНЫХ названий глав) [idpf.org/epub/20/spec/OPF_2.0.1_draft.htm]. FB2 (жив, критичен для ru-рынка): дерево глав = сама разметка body/section с рекурсией и title [github.com/gribuser/fb2]. То есть для epub/fb2 границы И НАЗВАНИЯ глав достаются из стандарта вообще без эвристик — наш текущий разрез «по spine с игнором nav» выбрасывает гарантированную спекой структуру.
|
||||
3. **«Что с печатным оглавлением?»** Отдельное устоявшееся направление (ICDAR Book Structure Extraction 2009–2013): детект TOC-блока → парсинг записей → линковка в тело матчем заголовков. Print-TOC — не помеха, а бесплатный источник границ и КАНОНИЧЕСКИХ названий; TOC-гейты дёшевы (chapterize: кандидаты ближе 4 строк = блок оглавления).
|
||||
|
||||
## §2. Несущие факты по слоям
|
||||
|
||||
**EPUB (уточнения сверх §1):** резать по spine неверно ПО СТАНДАРТУ — якоря nav легально ведут внутрь файла (несколько глав в одном xhtml) и глава легально живёт в нескольких файлах; правильный алгоритм: поток = spine linear="yes", границы = якоря nav/NCX, спроецированные на поток. Порядку/полноте nav верить нельзя (с EPUB 3.3 порядок — SHOULD, полнота не требовалась никогда) — нормализация: сортировка целей по позиции в spine, непокрытые документы прикреплять к предыдущей главе. Служебные страницы фильтруются каскадом штатных сигналов: manifest properties (nav, cover-image) → spine linear="no" → landmarks (epub:type обязателен: cover/titlepage/toc/bodymatter) → epub:type/DPUB-ARIA в контенте (добровольный — сигнал, не гарантия). Однофайловый epub и битый nav → фолбэк на txt-эвристики.
|
||||
|
||||
**TXT — состояние искусства (Calibre как эталон):** (1) статистический детект формата абзацев (line histogram, доли пустых/отступных строк); (2) списки словесных паттернов — у Calibre только en+de в коде(!), CJK-миры держат свои инструменты: kaf-cli zh «第.{1,8}章» + том «第…[卷部]», AozoraEpub3 ja — богатый список 話/章/篇/部/節/幕/プロローグ/序章/終章/間章; (3) пороги правдоподобия: схема принимается только при min_chapters=ceil(wordcount/7000) ≤ hits < 150, заголовок ≤35 симв. (kaf-cli), ≥3 глав (chapterize); (4) сцены «* * *» — отдельный класс, не главы; (5) конвенция Gutenberg: 4 пустые строки перед главой — пустострочные раны как вторичный сигнал [pgdp.net DP Formatting Guidelines; W3C WCAG T3]. **Готовой мультиязычной библиотеки паттернов-как-данных не существует** — собирать свою в langpack из проверенных списков этих инструментов (сид: kaf-cli+AozoraEpub3+Calibre+chapterize; regex-набор Chapter Captor — сид для en); прецедент конфиг-схемы — ParserConfig oomol-lab (chapter_patterns/volume_patterns/section_patterns).
|
||||
|
||||
**Иерархия:** том/часть над главой — отдельный уровень паттернов у всех зрелых инструментов; плоский список ломается на «Том 2, Глава 1» (нумерация перезапускается) — в модель структуры нужен уровень volume/part, иначе якоря и банк едут на многотомниках.
|
||||
|
||||
**LLM-место:** полная LLM-разметка книги (LumberChunker, EMNLP 2024) — дороже/медленнее по признанию авторов, цена линейна от объёма, недетерминизм ломает снапшоты — ОТВЕРГНУТЬ как основной путь. Доказанный в проде паттерн (LILAC FSE'24, лог-парсинг): **LLM один раз ВЫВОДИТ шаблон, дальше режет детерминированный код** — шаблонов на порядки меньше экземпляров; перенос на книги естественен (один дешёвый вызов на семплах строк-кандидатов → regex книги → в снапшот → перепрогоны $0 и воспроизводимы). Для книг такой паттерн не опубликован — будем первыми.
|
||||
|
||||
## §3. Рекомендуемый класс решения (предложение оркестратора, НЕ ратифицировано)
|
||||
|
||||
Каскад по цене источника, LLM никогда не режет сама:
|
||||
1. **Структурные источники ($0, без эвристик):** epub nav → NCX → fb2 section/title; скрейп-epub (WebToEpub/FanFicFare и т.п.) — границы точны по построению, доверять. Названия глав на языке оригинала — из тех же источников (закрывает и вопрос heading/К-3).
|
||||
2. **TXT:** детект print-TOC блока (плотность кандидатов) → использовать его как источник имён и сверки; языко-НЕзависимый статистический скорер строки-заголовка (короткая · изолирована пустыми строками · монотонная нумерация · повторяющийся префикс-шаблон · равномерность по файлу · коридор hits/wordcount) + словари маркеров per-language как ДАННЫЕ langpack; несколько конкурирующих схем-кандидатов, выбор по скору.
|
||||
3. **Fallback:** один дешёвый LLM-вызов выводит шаблон книги, шаблон — артефакт снапшота (LILAC-паттерн).
|
||||
4. **Всегда:** громкие WARN вместо молчаливой деградации («1 глава на 20 МБ», «скачок нумерации», «глава-огрызок»).
|
||||
|
||||
**Требование к дизайну (урок владельца 09.08):** модель «что бывает заголовком» выводится из КОРПУСА разнообразных книг (языки·авторы·форматы), не из стенд-книги; приёмка детекта — прогоном по корпусу с замером точности границ (полигон). Схема данных проектируется от общего кейса, а не наращиванием заплаток к CJK-форме (история вопроса: пак-2 завёл CJK-сплит до канона общности, фазы общности вынесли маркеры в данные, но форма шаблона осталась в Go и слой выпал из карты общности — D39.64 честно не включал его в критерий).
|
||||
|
||||
**Цена итераций:** правки детекта двигают нарезку → снапшот → реснапшот-класс на прогнанных книгах. Проектировать один раз от корпуса и строить ДО открытия интейка книг пользователям; сейчас единственная платная книга — стенд, окно дешёвое.
|
||||
|
||||
## §4. Что НЕ брать
|
||||
|
||||
Тематическая сегментация как основа (F1=0.453) — максимум tie-breaker · полная LLM-разметка (цена/недетерминизм) · вебновелльные скрейперы как образец детекта (у них глава = страница сайта, задачи нет) · универсальный код без языковых данных (ни один инструмент так не решил).
|
||||
Loading…
Add table
Reference in a new issue