もっと詳しく

前回の記事に引き続き、今回は Python + pysummarization という組み合わせで文書要約をしてみます。

ニューラルネットワーク言語モデルを使用しているという事なので、sumy との要約結果の違いも気になるところです。

sumy よりも使い方が簡単なので、今回は関数にしています。

とりあえず試したい方は、掲載しているソースコードをコピペして実行してみて下さい。



pysummarizationの概要

pysummarization は自然言語処理とニューラルネットワーク言語モデルを用いた 自動要約のPythonライブラリです。

内部で深層学習(ディープラーニング)ライブラリのpydbmが使用されており、RNNの改良版LSTMによるエンコーダー/デコーダーを実装しているところが特徴です。

また、日本語の自動要約を行うためには、Mecab を利用する必要があります。

英語ですが、公式ページに使い方が紹介されています。



インストール方法

あらかじめ、MeCabをインストールしておく必要があります。

32bit 版のPythonをお使いならMeCab公式サイトからインストーラー(mecab-0.996.exe)をダウンロードして下さい。

64bit 版のPythonをお使いなら、こちらのサイトからインストーラー(mecab-0.996-64.exe)をダウンロードして下さい。

尚、64bit版のMeCab のインストール方法については、こちらの記事でも詳しく解説しています。

次に、以下の通り pip コマンドで必要なライブラリをインストールします。

pip install pysummarization
pip install mecab-python3
pip install unidic-lite
pip install nltk



pysummarization の使い方

以下の通り、必要なモジュールをimport します。

from pysummarization.nlpbase.auto_abstractor import AutoAbstractor
from pysummarization.tokenizabledoc.mecab_tokenizer import MeCabTokenizer
from pysummarization.abstractabledoc.top_n_rank_abstractor import TopNRankAbstractor

下記は、もっとも簡単なサンプルです。

#全ての行を結合
document = "スタートレックには長い歴史がある。現在も人気が衰えず、次々と新作が登場している。"
# 自動要約のオブジェクトを生成
auto_abstractor = AutoAbstractor()
# トークナイザー(単語分割)にMeCabを指定
auto_abstractor.tokenizable_doc = MeCabTokenizer()
# 文書の区切り文字を指定
auto_abstractor.delimiter_list = ["。", "\n"]
# キュメントの抽象化、フィルタリングを行うオブジェクトを生成
abstractable_doc = TopNRankAbstractor()
# 文書の要約を実行
result_dict = auto_abstractor.summarize(document, abstractable_doc)

summarizer は戻り値として辞書を返してきます。

この辞書に対してキーにsummarize_resul’ を指定すると、要約文書のリストが受け取れます。

従って、次の様に記述することで要約された文書が取り出せます。

#要約結果の取り出し
for x in result_dict["summarize_result"]:
    print(x)

ちなみに、result_dict のキーに ‘scoring_data’ を指定すると、抽出された行番号と重要度が取得できます。

文書要約関数について

では、さっそく文書要約関数の概要、リファレンス、ソースコードの順に紹介していきたいと思います。

関数の使い方

関数名は document_summarize で、引数にファイル名を指定するだけです。

document_summarize(ファイル名のパス)

戻り値として、要約文書のリストが返されます。

例えば、Pドライブ直下にあるstartreck.txt を要約したい場合、以下の様になります。

#文書の要約
lines =  document_summarize('p:/startreck.txt')

#要約結果の表示
for line in lines:
    print(line)

検証で使ったPCはWindows10マシンなので、サンプルソースはPドライブ直下に保存した startreck.txt というファイルを読み込むようになっています。

また、ファイルの中身は以下の通りです。

