長文テキストを自動要約しよう（その2） 〜pysummarization〜

**2022/5/15 :pysummarizationによるテキスト要約を「生成型」と表現していましたが「このコード内容は抽出型」であるようです。「生成型である」との表現は記事からカットしました。**

# はじめに
テキストを自動で要約してくれるPythonライブラリがあります。
長文、短文に関わらずテキストを与えると、ぎゅっとまとめた要約文を返してくれるというものです。

[**前回の記事「長文テキストを自動要約しよう（その1）」**](https://qiita.com/hima2b4/items/03b1cf2d2fb5669c5142)で「抽出型」のPythonライブラリ（sumy）を紹介しました。
今回は **pysummarization** というライブラリの適用例を記事にしたいと思います。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1275001/678ead80-59d4-25f1-bb84-67f4ea8285ad.png)

##pysummarizationについて
>- **pysummarization**は、自然言語処理とニューラルネットワーク言語モデルを用いたPythonのテキスト自動要約ライブラリです。
- テキストのフィルタリングとクラスタリングを「教師あり学習」を必要とすることなく、対象テキストの概要が要約できます。
- 制作者 Accel Brain社曰く「LSTMをベースとしたSequence-to-Sequence（Seq2Seq）の学習を実現するニューラルネットワーク言語モデルの基礎的なモデルをre-seq2seqの学習モデルや再構成モデルに応用することで、文書自動要約器を実装したもの」とあります。



## 実行条件&やってみたこと
>- **Google colab**で実行
- [**Wikipediaのヘビーメタル**](https://ja.wikipedia.org/wiki/%E3%83%98%E3%83%B4%E3%82%A3%E3%83%A1%E3%82%BF%E3%83%AB) の内容を要約した。
- パソコン内の任意のファイルを選択するダイアログが表示されるGoogle colabの機能を使用（対象ファイルはtxtファイルのみ）
-類似性フィルターカットオフ設定をGoogle colabの機能（フォーム：スライドバー）で対応　※設定幅： min:0.05, max:0.5, step:0.05, Default=0.25

# ライブラリインストール＆インポート
```Python:pysummarizationインストール
pip install pysummarization
```

```Python:Mecabインストール
#Mecabのインストール
!pip install mecab-python3==0.996.5
```
```Python:
import pandas as pd
```

#テキスト読込み

```Python:Google‗colabファイル読込みダイアログ
from google.colab import files
print('txtファイル(UTF-8）を指定してください')
uploaded = files.upload()

for fn in uploaded.keys():
  print('User uploaded file "{name}" with length {length} bytes'.format(name=fn, length=len(uploaded[fn])))
```
※以下は「heavy.text」というファイル読込み後の表示をキャプチャしたものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1275001/7ee9b86e-b95c-fdc0-bad6-c0b6df9f8ee4.png)


```Python:類似性フィルターカットオフ設定
#@title 類似性フィルターカットオフ設定（Defalt = 0.25） { run: "auto" }
similarity_limit = 0.25 #@param {type:"slider", min:0.05, max:0.5, step:0.05}
```
※上記記述で以下のフォームが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1275001/3c5c5f90-d27c-0158-19b7-12af055d1761.png)


# テキスト要約処理
```Python:原文書の処理
if len(uploaded.keys()) != 1:
    print("アップロードは１ファイルにのみ限ります")
else:
    target = list(uploaded.keys())[0]
    
with open(target) as f:
    contents = f.readlines()

document = ''.join(contents).replace(' ', '').replace('　', '')
```

```Python:要約処理
print(u'[原文書]')
print(document)
    
# 自動要約のオブジェクト
auto_abstractor = AutoAbstractor()
# トークナイザー設定（MeCab使用）
auto_abstractor.tokenizable_doc = MeCabTokenizer()
# 区切り文字設定
auto_abstractor.delimiter_list = ["。", "\n"]
# 抽象化&フィルタリングオブジェクト
abstractable_doc = TopNRankAbstractor()
# 文書要約
result_dict1 = auto_abstractor.summarize(document, abstractable_doc)

print(u'[要約結果]')
# 出力
for sentence in result_dict1["summarize_result"]:
    print(sentence)
    
# NLPオブジェクト
nlp_base = NlpBase()
# トークナイザー設定（MeCab使用）
nlp_base.tokenizable_doc = MeCabTokenizer()
# 類似性フィルター
similarity_filter = TfIdfCosine()
# NLPオブジェクト設定
similarity_filter.nlp_base = nlp_base
# 類似性limit：limit超える文は切り捨て
similarity_filter.similarity_limit = similarity_limit

# 自動要約のオブジェクト
auto_abstractor = AutoAbstractor()
# トークナイザー設定（MeCab使用）
auto_abstractor.tokenizable_doc = MeCabTokenizer()
# 区切り文字設定
auto_abstractor.delimiter_list = ["。", "\n"]
# 抽象化&フィルタリングオブジェクト
abstractable_doc = TopNRankAbstractor()
# 文書要約（similarity_filter機能追加）
result_dict2 = auto_abstractor.summarize(document, abstractable_doc, similarity_filter)

print(u'[要約結果：Similarity Filter機能]')
# 出力
for sentence in result_dict2["summarize_result"]:
    print(sentence)
```

