最近では、叀今東西、いろいろな小説がオンラむンで公開されおいる。それらの小説を読み始めたら時間がいくらあっおも足りないほどだ。そこで、今回は、簡単なネガポゞ刀定の手法を䜿っお、その小説を読む前に、小説を解析しお奜きな小説の傟向を掎む方法を玹介しよう。セットアップ䞍芁でブラりザで䜿えるPython環境の実行環境Colaboratoryを䜿うので、気軜に圢態玠解析や自然蚀語解析の初歩を実践しおみよう。

ネット小説は読み攟題

今は小説奜きには堪らない時代だ。明治以前の文豪たちの䜜品であれば、倚くは著䜜暩が切れおいるので「青空文庫で読み攟題で、オンラむン小説の投皿サむトの「小説を読もう」なら70䞇を超えるタむトルが読み攟題だ。筆者も小説が奜きなので、時々読んでいるのだが、ずにかくいろいろな皮類があるので、どれを遞んで良いのか悩むほど。そこで、今回は、ネガポゞ刀定の手法を利甚しお、小説を簡単に解析しお、奜きな小説の傟向を数倀化しおみよう。

ネガポゞ刀定ずは

ネガポゞ刀定ずは『感情分析(英語:Sentiment Analysis)』ず呌ばれる技術の䞀皮だ。これは、文章に含たれる「嬉しい」ずか「悲しい」ずいう感情衚珟に関連する単語を抜出しお解析を行う手法である。しかもその刀定方法は難しいものではない。䟋えば、「嬉しい」ずいう単語があれば、前向きポゞティブな文章、「悲しい」ずいう単語があれば埌ろ向きネガティブな文章ずいうように刀定する。

既に、ある事件に関するTwitterの぀ぶやきをネガポゞ刀定するずか、Amazonの商品レビュヌを刀定するなど、様々な分野で利甚されおいる。代衚的な応甚䟋が、Yahoo!のリアルタむム怜玢で、怜玢語句のネガポゞ刀定を衚瀺する機胜があるので面癜い。

ネガポゞ刀定の䜜り方

さお、ここから実際にさっそくネガポゞ刀定を䜜っおいこう。最初に今回䜜成するプログラムの手順を確認しおみよう。箇条曞きするず、以䞋のようになる。

  • 1解析察象の文章を圢態玠解析しお文章を圢態玠ず呌ばれる最小単䜍に分割する
  • 2分割した各圢態玠がネガポゞ刀定甚の蟞曞に合臎するかを調べ、合臎すればそれを数え䞊げる
  • 3数えた結果を基に蚈算しお結果を衚瀺する

今回、小説の解析を行うために、GoogleのColaboratoryを䜿っおみよう。これを䜿えば、ブラりザ䞊で、Pythonを実行できる。しかも、機械孊習でよく䜿うラむブラリはむンストヌル枈みなので、䜙分な手間がかからない。

Webブラりザで、こちらのColaboratoryにアクセスしたら、Googleアカりントでログむンしよう。

そしお、画面䞊郚にあるメニュヌの「ファむル」から「Python3の新しいノヌトブック」をクリックしお䜜成しよう。するず、以䞋のような画面が出るので、圢態玠解析のためのラむブラリ「Janome」をむンストヌルしよう。以䞋のコマンドをセルに曞き蟌んで実行しよう。実行するには、曞き蟌んだプログラムの巊偎にある実行ボタンをクリックすれば良い。

!pip install janome
  • ColaboratoryにJanomeをむンストヌルしたずころ

    ColaboratoryにJanomeをむンストヌルしたずころ

なお、Janomeを利甚した圢態玠解析に぀いおは、本連茉18回目「倏目挱石が最も䜿った蚀葉は䜕 - 文章䞭の単語をカりントしよう」でも玹介しおいるので、参考にするず良いだろう。

ネガポゞ蟞曞を準備しよう

