年始休暇中に(自分向け)論文管理ツールを実装しました。
モチベーション
1年前ぐらいに Mendeley という論文管理ウェブサービスを試してみましたが 同じ論文が重複に登録されたりして何かイマイチだなぁと感じてその後は使っていませんでした
具体的には、フォルダ(Collection)間をドラッグアンドドロップして論文移動させると重複に存在するようになってしまうという現象が特にイマイチな感じでした。
デスクトップ版は今では重複チェック機能が実装されているらしい(参考記事)ですが、Web版は確認する限りではそのような機能はありません
Mendeley以外の選択肢としては、Google製の Paperpile というのが良いようなのですが有料サブスクリプションで $3/月 かかります。
$3/月なので高いとまでは思いませんがお金払ってまでまじめに論文管理したいわけでもないんだよなと思って自作ツールを開発することにしました
要件と仕様
要件
- ファイル名から重複チェックができる
- タイトル抽出してキーワードサーチができる(ファイル名だけだとpdfファイルを開くまで何の論文か分からないため)
- 同様に、Abstract抽出して キーワードサーチができる
そして、仕様は「論文からファイル名、タイトル抽出、Abstract抽出してcsvファイルに保存する」というミニマム仕様です。
PDFファイルからの文字抽出
Pythonでpdfファイルから文字抽出するのは何種類かパッケージがあります。
上の記事の中で取り上げられてた PyPDF2 と PDFMiner を試してみましたが PDFMinerが良さそうです。 Qiitaで参考にした記事でも PDFMiner を使ってました。
タイトル抽出とAbstract抽出
基本的には タイトル抽出は 2番目のQiita記事で書かれているように Bouding Boxのheightが一番高い行を抽出してくれば大半の論文では抽出できます。
Abstract抽出は "Abstract" という行を抽出して、"Introduction" の行までを切り出せばokです。
手こずったところ(タイトル抽出編)
Title行抽出で単純にはうまくいかずちょっと苦労したのがいくつかあったので紹介しておきます
Author行が一番大きいheightになっているパターン
上付き文字があると見た目の高さ以上のheightになっていて、そこがTitle行として判定されてしまいます
以下の図では数字がその行のheightを表しています
Author行っぽいか / 所属機関行っぽいか を判定するルールを追加して対処しました。
複数行に渡るタイトルで heightの高さが揃ってない
ほとんどの論文では同じheightが複数行にわたるのでheightが同じ行が続くかどうかで判定すればよいのですがそうはならない論文も中にはあります。
仕方ないので完全に同一のheightが続くという条件を少し緩和しました
手こずったところ(Abstract抽出編)
基本的には Abstract という行を抽出して、Introductionの行までを切り出せばokですがTitle抽出と同様にいくつかそれが当てはまらないケースがあり苦労しました。
Abstractの文字がないパターン
Abstractの文字をサーチして、Abstract行の先頭を特定できません
先にIntroductionの行を抽出してそこからエリア推定します。
2カラム形式になっているパターン
Abstract行の直後にIntroductionが来るのでAbstractブロックを正しく抽出できません
下の図のような論文で BoundingBox抽出すると、Abstractの先頭行の後にIntroduction行が続き、その後にAbstractの本文が続きます。
改行されていることを判定する(上のブロックとの位置関係から分かる)ことでうまく抽出できるようになりました。
開発してみて
もっと簡単にいくのかなと思っていたので意外と課題はありましたがそれらに対応したルールを1個ずつ追加してうまくできるようになりました。
とりあえず手元の420個程度の論文で試してみる限りは全体として99%程度うまくいっていて満足です。
1997年の古い論文とか日本語の論文とか、一部の論文ではうまく情報抽出できてませんでしたが2010年あたり以降の新しい論文は基本うまくいっています。
自分の手持ちの論文に完全にチューニングされているルール/パラメータになってますがarxivの機械学習系の論文だったらそれなりの精度で動く気はしてます。
Author行かどうかの判定に苦労したので 今後はBERTの固有表現抽出等を組み込んで判定できると面白いと思っています。