«前の日記(2010年11月16日) 最新 次の日記(2010年12月14日)» 編集

混沌の庭研究所

1998|06|07|08|09|10|11|12|
1999|03|04|05|06|07|08|09|10|11|12|
2000|01|02|03|04|05|06|07|08|09|10|11|12|
2001|01|02|03|04|05|06|07|08|09|10|11|12|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|06|07|08|09|10|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|05|06|07|08|10|11|12|
2011|01|03|09|
2012|02|03|
2013|05|12|
2019|10|

2010年12月13日 月曜日 [長年日記]

_ [Perl] ライトノベルのあらすじを使って遊ぶ

ライトノベルのあらすじからトレンドを知ることができるか」を読んで、同じようにやってみました。自分、Perlしか使えないので、こちらはPerlで。

まず、「ラノベの杜 - DB検索」のデータを元にアマゾンからあらすじのテキストを取ってきます。とりあえずサンプルとしてdengeki-bunko.tsvをダウンロードします。

ダウンロードしたtsvファイルは、後々の事を考えてUTF-8に変換しておきます。

nkf -S -w dengeki-bunko.tsv > dengeki-bunko.utf-8.tsv

実験として、とりあえず「とある魔術の禁書目録」でやってみましょう。

grep 'とある魔術の禁書目録' dengeki-bunko.utf-8.tsv > toaru.tsv

「とある魔術の禁書目録」のデータだけを取り出したtoaru.tsvができました。このファイルの中からISBNコードを取り出し、このISBNコードからアマゾンの該当ページを取ってきて、その中からあらすじ部分を抽出します。そのために作ったスクリプトがget_amazon_data.plになります。このスクリプトでは抽出したあらすじテキストは入力ファイルの各行の末尾に追加して標準出力に書き出しますので、出力ファイルにリダイレクトしてください。なお、このスクリプト、昨今の事情を鑑みて1件データを取ってくると3秒待つようになっています。うまく取れなかったときは10秒待って取り直しを10回まで繰り返して、それでもダメだった場合はHTTPのステータスコードをあらすじテキストの代わりに記録するようになってます。そういうのが混じってる場合は手作業で直してやってくださいね。

ちなみに、2007年以降に発行された書籍は13桁のISBNコードが付与されているのですが、なぜかアマゾンでは存在しない10桁のISBNコードで書籍を指定する形になっています。ISBNコードの末尾の数字はチェックデジットといって、それ以外の桁の数字から計算して出てくる数字なのですが、そのため13桁のISBNコードのチェックデジットは10桁のISBNコードのチェックデジットとは異なっています。わざわざ10桁のコードを計算するのめんどくさいよ!

perl get_amazon_data.pl toaru.tsv > toaru_arasuji.tsv

ともかくこれで、toaru.tsvにあらすじが追加されたtoaru_arasuji.tsvができました。

あらすじテキストをMeCabで処理するために、あらすじテキストをセンテンスごとに分割します。日本語用のセンテンスカッターも探せばどこぞにありそうな気もしますが、まあ適当に作ってみました。スクリプトはsplit_sentence.plです。センテンスごとにISBN, センテンスをタブ区切りで出力します。

perl split_sentence.pl toaru_arasuji.tsv > toaru_sentence.tsv

ここまででMeCabで処理するためのセンテンスデータ、toaru_sentence.tsvが準備できました。MeCabは、Mac OS XならMacPortsを使ってインストールするのが楽ちんでしょう。また、PerlからMeCabを使うためにはText::MeCabをCPANからインストールする必要があります。

split_sentence.plで書き出したファイルから、get_noun_list.plを使ってセンテンスごとにMeCabに渡して名詞のリストを取り出します。このスクリプトでは、連続する名詞は複合名詞として繋ぐ処理を35-68行目でやっていますが……なにぶん、素人のやる事なので。抽出した名詞・複合名詞のリストは、入力ファイルの各行の末尾に追加する形で標準出力されます。

perl get_noun_list.pl toaru_sentence.tsv > toaru_noun.tsv

こうしてセンテンスごとの名詞のリスト、toaru_noun.tsvができたので、この名詞リストを集計してみましょう。まずは単純に集計するだけのバージョンです。スクリプトはcount_noun.plになります。

perl count_noun.pl toaru_noun.tsv > toaru_noun_count.tsv

出力されたtoaru_noun_count.tsvを見てみましょう。下に、最初の10行を表示してあります。

学園 都市26
上条 当麻22
上条16
インデックス16
物語14
魔術14
交差13
11
それ10
御坂 美 琴10

このテーブルを見てみると、「上条 当麻」が22、「上条」が16となっています。これは、「とある魔術の禁書目録」既刊24冊のあらすじ中に「上条当麻」が22回、他に何も付かないただの「上条」が16回出てきたことを表しています。単純にカウントするだけならこれでもいいのですが、「上条」には「上条当麻」の22回も追加してやりたいという気もしますね。というわけで、次はこの辺も考慮してカウントしてみましょう。なお、get_noun_list.plでは複合名詞を作る際に名詞の間にスペースを挿入しているため、複合名詞は後からスペースで名詞に分割する事もできるという寸法です。

上に書いたようにカウント方法を変更したスクリプトがcount_noun_with_sub.plになります。実行は先ほどと同じ。

perl count_noun_with_sub.pl toaru_noun.tsv > toaru_noun_count2.tsv

出力されたtoaru_noun_count2.tsvを見てみましょう。先ほどと同じように、下に最初の10行を表示してあります。

上条1640上条 当麻(22), 上条 刀 夜(1), 上条 宅(1)
魔術1427魔術 師(9), 魔術 師 ステイル(1), 魔術 組織(1), 魔術 業界 屈指(1), 魔術 側(1)
学園 都市2627学園 都市 最大 級 行事(1)
当麻123上条 当麻(22)
上条 当麻2222
インデックス1616
115一 人(6), 二 人(4), 三 人(3), 人 たち(1)
物語1414
科学914一般 科学(2), 反 科学 デモ(1), 科学 サイド(1), 科学 者(1)
御坂113御坂 美 琴(10), 御坂 妹(2)

先ほどのテーブルと比べてみましょう。3カラム目が欲しかった数値になります。ただ、ここでひとつ問題があります。「人(ひと)」のカウント結果に「一 人」「二 人」「三 人」が一緒に入っています。こちらの「人」は単位なので一緒に混ぜるのはどうかと思いますが、取ってきたそれぞれの名詞にどんな意味があるのかはリストからはわからないので、ここまでやってきた処理ではこの点はどうしようもありません。それにしてもインデックスさん、空気空気言われるわりにはあらすじだと御坂さんより回数上ですなー。

次に、電撃文庫全体を対象にしてあらすじに使用される名詞の経年変化とか見てみようと思ったのですが、いい加減時間が遅いのでそれはまた次回という事で。