O'Reilly の電子書籍をテキストマイニング
上記の環境を整えたかった理由のひとつとして電子書籍のテキストマイニングがある。
Amazon Kindle や 楽天 Kobo などの電子書籍データは暗号化されているため正当な方法で抽出することができないが、オライリー出版の電子書籍は DRM フリーの EPUB 形式で配信されている。
EPUBは、HTMLやウェブブラウザのオープン性を保持しつつ、インターネット接続が切断された状態の携帯情報端末(PDA)やノートパソコンなどでも電子書籍の閲覧が継続できるようにダウンロード配信を前提にパッケージ化された、XHTMLのサブセット的なファイル・フォーマット規格であり、画面の大きさに合わせて表示を調整する「リフロー機能」が特徴である(固定する設定も可能)。
EPUB はXHTMLのサブセットをZIPで固めたものであるため、一般的なウェブサイトスクレイピングの手法を応用することで比較的簡単に解析できる。
EbookLib で EPUB を読み出して頻出単語を解析
今回のプログラムには EbookLib を利用する。 Kindle フォーマット解析も開発中とあるが、今のところは EPUB2 と EPUB3 に対応している。 requirements.txt に以下のモジュールを追加して pip3 install -r requirements.txt を実行
lxml==4.6.3 ebooklib==0.17.1
以下のプログラムで利用できる。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- __version__ = "0.1.0" import argparse import logzero import settings import ebooklib from ebooklib import epub import re import mecab_tokenize class EpubTokenize: def __init__(self): logzero.logfile( settings.logfile, loglevel=20, maxBytes=1e6, backupCount=3 ) self.logger = logzero.logger self.mecab = mecab_tokenize.MecabTokenize() def extract_epub_text(self, path): text = '' for item in epub.read_epub(path).get_items(): if item.get_type() == ebooklib.ITEM_DOCUMENT: text += re.sub(r'<.+?>', '', item.get_content().decode()) return text def freq(self, text): df = self.mecab.freq(text, count=10) return df[df['info1'].isin(['名詞', '動詞']) & (df['term'].str.len() >= 2)] def main(self, args): self.logger.info(f'{__file__} {__version__} {args}') text = self.extract_epub_text(args.path) df = self.freq(text) df.to_csv(args.path + '.freq', sep='\t') if(__name__ == '__main__'): parser = argparse.ArgumentParser() parser.add_argument( '--version', action='version', version=f'{__version__}' ) parser.add_argument('path') args = parser.parse_args() EpubTokenize().main(args)
extract_epub_text() でテキストを抽出して正規表現でタグを除去。freq() で10個以上カウントされた単語を pandas.DataFrame 形式で取得して、さらに2文字以上の名詞と動詞で単語を絞り込んでいる。 mecab_tokenize についてはこちらを参照のこと。
オライリー出版の EPUB 電子書籍の頻出単語を表示
% docker-compose run --entrypoint "python /data/src/epub.py" mecab-test '../work/oreilly_test.epub' Creating mecab-test_mecab-test_run ... done [I 210530 18:18:39 epub:35] /data/src/epub.py 0.1.0 Namespace(path='../work/oreilly_test.epub') % head work/oreilly_test.epub.freq term info1 info2 freq 6 gt 名詞 固有名詞 4298 10 する 動詞 自立 2731 12 () 名詞 固有名詞 1775 14 よう 名詞 非自立 1160 15 こと 名詞 非自立 1085 17 プログラム 名詞 サ変接続 977 21 ファイル 名詞 一般 755 23 文字列 名詞 固有名詞 678 25 でき 動詞 自立 659
gt は本文内の「> 」なので除去対象にしても良いかもしれない。ここまででオライリー出版の EPUB 電子書籍の形態素解析ができた。書籍内に出てくる単語の頻度を解析することで、その文章のジャンルを推定したり、新しい用語が広がっていった過程を知ることができる。簡単なスクリプトなので必要に合わせたカスタマイズも容易だ。
EPUB形式の電子書籍を解析対象として保有する意義
例えば『お好み焼きの戦前史 第二版』においても過去文献類をスキャンしたり、ネット上の文献をダウンロードすることで作成した電子テキストデータ群を解析することで料理方法の初出や普及の過程を明らかにしており、電子テキストデータ群の準備こそが重要な研究材料となっている。
基本的には Amazon Kindle のロックインから離れられるとは思えないけれど、解析対象としての電子書籍所有という観点の場合は EPUB 形式のがありがたい。そもそも編集作業はデジタルで行なっているのが当たり前になってきているのに電子テキストデータが隠されているのは残念な状況。
もちろん、簡単にコピーできないようにするのも必要な措置だが、例えば国会図書館への寄贈については最終稿のデータ入稿もセットで求めていかないと無駄な再デジタル化コストやOCRの誤判定などによる研究の非効率化が出てきてしまうのではないかと思えた。これからは、EPUB形式の電子書籍を解析対象として保有する意義についても意識したい。