書籍ナレッジベースに7冊を追加取り込みして、文字化けとKindleキャプチャの誤検知を直した日
朝いちばんに考えていたのは、運営しているサイトの中身を増やすことだった。手を動かす前に、手元の蔵書DBに何が入っているかを数えさせた。386冊。思っていたより溜まっている。
ところが、その一覧が読めない。Windowsのコンソールがcp932で書名を吐き出すので、画面が化けた文字で埋まった。UTF-8のファイルに書き出させて開き直したら普通に読めた。数分の回り道で済んだが、この日はもう一度、同じ理由で同じことをやり直すことになる。
どの本なら自動取り込みを通せるか
コンテンツの元にしたい本を10冊まで絞ったところで、原本の在処を確認させた。ここで数が減った。
- PDFで手元にある6冊は、そのまま通せる
- Kindleの4冊のうち2冊は、ブラウザのCloud ReaderでもPCアプリでも開けない。スマホとタブレットのアプリ専用で、過去に取り込みを試したときの除外マークが残っていた
- Kindleの残る2冊のうち1冊は未購入だった。DBにはサンプルだけが入っていて、そのフラグが立っていた
実行できるのは7冊。Kindleのライブラリに入っていることと、自動取り込みのパイプラインを通せることは別だった。
作業の置き場所も決めた。抽出と成果物づくりはサイト側のセッションに残し、取り込みそのものは蔵書DB側のリポジトリで別セッションを立てる。
決まったところで、この日やることをGoogleタスクに2件積ませた。取り込みの作業そのものと、その計画が存在すること。期日は今日。ところが2件目に期日が付いていない。見たらタスクリストのIDを打ち間違えていた。正しいIDで入れ直させ、2件とも実在と期日をAPIで確認した。
OCRを回している50分の使い方
取り込みの本体は蔵書DB側のセッションで始めた。最初にやらせたのは重複チェック。ここでまた画面が化けた。DBの照合結果が読めないので、文字化けしない形でやり直させた。7冊とも未登録だった。
OCRは1ページあたり1.8秒ほどで進む。6冊で50分。GPUに空きがあり、しかもOCRが工程のなかで最も長い。6冊を直列で回すバッチを先にバックグラウンドへ流し、待ち時間を別の作業に充てた。
- Amazon側のメタデータ収集(原本ファイルの番号が取れればPDFを開かずに済む)
- 図のリネームと目次抽出のヘルパー作り
- Kindle1冊のキャプチャ開始
メタデータで1つ気づいたことがある。6冊のうち2冊は、Amazon側の登録が後年の別版を指していた。手元のスキャンは旧版なので、書誌はOCRのあと奥付で取り直すことにした。実際、1冊目は表紙に刷られた出版社が事前の想定と違っていて、実物に合わせて直した。
章の見出しで4回つまずいた
OCRが終わった本は、まず素のチャンクとしてDBに入る。1冊目は170チャンク、図219枚。これを目次と突き合わせて章と節にまとめ直す工程で、ずっと足を取られた。
最初の設計は素直だった。チャンクの章フィールドに節見出しがそのまま入っているので、目次テキストと自動照合すればいい。汎用のスクリプトを書かせて回した。
そこから先が、直すたびに別の壊れ方をする。
- マッチ率を上げようと本文冒頭の短い行も見出し候補に入れたら、誤マッチが出た。候補を「チャンクの冒頭にあり、かつ一致率が高いもの」に限定した
- 2冊目では、ページ上部の柱(ランニングヘッダー)が章タイトルと誤マッチした。柱は連続したページに繰り返し出るので、章見出しは短いチャンクだけに限る条件を足した
- それでも足りず、章エントリの照合そのものをやめた。節だけで区切り、章扉は境界検出で分ける方式に変えたら、88/100が一致して章境界も正しく取れた
- 4冊目は目次エントリが「フェーズ名+サブタイトル」の合成になっていて、本文中の見出しと一致しない。目次ファイルの記法を変え、表示名と照合キーを分けられるようにした
# 目次ファイルの1行(表示名|照合キー)
第2フェーズ 数字で確かめる|数字で確かめる
途中で、まとめた結果のチャンクが大きくなりすぎることにも気づいた。統合に6000字の上限を入れ、上限を入れる前に通していた1冊目と3冊目は取り込みからやり直した。1冊目は170チャンクが41にまとまった。
[ の入ったファイル名で、1冊だけバッチが落ちた
6冊のバッチのうち、4冊目だけがrc=1で落ちていた。ログを見るとファイル名の照合ミス。実ファイル名を確かめたら、名前に[が入っていた。Git BashのMSYS2はパスを自動変換するが、この文字を含む引数では変換が効かず、渡した先が別のパスとして扱われていた。
走っているバッチの邪魔をしたくないので、6冊目のOCR完了を待って4冊目を自動で流すジョブを組み、そちらはWindowsのパス表記で渡した。これで通った。
Kindleが「進んでいない」と言い張る
並行して走らせていたKindleのキャプチャが、この日いちばん時間を食った。
1回目は位置56/258で止まった。「位置が進んでいない」という判定で自動停止したらしい。ただ、画面のページ自体は進んでいた。
PDFを片付けてから再開させ、また止まった。今度は位置53。実際の画面を見たら、見開き2ページ表示で印刷ページの60から61を映している。手でページを送ってみると、ページはちゃんと進む。それなのに位置の表示は53のまま動かない。
原因はここだった。固定レイアウトの本では、位置の数字がページ送りに追従しない。停滞の判定を位置だけで見ていたので、ページが進んでいるのに止まったと誤検知していた。ブラウザ拡張の判定を最小限だけ直させ、拡張をリロードしてタブを読み込み直したら、36ページ、129ページと進み続けた。
最後は奥付に到達して正常に終わった。137ページ取れた。ただし3回に分けて走らせていたので、結合が要る。中身を確かめたら、3回目のバッチが表紙から始まる完全な1周だった。リロードで先頭に戻っていたためで、結局そのバッチだけを採用した。
見開き画像は1ページあたりの解像度が落ちる。心配だったので、1枚だけOCRにかけて品質を見てから全部を流した。この誤検知はその場しのぎで済ませたくなかったので、issueとして記録に残させた。
マンガ本で、消してはいけないもの
7冊目のマンガ本では、逆に「やらなくていいこと」をやりかけた。
- 図のファイル名パターンが他と違ったので専用のリネームを走らせたが、インポータ側がKindleの命名を内部で処理していたので不要だった。誤って変えた2件を元に戻した
- 章扉が見出し記法になっておらず、前のチャンクに吸収されていた。分割しようとしたら、分割対象を目次のテキストのほうに当ててしまった。手で継ぎ接ぎせず、取り込みからやり直してクリーンな状態に戻した
- クリーンアップで装飾図の除去は行わなかった。マンガはパネル自体が本文なので、消すと中身が消える
PDFの6冊は、図の判定用にコンタクトシートを31枚作らせ、目視で装飾図を選り分けた。装飾図のリストを作ってから6冊まとめてクリーンアップし、全文検索インデックスの再構築は最後に1回だけ回した。仕上げに残ノイズを見ると2冊に柱が残っていたので、パターンを確認して除去した。適用前に差分を目で見て確かめてから通した。
Web側の表示も見て、6冊とも「整」「済」のバッジが付き、図がR2から出ていることを確認した。これで7冊すべてが終わった。
買う理由を思い出せない本があった
昼前、別のところでつまずいた。Googleタスクに前から積んであった「買って読む」グループの中身を確認したときのことだ。3グループで7〜8冊ある。1冊はすでに電子化済みで買う必要がなく、1冊は手持ちが古い版だと分かった。
引っかかったのは投資情報誌だった。なぜこれを買うことにしたのか、自分で思い出せない。競合として見るつもりだったのだろうか。
調べさせたら、理由は競合ではなかった。読者リサーチ用の資料として挙がっていた。しかもその必要性は、まだ確定していない読者像の仮置きにぶら下がっていた。いらない気がしていたのは、根拠のほうが浮いていたからだった。
この経緯をメモに残させた。「加えて」と頼んだので、既存の記述は1文字も消さず、該当項目の下とタスクのメモ末尾の2か所に足す形にしてもらった。
学び
- 文字化けは2回起きた。Windowsのコンソールに日本語を吐かせず、最初からUTF-8のファイルに書き出させるのが結局いちばん早い
- 見出しの自動照合は、条件を足して精度を上げるより、当てにいく対象を減らしたほうが効いた。章をあきらめて節だけで区切った瞬間に一致率が上がった
- 「止まった」という自動判定は、何を根拠に止まったと言っているかを疑う。位置の数字が動かないことと、ページが進んでいないことは同じではない
- Kindleのライブラリに入っている本が、自動取り込みを通せるとは限らない。買う前に経路を確かめる
- 買う予定の本は、書名だけでなく「何のために要るのか」をメモに残しておかないと、あとから自分で判断できない