```Python:データフレーム化
doc0 = ''.join(s for s in document)
doc1 = result_dict1["summarize_result"]
doc2 = result_dict2["summarize_result"]
doc1 = ''.join(s for s in doc1)
doc2 = ''.join(s for s in doc2)
lst1 = ["原文書","要約文書","要約文書:SF"]
lst2 = [doc0,doc1,doc2]
df = pd.DataFrame(list(zip(lst1,lst2)), columns = ['Class.','Content'])
df = df.replace( '\n', '', regex=True)

with pd.option_context('display.max_rows', None, 'display.max_columns', None, 'display.colheader_justify','light', 'display.width', 2000, 'display.max_colwidth', 500):
    df = df.stack().str.lstrip().unstack()
    df = df.style.set_properties(**{'text-align': 'left'})
```


# テキスト要約結果
```Python:データフレーム表示
df
```
※見やすいかな思い、こうしただけです。
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1275001/c0e1a881-6d16-2664-f837-29cf2f8ed3e6.png)


# 要約結果
><details><summary>**要約結果**</summary><div>
ハードロック/ヘヴィメタルは70年代半ばごろから、アリーナ・ロックや産業ロック的なバンドと、アルバム志向のヘヴィメタル・バンドに分かれる傾向も見られ、また、時代が新しくなるにしたがって、シーンも細分化が進んできた。シーンの細分化によって、ヘヴィメタルは様々な「サブジャンル」を持つようになった。このジャンルに分類されるバンドのサウンドはハードロック[5]同様、エレクトリック・ギターのファズやディストーションを強調した、ラウドなものであるのが基本である。ヘヴィメタルという用語自体は、70年前半から存在したが、ハードロックが70年代前半にピークを迎えた後、パンク・ロックの性急感を加えて存続したジャンルである。ハードロックとヘヴィメタルの間に厳密な境界線は無く、ハードロックとヘヴィメタルとを一括りにしてHR/HM（HM/HR）と呼ぶこともある。英国のハードロックは1970年代前半に一時代を築き上げるが、ハードロック、プログレッシブ・ロックのマンネリ化への反動や大不況などから、1970年代半ばにパンク・ロック・ムーヴメントが起きる。『サウンズ』誌の記者ジェフ・バートンにより「NWOBHM（ニュー・ウェイヴ・オブ・ブリティッシュ・ヘヴィ・メタル）」と名付けられたこのムーヴメントは、少しずつ知られるようになっていった。またモーターヘッドは、ロックンロールにパンク・ロック的な要素やスピード感のあるリズムを導入し、後のハードコア・パンクやスラッシュメタルの先駆けにもなった。MTVはヘヴィメタルバンドを大々的にバックアップし、産業化が進んでいくこととなる。このようなサブジャンル化（後述）は現在も止まることなく進んでいる。
</div></details>

><details><summary>**要約結果:SF(0.25)**</summary><div>
ハードロック/ヘヴィメタルは70年代半ばごろから、アリーナ・ロックや産業ロック的なバンドと、アルバム志向のヘヴィメタル・バンドに分かれる傾向も見られ、また、時代が新しくなるにしたがって、シーンも細分化が進んできた。シーンの細分化によって、ヘヴィメタルは様々な「サブジャンル」を持つようになった。また、ドラムソロやベースソロも行われることも多く、歌よりも演奏で魅せるような曲も多く、インストゥルメンタルの曲も多い。このようなサブジャンル化（後述）は現在も止まることなく進んでいる。
</div></details>

# 最後に
[**前回**](https://qiita.com/hima2b4/items/03b1cf2d2fb5669c5142)は ライブラリ sumy を、今回はライブラリ **pysummarization** を扱いました。
いずれも同じデータを要約しましたので、純粋に比較することもできました。

まず、**起動の手軽さ**ですが、
sumyは、自然言語ライブラリの読込みに数分要するのに対し、pysummarizationはほとんど時間を要しませんでした。sumyはGiNZAを再インストールしないこともありましたので、これら含め**手軽さはpysummarizationの方がよかった**です。

次に、**テキスト要約**の内容ですが、
こちらも、pysummarizationがsumyを圧倒しているように思えました。
要約内容のよしあし判断はむつかしいですが、sumyの要約は少し切り取り感を覚えるに対し、**pysummarizationの要約はスマート**さを覚えます。
「機械も侮れんな」、どころか、同じレベルの要約はできないじゃないか（できたとしても相当な時間を要する）と感じました。すごいです。


Pythonでテキスト要約したいがどれを使えばよいか探しておられる方がおられれば、私は2つしか試していませんが、おすすめはpysummarizationですね。

今回の記事は、ここまでです。最後まで読んでいただき、ありがとうございました。


※以下は、制作者のAccel Brain社のTweetです。これもやってみたいと思います。

https://twitter.com/AccelBrain/status/1299901783712567296?s=20


## 参考サイト
https://zerofromlight.com/blogs/detail/35/

https://www.digest.elyza.ai/summaries/9741964532070237615