はじめに
日本語のテキストマイニングを、Facebook FastTextで実際にやってみるシリーズ第2弾。
第1弾では、教師データや評価対象データの準備まで行った。
今回はその続きを最後まで行い、Twitterのつぶやきの感情分析を行って、そのつぶやきが
ポジティブ
なのか ネガティブ
なのか、それを判定してみようと思う。
前提
第1弾と同じ内容を再掲する。
- 環境構築
- Mecabやfasttextなどの導入手順
- 日本語の前処理
- 形態素解析
- テキストマイニングの精度向上させるコツ
- それを実現するためのライブラリとその使い方
- 本記事で使用するコードは、全てここから取得可能
手順
以下のような順で実施する。
- twitterからデータを入手する
- 入手したデータの前処理
- 教師データの学習と学習モデル作成
- 評価対象データの分類
- 結果の可視化
- 結果の解釈
今回は 教師データの学習と学習モデル作成 からを述べる。
3. 教師データの学習と学習モデル作成
第1弾は2章までだったので、3章から再開する。
以下が、fasttextで分類を学習させるためのスクリプトlearning.py。
# -*- coding: utf-8 -*-
import fasttext as ft
import argparse
# 実行引数の受け取り
parser = argparse.ArgumentParser(description="教師データを学習し、学習モデルを作る")
parser.add_argument('input', type=str, help="入力ファイルへのPath(必須)")
parser.add_argument('output',type=str, help="出力ファイルへのPath(必須)")
args = parser.parse_args()
# 学習
classifier = ft.supervised(args.input, args.output, dim=400, lr=0.10, epoch=200, thread=6)
# Properties
result = classifier.test(args.input, 2)
print("result.precision", result.precision) # Precision at one
print("result.recall", result.recall) # Recall at one
print("result.nexamples", result.nexamples) # Number of test examples
以下のように、コマンドラインから、learning.pyを実行する。
すると、negaposi.bin という学習モデルが作成される。
python learning.py traindata.tsv negaposi
result.precision 0.5
result.recall 1.0
result.nexamples 4608
教師データを作るとき、そのモデルに対しての適合率や再現率も、計算している。
観点 | 内容 |
---|---|
Precision | 適合率のこと。予測を正と判断した中で、答えも正のもの。 |
Recall | 再現率のこと。答えが正の中で、予測が正とされたもの。 |
Recallが1.0ということは、ポジティブとラベルしたデータはすべてポジティブに、
ネガティブとラベルしたデータはすべてネガティブに、分類しているようだ。
1.0だと、ちょっと過学習しているような気もするのだけど、とりあえずこのまま進める。
4. 評価対象データの分類
2.2節で、評価対象データの前処理は、すでに完了させてある。
その前処理の結果として、 w_[アカウント名].pkl のようなファイルが作成されているはずだ。
このファイルを読み込み、評価結果を出力させていく。
改めて、w_nikkei.pkl の中身がどんな内容となっているのか、確認しよう。
ただ、このpklファイル形式は、pythonのバイナリ保存形式である。
同じ中身が、plain textで拡張子tsvで出力されているので、これを確認する。
2017-08-04 16:31:02 nikkei キヤノン電子 4 社 小型衛星 打ち上げる 参入
2017-08-04 15:13:02 nikkei ポスト安倍 石破 氏 首位 岸田氏 4位
2017-08-04 14:12:45 nikkei 規模 領域 幅広い さ 違う 私たち 多く 共通点 ある マツダ 社長 トヨタ 資本 業務提携 発表 する た 記者会見 一問一答 です
2017-08-04 14:07:02 nikkei NY 株 上昇 始まる 米 雇用統計 受ける 金融株 買う
2017-08-04 13:37:02 nikkei 内閣支持率 42% 3 ポイント 上昇 本社 世論調査
2017-08-04 13:15:49 nikkei SingPost chief IS Confide NT of putting company back ON track after months without top management
2017-08-04 13:04:02 nikkei 台風5号 列島 接近 6日 夜 九州 上陸
このようなデータを元にして、1行ごとに出力されているtweetデータの内容がポジティブなのかネガポジなのかを判定していく。
ここでは、positiveなら+1
、negativeなら-1
となるようにする。
具体的には、positiveとnegativeに分類される確率を取得し、negativeの場合は、その確率の値の負を取る。
そのための処理を行うpython script、judgePositive.pyを作ったので、
この引数に、対象ファイル名と教師データを与えて、結果を得る。
以下のshell scriptで、一気に変換できる。
echo evaluating tweet data
for item in ${T_ARRAY[@]} ${A_ARRAY[@]} ${NIKKEI[@]}; do
echo "converting data: "$item
python judgePositive.py w_${item}.pkl negaposi.bin
done
この処理の結果、result_w_[アカウント名].tsv、result_w_[アカウント名].pkl といった、
tsvファイルとpklファイルの2種類が出力される。
それでは、result_w_nikkei.tsv の中身を確認してみよう。
date label posibility tweet
2017-08-05 01:31:02+09:00 n -0.998047 キヤノン電子 4 社 小型衛星 打ち上げる 参入
2017-08-05 00:13:02+09:00 n -0.984375 ポスト安倍 石破 氏 首位 岸田氏 4位
2017-08-04 23:12:45+09:00 p 0.996094 規模 領域 幅広い さ 違う 私たち 多く 共通点 ある マツダ 社長 トヨタ 資本 業務提携 発表 する た 記者会見 一問一答 です
2017-08-04 23:07:02+09:00 n -0.998047 NY 株 上昇 始まる 米 雇用統計 受ける 金融株 買う
2017-08-04 22:37:02+09:00 p 0.998047 内閣支持率 42% 3 ポイント 上昇 本社 世論調査
2017-08-04 22:15:49+09:00 p 0.962891 SingPost chief IS Confide NT of putting company back ON track after months without top management
2017-08-04 22:04:02+09:00 p 0.992187 台風5号 列島 接近 6日 夜 九州 上陸
2017-08-04 21:46:02+09:00 n -0.976563 米 雇用 20 9万人 増 7月 市場 予測 上回る
2017-08-04 21:25:02+09:00 p 0.998047 公的年金 運用益 5 1兆円 46 月 株高 追い風
2017-08-04 20:52:02+09:00 n -0.65625 トヨタ 社長 EV 米 Google Inc. 競う マツダ 会見
2017-08-04 20:45:47+09:00 p 0.832031 高電圧 三菱重工 事務 系 採用 ゼロ 民間 ロケット打ち上げ 失敗 日経 記事 Twitter 読む れる た 10本
これだけみると、あまりポジティブとネガティブを判定できていないと、直感的に思える。。。。
教師データも少ないし、いくら前処理を頑張っても、限界があったのかもしれない。
そもそも、ポジティブ名言の内容で、
諦めたら、そこで試合終了だよ
というものもあった。ここから、以下のような内容を判定するのは、そもそも無理があるのだろう。
NY株、上昇で始まる 米雇用統計受け金融株に買い
これは、株が上がるってことで、誰しもが 「ポジティブ」 ととらえる文章だとう。
しかし、これがネガティブ判定されてしまっている。
これが、なぜそうなのか説明できないところが機械学習というか、なんというか。
5. 結果の可視化
5.1 結果の可視化方法
結果の可視化を行う。
twitterデータは、時系列情報のデータ。
そのため、文章から感情の時間変化を描画する
ことが可能なはず。
また、この結果を複数のアカウントのつぶやきと比較することによって、
相対的にそのアカウントのつぶやきが、ポジティブなのかネガティブなのかを比較することができる。
visualizeResult.pyという、可視化のためのscriptも用意した。
# 個人的フォロワーなどのアカウント
varray=()
for item in ${T_ARRAY[@]}; do
varray+=(result_w_$item.pkl)
done
python visualizeResult.py ${varray[@]}
# アニメのセリフなどのbot
varray=()
for item in ${A_ARRAY[@]}; do
varray+=(result_w_$item.pkl)
done
python visualizeResult.py ${varray[@]}
# 日経関連のアカウント
varray=()
for item in ${NIKKEI[@]}; do
varray+=(result_w_$item.pkl)
done
python visualizeResult.py ${varray[@]}
このスクリプト中で、ポジティブとネガティブの半手度合いの数値は、週次/月次で集計
したものを描画した。
そのまま描画すると、個々のつぶやきはポジティブだったりネガティブだったりして、
大きくバタつき、非常に見づらいグラフとなってしまうからだ。
5.2 個人的に知っている人達のアカウント
早速可視化した結果を見てみよう。
まず最初は、どこの誰かは明言しないが、個人的に知っている人達のアカウント。
アカウント名karen529mm
の発言は、2017年5月ごとにテンションが上がっている。
何があったのかわからないが、きっとアゲアゲだったのだろう。
あと、いくつかのアカウントが、今年の4月以降なんだかざわついている。
いろいろと、心境の変化画ったりしたのだろうか。
5.3 アニメのセリフなどのbot
matsuoka_shuzo
は、もちろん松岡修造氏のアカウントです。
この安定したポジティブ感wwwwww
ただ、このアカウントは公式だと思うのですが、動きを見ているとどうやらbotのようだ。
残り2つのアカウントは、エヴァのシンジ君(shinji0606_bot
)と葛城ミサト(ayano0515
)の
セリフbotなのだが、意外にネガティブじゃないのな。
botだと似たようなセリフをひたすら繰り返すため、内容が均質化されてしまい、
こういう可視化すると 面白くない 。
5.4 日経関連のアカウント
アカウントごとに発言量が違うので、それもあって期間の長さが違うが、
同じような記事の見出しのはずなのに、意外にバラける。
6.結果の考察
6.1 教師データの分類
教師データの評価で、Recallが1.0だったことに触れた。
これについても、あえて評価対象データとして可視化してみる。
* ポジティブ名言bot
- ネがティブ名言bot
確かに、教師データとして、すべて意図通りに分類されているようだ。
6.2 その他
5.4節で 日経関連のアカウントを可視化した。
この時、nikkeiWOL
とnikkeistyle
、nikkeivdata
、の3つのアカウントが、
かなりポジティブ寄りの記事らしいことが分かった。
実際に、そのつぶやきの内容を見てみよう。
6.2 nikkeiWOL:日経ウーマンオンラインのアカウント
早速その中身。
date label posibility tweet
2017-08-04 22:00:30+09:00 p 0.978516 宝くじ 人生 狂わせる 恐れ ある 合う ない 運試し
2017-08-04 21:00:27+09:00 p 0.998047 自分 何 提供 する ない 他人 モノ 情報 搾取 する まくる 通称 くれる くれる ちゃん 一言 言う たい
2017-08-04 20:00:32+09:00 p 0.998047 多汗症 女性 平均 ワキ 汗 量 汗じみる 危険 行動
2017-08-04 19:00:22+09:00 p 0.998047 皮脂 テカ 毛穴落ち ファンデーション キレイ 直す コツ ある た
2017-08-04 18:15:41+09:00 p 0.994141 グッド!モーニング アワード 2017 結果発表 総合 大賞 ドリンク
2017-08-04 18:00:24+09:00 n -0.986328 私 汗 臭う 腋臭 体質 分かる チェックリスト
2017-08-04 16:47:31+09:00 p 1.0 暴言 不倫 辞任 騒動 女難 終止符 打つ たい 安倍首相 本気 度 ー 野田聖子 現代 女子 感覚 私たち 閉塞感 救う
2017-08-04 12:05:03+09:00 p 0.978516 相手 心を掴む メール 達人 なる
2017-08-04 12:05:03+09:00 p 0.982422 専業主婦 バリキャリ 堂々 頑張る いる 言う たい
2017-08-04 12:00:13+09:00 n -0.998047 バリキャリ やめる ます 幹部 候補 中堅 社員 胸の内
2017-08-04 08:09:08+09:00 p 0.998047 夏 持つ たい おすすめ ポーチ 収納 アイテム
2017-08-04 07:53:09+09:00 p 0.724609 寝る 5分 胸 まわり 凝り ほぐす 完全 呼吸法
2017-08-04 07:36:09+09:00 p 0.998047 東京駅 エキナカ 押さえる おく べし 帰省 土産 12 選
2017-08-04 07:20:07+09:00 n -0.998047 宝くじ 3億円 当選 強 運 つかむ だ 派遣社員 その後
2017-08-04 07:03:09+09:00 n -0.996094 Chaldee vs Costco 麺 ピザ 菓子 人気 商品 勝負
2017-08-03 23:30:30+09:00 p 0.669922 幸せ アピール 子ども 写真 SNS 投稿 する ワケ
うーん、ネガィテブと判定されている文章は、確かにそんな気がする。
が、ポジティブと判定されているものの中で、なんか違うなと思うものもあるが、
それは個人で考えや感性も違うだろうから・・・・・(逃
個人的には、以下のつぶやきがネガティブと判定されていることにちょっと笑えた。
2017-08-04 07:20:07+09:00 n -0.998047 宝くじ 3億円 当選 強 運 つかむ だ 派遣社員 その後
記事の中身を読んでみると、その後に身を持ち崩した話とか出ていて、確かにネガティブ寄りの記事かな、感じた。
7.まとめ
2回に分けて、ソースコード付きで、機械学習によるTwitter投稿内容のネガポジ感情判定を行う手順を紹介した。
今どき、ライブラリもかなり増えてきたし、マシンパワーもかなりのものなので、気軽に機械学習できるようになった。
こういう時代になってくると、プログラミングはそこそこ出来れば十分。
それよりも、むしろその処理内容の数学的内容を理解して、結果の差異を考察できる能力のほうがよほど重要
ですね。
もうこれは、理系だとか文系だとかは関係なく、
- 統計的な数量をどう解釈すべきか
- どういう時に、どういう手法を使うべきか
こうしたことに、一定の根拠を持ってアプローチできる人は、需要が高いでしょう。
今どき、AIによって人間の仕事がなくなるとかいうバズワードが流布しています。
そんなことは絶対なくて、単に上記のようなことができない人が、今までのように給料をもらえなくなるだけの話でしょう。
人間、一生勉強ですね。
それでは。