
人工知能でTwitterのタイムラインとみんなの心を光で満たしたい
はじめまして!Aidemy研修生の紫垣と申します! 僕はよく、Twitterを眺めててネガティブなツイート(病みツイとか)を見かけて、気分がどんよりしてしまうことがあります・・・ じゃあそいつのアカウントミュートなりブロックなりしろよ!と言われるかもしれません。 だけど付き合い上そういうことができない方も多いですし、実際一つ一つミュートとかしてもキリないですよね?
そこで!!!!人工知能の力をお借りしたいと思います!!!!!
ツイートがポジティブなものかネガティブなものかを人工知能が判別して、ネガティブなツイートをタイムライン上に表示しないようなアプリを開発すれば、僕たちの心は光で満ち溢れるのではないかと思いました!! まずこの記事では、第一歩として、ツイートがポジティブかネガティブかを判別する機械学習モデルを開発します! というわけで、さっそく開発の流れを書いていきます!!
目次[非表示]
- 1.実行環境
- 2.データ集め
- 3.データの整形
- 4.機械学習
- 4.1.ランダムフォレスト
- 4.1.1.決定木分析とは?
- 4.1.2.ランダムフォレストとは?
- 4.2.BOW_tf-idfによる文字→数値表現
- 4.3.学習開始!
- 4.3.1.プログラム
- 4.4.実際に動かしてみた
- 5.考察
- 5.1.誤判定について
- 5.1.1.原因(予想)1. 単語の学習不足?
- 5.1.2.原因(予想)2. 決定木が不完全?
- 5.1.3.原因(予想)3. 単語同士の繋がり(文脈)が考慮されていない
- 6.今後の展望
実行環境
- OS : ubuntu 17.10
- CPU : Intel(R) Xeon(R) CPU @ 2.30GHz
- GPU : Tesla K80
- メモリ : 12GB
データ集め
方法
機械学習をおこなうためには、まず大量のデータが必要です!今回必要とするデータは- ポジティブなツイート
- ネガティブなツイート
プログラム
今回、pythonで記述していきます! こちらがデータ集め用のプログラムです!まず、janomeライブラリの中のTokenizer()というインスタンスを作成します。このインスタンスが形態素解析をおこなってくれます。 次に、Tokenizer()インスタンスのtokenize()関数を使って、集めたツイート一つ一つを、先ほどの文章みたいに細かく切り刻みます。
そしてfor文で1つ1つの単語の品詞を変数partOfSpeechに代入し、その品詞が学習で使えそうな品詞(名詞、動詞、形容詞、形容動詞のいずれか)なら、noun_flagというフラグを1(このフラグの値は元々0)にします。
最後に、1つ1つの単語に対してその単語のnoun_flagが1なら(上に挙げた品詞に該当する)残す、0なら(上に挙げた品詞に該当しない)その単語を削除、といった具合にツイートをゴリゴリ削っていきます!また、今後のために各単語を半角スぺース" "で区切っています。 そうして整形されたツイートを返り値として返す関数になっています! 例えば、「明日は晴れるでしょう。」というツイートがもしあった場合、こうなります。 「明日 晴れる」 これで機械に学習させる準備は整いました!早速学習させていきましょう!
機械学習
ランダムフォレスト
決定木分析とは?
下の図のような決定木と呼ばれるものをデータの学習によって作成し、条件分岐によってグループ(ツイートの集まり)を分割し、グループ内の各要素(ツイート)を分類する(ポジティブか?ネガティブか?)手法です。
上の決定木だと、「ゲーム楽しい!最高!」というツイートはPositive!に分類されます。 また、「ゲーム楽しいけど、負けるとイライラする...」というツイートはNegative...に分類されます。 この決定木は元の学習データ(ツイート)と、教師データ(そのツイートがポジティブなものかネガティブなものかの答え)によって作成されます。
膨大な量の学習データ、教師データから決定木を作成し、人間がポジティブかネガティブかを教えずにツイートを与え、先ほどの学習によって作られた決定木によってポジティブかネガティブかを判定させる、これを決定木分析といいます。
ランダムフォレストとは?
上記の決定木分析で作られる決定木は一本のみです。しかし、ランダムフォレストでは、この決定木を複数作成します。 そうして得られた複数の決定木から一番判定の精度が良いものを選抜し、ポジティブかネガティブかがわからないツイートの判定に用いる。この学習方法をランダムフォレストといいます。
BOW_tf-idfによる文字→数値表現
学習開始!
それではランダムフォレストを使って学習を開始していきます!プログラム
実際に動かしてみた
それでは、完成したプログラムを動かしてみたいと思います! こちらです!!
トレーニングデータ、テストデータに対する出力はなかなかなものではないでしょうか! 試験用ツイートの判定もまあまあといったところですね。
考察
誤判定について
今回、試験用ツイートに2つ誤判定がありました。 「君が友達で俺は幸せだ!」 「君のおかげでいろいろ助かった!ありがとう!」 この2つはpositiveとして判定してほしかったのですが、negativeとして判定されてしまいました。
誤ツイート1は、"幸せ"という如何にもポジティブそうな単語があるにも関わらず、negative判定されています。
誤ツイート2は、"ありがとう"とかのフレーズはポジティブっぽいのにnegaitve判定されています。 これらの誤判定の原因を3つ考えました。
原因(予想)1. 単語の学習不足?
今回収集したポジティブツイートの数は15551ツイートですが、その中に"幸せ" "ありがとう" これらの単語が含まれたツイートが少ないため、学習モデルがこれらの単語をポジティブな単語として認識してくれなかったのではないかと考えました。
また、"君"という言葉をネガティブな単語として判定しているのでは?とも感じました。しかし、 「君のことを考えるだけで目の前が光で包まれるよ!最高だ!」というツイートはpositive判定されています。これは、"光" "最高" など、ポジティブ要素が非常に強い単語でネガティブ要素を相殺しているため、positive判定されたのではないか、と考えました。
原因(予想)2. 決定木が不完全?
"幸せ"という単語が、決定木のより先端に近い方に配置されていて、"幸せ"という単語があるかないかの判定をされる前に他の関係のない単語でnegative判定されてしまっているのではないかと考えました。原因(予想)3. 単語同士の繋がり(文脈)が考慮されていない
今回の学習方法は、単語1つ1つを学習に用いています。 「君のおかげでいろいろ助かった!ありがとう!」 こちらのツイートは、一見ポジティブ感がありますが、このツイートを上のプログラムで整形してみると、 「君 おかげ 助かっ ありがとう」 となり、"ありがとう"以外の単語は、ポジティブともなんともいえない単語です。 そのため、学習不足などにより"ありがとう"がpositive判定されないと、他の単語の影響により、一気にnegative判定の方へといってしまいそうです。今後の展望
以上の考察から、今後の展望として、 ・学習ツイート数を増やす(twitter apiの制限をなんとかしないといけない) ・決定木の再構築(random_stateの値を見直す) ・どうにかして単語同士のつながりも特徴量に含まれるようなアルゴリズムを考える(Word2VecとBOWの併用とか?) このあたりをなんとかしていけたらいいなと思います! 最後まで読んでいただき、ありがとうございました!
PythonやAIプログラミングを学ぶなら、オンライン制スクールのアイデミープレミアムプラン。
「機械学習・ディープラーニングに興味がある」
「AIをどのように活用するのだろう?」
「文系の私でもプログラミング学習を続けられるだろうか?」
少しでも気になることがございましたら、ぜひお気軽にAidemy Premium Planの無料相談会にお越しいただき、お悩みをお聞かせください!
このほかにも、Aidemy MagazineとTwitter(@AidemyMagazine)ではたくさんのAI活用事例をご紹介しています。どちらも要チェック!