スタートレックは、22世紀から24世紀の話である。設定では、2026年から2053年にかけて発生した第三次世界大戦により、6億人の犠牲者と文明の崩壊が起きている。2063年にゼフラム・コクレーンがワープエンジンを開発、試験飛行中にバルカン時に発見され、ファーストコンタクトを果たした。 2151年には初代エンタープライズ号「NX-01」が竣工し、クリンゴンとのファーストコンタクトを果たしている。2153年にロミュラン人との戦争が勃発、2161年に地球連合、バルカン、アンドリアが中心になり惑星連邦が設立された。 地球人は銀河系内の約4分の1の領域に進出し、様々な異星人との交流を行っている。 既に貧困や戦争などは根絶されており、見た目や無知から来る偏見、差別も存在しない、理想的な世界となっている。 レプリケーターの登場により貨幣経済は無くなり、人間は富や欲望ではなく人間性の向上を目指して働いている。 しかし、個人財産は存在しており、ワイナリーや宇宙船を所有する一部の恵まれた人々が存在する。 惑星連邦の本部はパリにあり、宇宙艦隊の本部はサンフランシスコに存在する。 惑星連邦内では軍事力による紛争が根絶されたが、クリンゴン帝国やロミュラン帝国、カーデシア連合などの侵略的な星間国家とは必ずしも良好な関係を築けていない。 『スタートレック:エンタープライズ』では惑星連邦設立以前の時代を、『スタートレック:ディスカバリー』では、地球連合やバルカン星などが脱退、惑星連邦が瓦解した32世紀の世界が描かれている。 長く続く作品では、これまでの作品を「なかったこと」にし、設定を一新することがしばしばあるが、スタートレックのシリーズではほぼすべての作品が同じ宇宙を共有している。 一方、作品の根幹としてマルチバースの概念が取り入れられ、物語の主軸として描かれている宇宙とは異なる平行宇宙(パラレルワールド)が登場することもある。 劇場版第11作から劇場版第13作まではリブート作品ではあるが、タイムトラベルの影響で歴史が変わったという設定で、シリーズとしての連続性は保たれている。 タイムトラベルを扱った作品はスタートレックの中でしばしば登場し、異なる歴史を持つパラレルワールドがいくつも存在している。

要約結果は重要度から順に10行が返って来ます。

今回は以下の通り要約されました。

スタートレックは、22世紀から24世紀の話である。
設定では、2026年から2053年にかけて発生した第三次世界大戦により、6億人の犠牲者と文明の崩壊が起きている。
2063年にゼフラム・コクレーンがワープエンジンを開発、試験飛行中にバルカン時に発見され、ファーストコンタクトを果たした。
2151年には初代エンタープライズ号「NX-01」が竣工し、クリンゴンとのファーストコンタクトを果たしている。
2153年にロミュラン人との戦争が勃発、2161年に地球連合、バルカン、アンドリアが中心になり惑星連邦が設立された。
地球人は銀河系内の約4分の1の領域に進出し、様々な異星人との交流を行っている。
惑星連邦内では軍事力による紛争が根絶されたが、クリンゴン帝国やロミュラン帝国、カーデシア連合などの侵略的な星間国家とは必ずしも良好な関係を築けていない。
『スタートレック:エンタープライズ』では惑星連邦設立以前の時代を、『スタートレック:ディスカバリー』では、地球連合やバルカン星などが脱退、惑星連邦が瓦解した32世紀の世界が描かれている。
長く続く作品では、これまでの作品を「なかったこと」にし、設定を一新することがしばしばあるが、スタートレックのシリーズではほぼすべての作品が同じ宇宙を共有している。
タイムトラベルを扱った作品はスタートレックの中でしばしば登場し、異なる歴史を持つパラレルワールドがいくつも存在している。

ソースコード

関数のソースコードは次の通りです。

from pysummarization.nlpbase.auto_abstractor import AutoAbstractor
from pysummarization.tokenizabledoc.mecab_tokenizer import MeCabTokenizer
from pysummarization.abstractabledoc.top_n_rank_abstractor import TopNRankAbstractor


def document_summarize(file):

    #ファイルの読み込み
    with open(file,encoding='utf-8') as f:
        contents = f.readlines()      
    
    #全ての行を結合
    document = ''.join(contents)
    # 自動要約のオブジェクトを生成
    auto_abstractor = AutoAbstractor()
    # トークナイザー(単語分割)にMeCabを指定
    auto_abstractor.tokenizable_doc = MeCabTokenizer()
    # 文書の区切り文字を指定
    auto_abstractor.delimiter_list = ["。", "\n"]
    # キュメントの抽象化、フィルタリングを行うオブジェクトを生成
    abstractable_doc = TopNRankAbstractor()
    # 文書の要約を実行
    result_dict = auto_abstractor.summarize(document, abstractable_doc)

    return [x.replace('\n','') for x in result_dict["summarize_result"]]



まとめ

今回は文書要約用のライブラリ pysummarizationのインストール方法、使い方、そしてこれを使った自作関数の説明、ソースコードについて紹介しました。

pysummarizationはニューラルネットワーク言語モデルによる文書要約であり、要約精度に定評があります。

要約行数は10行固定ですが、sumy と違って重要度が取得できるので、これを使って更に行数を絞り込むことも可能です。

MeCabをインストールする必要があるため、少々面倒かもしれませんが、興味のある方は是非お試しください。