Pythonで文章要約を開発してみた!TF-IDF理論で呪術廻戦キャラを3行で紹介してみよう!

業務で文章を要約するツールが必要だったので
自分なりに調べて開発してみました!

かじむー

Pythonで特にライブラリは使わず
簡単に開発
したい人向けです!

それだけだと勿体ないので
いまハマってる「呪術廻戦」を使って
ツールの出来栄えを確認してみたよ!

動画で見たい方はコチラ

文書を数値へ

文書を要約と言っても
コンピュータは数値じゃないと理解できませんよね!

なので文書を数値で表現しなければならない!

その方法としてBag-of-Wordsという手法を用います!

とその前に文書を処理しやすい形に整えますね!

文単位で区切る

まずはその文書を「文単位」で区切ろう!

ここは自分の扱う文書に沿って作りこむべし!

今回は「改行」「全角スペース」を「。」に置換した後
「。」区切りを1つの文章としてます!

形態素解析

次に区切った文章それぞれを単語で区切る
形態素解析を行います!

これはよく使われてる janome ライブラリを使いました!

かじむー

Pyinstallerで最後exeファイル化したい人は注意!

Python3.9の人は20行目のTokenizer 初期化時に
mmap=Falseオプションを付けましょう!
これしないとエラー出ちゃいます・・!

以下ドキュメントです!

Bag-of-Words

例えば次の3文があります!

私は虎杖が好き。
私は伏黒が嫌い。
私は釘崎が好き。

これらに使われている単語は

私・は・虎杖・伏黒・釘崎・が・好き・嫌い・。

それでは各文でこの単語の出現回数を出してあげると

てな感じで、文を数値で表せたね!!!

で、これよく見ると…!

そう!これは3行9列の行列なんですよね!
つまりベクトルです!

ベクトルなので「2つの文書がどれだけ似ているか?」を
2つのベクトルがどれくらい同じ方向を向いているか?」という
コサイン類似度で求める事もできるのです!

文書の評価

ではどうやって文書を評価して抽出するのか?

今回はTF-IDFに基づいて考えていこうと思います!

TF-IDFとは

文書の中でどの単語が重要かを表す」考え方です!

じゃあ単語の重要度ってどう決めるの?

定義は
ある文書ではよく出てくる(TF)けど他の文書ではあまり出てこない(IDF)単語
となります!

なのでTF値とIDF値を掛け合わせた値(TF-IDF)が大きいほど
その単語は重要となる!

TFとは

単語の出現頻度です!

TF = 単語Tの出現回数 / 全単語の出現回数

IDFとは

文書毎のその単語のレア度です!

IDF = log( 文書の総数 / 単語Tを含む文書の数 )

なぜ対数なのか?分母と分子が逆じゃない?とか思った人!
私と一緒です( ̄▽ ̄)笑

こちらを参考に色々考えさせられました!

珍しさを定量化した情報量(エントロピー)
そもそも対数とは「掛け算を足し算に直す」もの!
場合の数は足し算ではなく掛け算で増えていくから対数を使う!

などなど興味ある人は深堀してみて下さい!

TF-IDFを算出してみる

例えば呪術廻戦の公式サイトのイントロダクションから
少し抜粋してみました! ※多少修正アリ

人間が生む負の感情は呪いと化し日常に潜む。
呪い呪いでしか祓えない。
驚異的な身体能力を持つ少年虎杖はごく普通の高校生活を送っていた。
しかしある日呪いに襲われた学友を救うため己の魂に呪いを宿してしまう。
少年の後戻りのできない、壮絶な物語が廻りだす。

呪術廻戦公式サイト

呪い」「少年」「虎杖」の3つの単語に注目したとき
どの単語が重要か?TF-IDFを出してみると・・・

虎杖:1.32
少年:0.74
呪い:0.32

つまり「虎杖」と言う単語がこの中で重要だと分かるね!
逆に「少年」「呪い」はその文書を特徴づけるものではないと言えるね!

という感じで
各単語の重要度を数値で出せば、各文章をスコア化できるので
スコアが高いほど重要な文章だと言えるね!

呪術廻戦キャラを3行でまとめてみよう

メイン関数

それではこれまで作った関数を呼び出して
文書を3行に要約するメイン関数を作ります!
個人的に「関係ない文書を省く」という処理も必要だったので
その部分も含んでおります!

登場人物の紹介文を3行で要約してみる

それでは作ったツールで要約をしてみよう!

虎杖

本作の主人公。都立呪術高専1年生。宮城県仙台市出身。3月20日生まれ。常人離れした身体能力の持ち主。元々は非術師であったが、宿儺の指を口にしたことで呪力を手にし… <<中略>> …が作者から語られている。 両親はおらず(生死・行方ともに不明)、祖父に育てられた。両親についての記憶は特にないらしく、祖父から話を切り出された際も一切の興味を示さなかった。

Wikipedia

これらを要約すると・・・

3月20日生まれ。
黒閃1日5回記録。
両親はおらず(生死・行方ともに不明)、祖父に育てられた。

なるほど。何か足りない気もするが…うん!笑

もう一人やってみよう!

伏黒

都立呪術の高専1年生で、虎杖の同級生に当たる2級呪術師。12月22日生まれ。甚爾の息子であり、恵という名前は父から付けられた。御三家・禪院家の血筋であり、その分家出身と見なされている。実の両親は…<<中略>>…駆け付けてきた宿儺によって救出された。 好きな食べ物は生姜に合うもの(生姜そのものではないらしい)。嫌いな食べ物はパプリカ。実話系の本を読むことが多い。部屋着はとにかく楽なものを選ぶ。

Wikipedia

これを要約してみると・・・

実の両親は共に亡くなっており、小学1年時から1つ年上の義姉・津美紀と共に暮らしている。
好きな食べ物は生姜に合うもの(生姜そのものではないらしい)。
部屋着はとにかく楽なものを選ぶ。

面白い!笑
能力の話より、人となりを表す部分が重要視されてるね!

総括

今回は文章要約を1から作ってみて
テキストマイニングの理解度がかなり深まりましたね!

正直まだまだ奥深くてこれだけじゃ全然足りないですが(;’∀’)

単語をベクトルで表してくれるWord2Vecを使って
重要な単語の類似単語まで加味して要約するともっと精度上がるかも!

いつも発信している業務改善・効率化の内容とは違ったけど
文章を厳選する作業の手助けになるかも!

個人的には機械学習をさせて開発してみたいな…!
そのうち記事UPできるように頑張ります!

かじむー

業務改善をしたい現場のあなた!中小企業の方々!
お気軽にご相談ください♪