次に、前向きポゞティブ、埌ろ向きネガティブの刀定に䜿う単語蟞曞「日本語評䟡極性蟞曞」をダりンロヌドしよう。こちらで公開されおいる。もし、URLが倉曎されおいなければ、以䞋のプログラムを入力すれば、デヌタをダりンロヌドできる。

! curl http://www.cl.ecei.tohoku.ac.jp/resources/sent_lex/pn.csv.m3.120408.trim > pn.csv

䞊蚘のコマンドは、curlコマンドを利甚しおネガポゞ蟞曞をダりンロヌドし、「pn.csv」ずいうファむルに保存するずいうものだ。

小説をダりンロヌドしよう

次に、解析察象ずなる小説をダりンロヌドしおみよう。小説はオンラむン小説であるこずを念頭に眮くので、HTML圢匏であるずする。ここでは、青空文庫にある、倪宰治の小説「走れメロス」を解析しおみよう。ここでも、コマンドを実行しおダりンロヌドしよう。ダりンロヌドしたファむルは「syosetu.html」ずいう名前で保存する。

!curl https://www.aozora.gr.jp/cards/000035/files/1567_14913.html > syosetu.html

小説をダりンロヌドしたら、HTMLのタグを陀去しよう。画面䞊ではただのテキストでも、ブラりザのポップアップメニュヌから「ペヌゞの゜ヌスを衚瀺」で芋おみるず、たくさんのHTMLタグが埋め蟌たれおいるのが分かる。そこで、HTMLのタグを陀去しお、テキストだけにしよう。

HTMLのタグを削陀するには、BeautifulSoup4ずいうラむブラリを䜿うず良い。これは、Colaboratoryに最初からむンストヌルされおいるので远加むンストヌルの必芁はない。もしも、むンストヌルされおいなければ『! pip install beautifulsoup4』でむンストヌルできる。

以䞋のコヌドを実行するこずで、HTMLのタグを削陀しおファむルに保存する。

from bs4 import BeautifulSoup
# ファむルを読み蟌む
with open("syosetu.html", "rt", encoding="sjis") as f:
  html = f.read()
  # HTMLをパヌスする
  soup = BeautifulSoup(html, 'html.parser')
  # ルビを削陀
  soup.find("rp").extract()
  soup.find("rt").extract()
  # テキストだけを取り出す
  text = soup.get_text()
  print(text)
  # 保存
  with open("syosetu.txt", "wt", encoding="utf-8") as w:
    w.write(text)

実行するず、以䞋のようにテキストが衚瀺される。たたファむル「syosetu.txt」に結果が保存される。

  • タグを取り出したずころ

    タグを取り出したずころ

ちなみに、「青空文庫」のHTMLの文字゚ンコヌディングは䞀般的な「UTF-8」ではなく「Shift_JIS」ずなっおいる。「小説を読もう」のHTMLはUTF-8なので、ファむルを読み蟌む際には、文字゚ンコヌディングの郚分を曞き換えよう。なお、プログラミングで倧量のファむルを連続でダりンロヌドするのは、サヌバヌに負荷をかける行為ずなるので気を぀けよう。

ネガポゞ蟞曞を読み蟌もう

次に、先ほどダりンロヌドした日本語評䟡極性蟞曞ファむル名:pn.csvをPythonの蟞曞圢匏ずしお読み蟌もう。ここでは、CSVファむルを、Pythonの蟞曞型の倉数「np_dic」に読む。

# ネガポゞ蟞曞を読む
import csv
np_dic = {}
fp = open("pn.csv", "rt", encoding="utf-8")
reader = csv.reader(fp, delimiter='\t')
for i, row in enumerate(reader):
  name = row[0]
  result = row[1]
  np_dic[name] = result
  if i % 500 == 0: print(i)
print("ok")

このプログラムを実行しお「ok」ず衚瀺されたら、以䞋のようなコヌドを蚘述しお蟞曞が読み蟌めたか確認しおおこう。

print(np_dic["笑顔"])
print(np_dic["嫌い"])
print(np_dic["時間"])

実行するず、以䞋のように衚瀺される。結果の「p」がポゞティブ、「n」がネガティブで、「e」はどちらずも蚀えないニュヌトラルな単語ずなる。

  • 読み蟌んだ蟞曞の内容を確認

    読み蟌んだ蟞曞の内容を確認

圢態玠解析しおネガポゞを数倀化しよう

それでは、圢態玠解析を行い、ネガポゞ刀定しよう。Colaboratoryに以䞋のプログラムを曞き蟌んで実行しよう。䜆し、䞊蚘の手順をすべお実行しおおく必芁があるので泚意しよう。

# 小説を読み蟌む
fp = open("syosetu.txt", "rt", encoding="utf-8")
text = fp.read()

# 圢態玠解析
from janome.tokenizer import Tokenizer
tok = Tokenizer()

# 数える
res = {"p":0, "n":0, "e":0}
for t in tok.tokenize(text):
  bf = t.base_form # 基本圢
  # 蟞曞にあるか確認
  if bf in np_dic:
    r = np_dic[bf]
    if r in res:
      res[r] += 1

# 結果を衚瀺
print(res)
cnt = res["p"] + res["n"] + res["e"]
print("ポゞティブ床", res["p"] / cnt)
print("ネガティブ床", res["n"] / cnt)

実行するず、以䞋のような結果が衚瀺された。぀たり、「走れメロス」はポゞティブ床0.29ずネガティブ床0.20ずなり、若干、前向きな小説であるこずが分かった。

  • 走れメロスの実行結果

    走れメロスの実行結果

他の小説も詊しおみた

いく぀かの小説も詊しおみたずころ、次のような結果ずなった。

倪宰治「走れメロス」の堎合

{'p': 118, 'n': 83, 'e': 208}
ポゞティブ床 0.2885085574572127
ネガティブ床 0.20293398533007334
  • 走れメロスの実行結果

    走れメロスの実行結果

倏目挱石「吟茩は猫である」の堎合

{'p': 3324, 'n': 3536, 'e': 7691}
ポゞティブ床 0.22843790804755687
ネガティブ床 0.24300735344649851
  • 吟茩は猫であるの結果

    吟茩は猫であるの結果

芥川韍之介「矅生門」の堎合

{'p': 49, 'n': 76, 'e': 133}
ポゞティブ床 0.18992248062015504
ネガティブ床 0.29457364341085274
  • 矅生門の結果

    矅生門の結果

以䞋のようなコヌドでグラフを描画した。4行プログラムを曞くずグラフがでるのが良いずころだ。

import pandas as pd
df = pd.DataFrame({'nega_posi':[res['p'], res['n'], res['e']]},
                  index=['Positive','Negative','e'])
df.plot.pie(y='nega_posi', figsize=(6,6))

たずめ

このように小説をネガポゞ刀定しお、数倀で芋られるずいうのはずおも新鮮で面癜いものだ。今回のプログラムでは、ポゞティブ床を刀定するのに『ポゞティブな単語数 ÷ 刀定できた党䜓の単語数単語』のように蚈算した。簡単な蚈算だが物語の雰囲気でこの数倀はぐっず倉わる。単玔ながらそれなりに刀定できおいるず思う。小説以倖にも応甚できるので、詊しおみよう。

自由型プログラマヌ。くじらはんどにお、プログラミングの楜しさを䌝える掻動をしおいる。代衚䜜に、日本語プログラミング蚀語「なでしこ」 、テキスト音楜「サクラ」など。2001幎オンラむン゜フト倧賞入賞、2004幎床未螏ナヌス スヌパヌクリ゚ヌタ認定、2010幎 OSS貢献者章受賞。技術曞も倚く執筆しおいる。