Twitterにおける感情分析

スポンサーリンク
StartLab 挫折しないプログラミング学習
スポンサーリンク
StartLab 挫折しないプログラミング学習

この記事では、Twitterのツイートを用いて感情分析を行っていきます。初めに、感情分析について紹介し、使用するデータセットの概要、データ処理とモデルの実装、過学習対策とモデルの評価、考察の順に紹介していきます。最後に今後の課題を述べたいと思います。

感情分析について

感情分析は人の顔や音声、テキストからポジティブ、ネガティブなどといった様々な感情を推測することができます。また、感情分析は主にルールベースの手法と機械学習を用いた手法があります。今回は、後者の方法でテキストから感情を推測するモデルを実装していきます。実装にはTensorFlowを使用していきます。

データセットの概要

今回は、Kaggleで提供されているTwitterのデータセットを使用していきます。データセットの概要は以下の通りです。

データセットの概要
  • データ数:160万
  • ラベルの種類:2(ポジティブ、ネガティブ)
  • カテゴリー数:6(ツイートのID、ツイートした日付、クエリ、ツイートしたユーザー名、ツイート)

データ処理とモデルの実装

処理の流れは以下の通りです。

処理の流れ
  • データの確認を行う。
  • 使用するデータを抽出する。
  • 学習、検証、テストデータに分割する。
  • テキストを数値に変換し、テキストの長さを統一する。
  • ラベルをNumpy配列に変換する。
  • モデルの構築と学習を行う。
  • モデルの学習プロセスをplotする。

データ処理

まずは、使用するライブラリをimportします。

データの確認をしていきます。

データセットの内容

各カテゴリは左からラベル、ツイートのID、ツイートした日付、クエリ、ツイートしたユーザー名、ツイートです。

次に、データセットのラベルの列とツイートの列を抽出し、データの概要を確認します。以降では、ツイートをテキストと表記します。

データの概要

データ数は160万、ラベルはint型で、テキストはstr型であることが確認できます。また、欠損値がないこともわかります。

次は、ラベルとテキストをそれぞれ抽出し、listに格納していきます。また、ラベル0がネガティブ、ラベル1がポジティブになるようラベルを修正します。

次は学習、検証、テストデータに分割していきます。それぞれのデータ数の確認も行います。

学習、検証、テストデータの数

学習を行うには、入力となるテキストを数値に変換する必要があります。また、テキストの長さを統一する必要もあります。ここではテキスト中の単語にIDを振り分け、テキストの長さを統一する処理を行っています。

Tokenizerインスタンスを使用することでテキスト中の単語にIDを振り分けることができます。tokenizer.fit_on_texts()にテキストを渡し、テキストを単語に分割して出現頻度の多い単語から順にIDを振り分けます。tokenizer.word_indexによって単語と単語IDがマッピングされた単語ID辞書を参照することができます。次に、tokenizer.texts_to_sequences()によって単語ID辞書をもとにテキスト中の単語をIDに変換します。最後は、pad_sequences()によって、テキストの長さを統一します。また、pad_sequences()によってlistをNumpy配列に変換してくれます。

学習データをもとに作成した単語ID辞書を用いて検証、テストデータの前処理を行っていきます。また、学習データと同じテキストの長さに統一する必要があります。

次は学習、検証、テストデータのラベルをlistからNumpy配列に変換します。

モデルの実装

次はモデルを構築して、学習を行っていきます。今回はEmbeddingレイヤDenseレイヤのみで構成されたシンプルなモデルを実装します。ここで実装するモデルをベースモデルとします。

学習結果をplotします。

学習プロセス

上の図が学習、検証データのAccuracyになります。下の図は両データのLossになります。横軸はともに学習回数を表しています。Accuracyを確認すると学習データは92%を超えていますが、検証データは約78%であることからモデルは過学習していることが分かります。また、Lossについては学習回数に伴い検証データのLossが大きく上昇しています。

次はテストデータを用いてモデルの評価を行います。

テストデータのAccuracyは78.1%、Lossは56.8%であることが確認できました。次は、モデルの過学習の改善とモデルの評価を行っていきます。

過学習対策とモデルの評価

過学習対策

上記で実装したベースモデルは、過学習をしていました。そこで、各レイヤのニューロン数を削減し、Dropoutレイヤを追加することで過学習を改善したいと思います。

ベースモデルと比較します。

ベースモデルとの比較

前回の図に紫色、シアン色のplotを追加しています。紫色、シアン色のplotはそれぞれ過学習対策を行ったモデルの学習、検証データを表しています。それぞれのモデルを比較した結果、過学習対策を行ったモデルの検証データの方がAccuracyが高く汎用的であることが分かります。また、Lossは減少しています。このグラフからベースモデルより過学習が改善されていることが確認できます。

テストデータのAccuracyとLossについてもベースモデルより改善されていました。

モデルの評価

次は、モデルが正解ラベルを予測できた、またはできなかったテキストの数を確認したいと思います。

混同行列
割合表示

混同行列から正解ラベルに大きな偏りがないことが確認できます(ネガティブ:79728件、ポジティブ:80272件)。また、モデルが誤ってネガティブと予測したテキストは約10%、誤ってポジティブと予測したテキストは約9%であることからこれらについても大きな偏りがありません(以降では前者をFalse Negative Texts、後者をFalse Positive Textsと表記します)。これらのことからモデルはネガティブ、ポジティブ予測において同じくらい予測を間違えていることが分かります。

考察

ネガティブ、ポジティブ予測の間違いの傾向を探るためにFalse Positive TextsとFalse Negative Textsをサンプリングしていきます。

サンプリング

まずは、False Negative Textsをサンプリングします。

False Negative Texts(正解ラベルはポジティブ)

次に、False Positive Textsをサンプリングします。

False Positive Texts(正解ラベルはネガティブ)

サンプリング結果を見ると記号(@、!、#)やURL、数字が多く含まれていることが分かります。これらのテキストの特徴を深掘りするために単語の出現頻度を求めて可視化します。まずは前処理を行います。

次は、単語の出現頻度を可視化します。

頻出単語の比較

このグラフは、単語の出現頻度Top20を表しています。横軸が単語の出現頻度、縦軸が出現単語です。False Negative Texts、False Positive Textsともに記号が上位を占めていることや’m、quotという単語が頻出していることが確認できます。また、False Positive TextsにはURL(http)がTop20に含まれています。記号やURL、’m、quotがモデルの予測に何らかの影響を与えているのではないでしょうか。このことを調査するために記号、URL、’m、quotの有無で感情スコアを算出していきます。また、サンプリング時に数字も多く含まれている印象だったので数字の有無についても確認していきます。

感情スコア算出

モデルの予測結果から感情スコアを算出する関数を実装します。

実装した関数にテキストと学習したモデルを渡して記号、URL、’m、quot、数字の有無による感情スコアの変化を順に確認していきます。最後には、モデルが文脈を考慮した上でネガティブ、ポジティブを予測しているのかについても検証していきます。

記号の有無

False Positive TextsとFalse Negative Textsから3つずつ@(記号)を含んだテキストをサンプリングし、それぞれ@の有無で感情スコアを算出しました。上記は、算出したテキストの一例です。感情スコアは0に近づくほどネガティブ要素が強く、1に近づくほどポジティブ要素が強くなることを表しています。1行目は@ありのテキスト、2行目は@を削除したテキストです。また、返信用ツイート(リプライ)にはテキストの先頭に@と返信先ユーザー名が表示されるため@とユーザー名をセットで記号として扱い削除したものが3行目のテキストになります。ここでは、@の有無と@とユーザー名の有無についての検証結果と考察を述べます。

– @の有無
@の有無(2行目のテキスト)については、感情スコアに変化がありません。また、他の@(リプライ)を含んだテキストにおいて@の有無を確認したところ0%~1%の間でしか感情スコアが変化していませんでした。

– @とユーザー名の有無
@とユーザー名の有無(3行目のテキスト)については、感情スコアが70%も変化しています。他の@(リプライ)を含んだテキストにおいて@とユーザー名をセットで記号として扱い、これらの有無を確認したところ2%~4%の間でしか感情スコアが変化していませんでした。また、これらのテキストの特徴としてユーザー名がテキスト全体を占める割合は3割程度で、ここで紹介しているものより少ないことが分かりました。

これらのことから、@についてはモデルの予測にあまり影響を与えていないことが考えられます。しかし、@とユーザー名をセットで記号として扱った場合については、テキスト全体に対するユーザー名の長さによってモデルの予測への影響が変わってくるのではないでしょうか。

URLの有無

①のテキスト
②のテキスト

記号の有無と同様に、False Positive TextsとFalse Negative Textsから3つずつURLを含んだテキストをサンプリングし、それぞれURLの有無で感情スコアを算出しました。上記では、2つのテキストの結果を示しています。両者ともに1行目はURLありのテキスト、2行目はURLを削除したテキストです。①のテキストは、感情スコアが1%しか変化していません。②のテキストについては17%感情スコアが変化しています。また、他のURLを含んだテキストについても0%~3%の間でしか感情スコアが変化していないことが分かりました。感情スコアは0~100%の値を取ります。それを考慮すると1%や17%は低い水準なので、テキストによって感情スコアが変化するものの大きな差はなくモデルの予測にあまり影響を与えていないことが考えられます。

‘mの有無

1行目はもとのテキスト、2行目は’mを削除したテキストになります。’mの有無では5%しか感情スコアが変化していません。また、’mについて調べたところ’mはI’mを分割したものということが分かりました。正確には、単語の前処理(トークン化)のところでI’mがIと’mに分割されていました。’mの有無によって感情スコアがあまり変化しないことから、NP、PNにおける単語頻度Top20に’mが出現するのは、’mが全体のデータにおいても出現頻度が高いからではないかと考え、次に’mの頻度を調査しました。

– ‘mの出現頻度の偏り
上記混同行列のNN、NP、PN、PPそれぞれのテキストにおいて’mを含んだものの割合を求めた結果、順に8%、7%、8%、6%で大きな偏りがありませんでした。しかし、これらの割合だけからは’mが頻出単語であるとは言えないため最も頻出する単語の出現率と比較しました。

– ‘mが頻出単語といえるのか
最も頻出する単語の出現率については、順に55%、60%、50%、46%でした。この結果から’mは頻出単語とは言いにくそうです。

これらのことから’mは、NN、NP、PN、PPに関係なく出現し、モデルの予測に影響を与える単語ではないと考えられます。

quotの有無

1行目はもとのテキスト、2行目はquotを削除したテキストになります。quotの有無では2%しか感情スコアが変化していません。quotについて調べたところ”(クォーテーション)を表す"というHTMLの特殊文字であることが分かりました。また、’mと同様に、混同行列のNN、NP、PN、PPそれぞれのテキストにおいてquotを含んだものの割合を求めました。結果は順に、1%、3%、2%、3%で大きな偏りがありませんでした。これらのことから、quotについても出現率にほとんど差がないことからモデルの予測にあまり影響を与えていないことが考えられます。

数字の有無

①のテキスト
②のテキスト

False Positive TextsとFalse Negative Textsから3つずつ数字を含んだテキストをサンプリングし、それぞれ数字の有無で感情スコアを算出しました。上記では、2つのテキストの結果を示しています。両者ともに1行目は数字ありのテキスト、2行目は数字を削除したテキストです。①のテキストは、数字の有無によって感情スコアが1%しか変化していません。②のテキストについては感情スコアが10%変化しています。また、他の数字を含んだテキストについては0%~17%の間で感情スコアが変化していました。感情スコアは0~100%の値を取ります。それを考慮すると1%や10%、または17%は低い水準なので、テキストによって感情スコアが変化するものの大きな差はなくモデルの予測にあまり影響を与えていないことが考えられます。

文脈を考慮した予測かどうか

モデルが文脈を考慮して予測しているのかを検証するためにFalse Negative Textsの中からネガティブ要素を持つ英単語badを含むものをサンプリングしました。ここでは、強い願望を表すso badという表現の中でbadが用いられているテキストを使用します。1行目はもとのテキスト、2行目はもとのテキストからbadを削除したテキストです。翻訳すると、「今夜のデートが待ち遠しい…今週末も。デートがしたくて仕方ない」という意味になるのでテキストにはネガティブ要素が含まれていません。しかし、1行目の結果からモデルはネガティブと予測しています。また、badを削除しただけで74%も感情スコアが上昇し、モデルはポジティブと予測していることが確認できます。これらの結果からモデルはネガティブ要素を持つbadに引っ張られてテキストの感情を正確に予測できていないことが考えられます。つまり、文脈を考慮した予測ができていないということです。

おわりに

以上がTwitterにおける感情分析でした。TensorFlowを用いてテキストから感情を推測するモデルを構築することができました。今後の課題は以下のとおりです。

今後の課題
  • 前処理の見直しを行う。(文字化けした文字の除去、@とユーザー名をセットで除去など)
  • 文脈を考慮した学習を行う。(RNN、LSTMレイヤの追加など)
  • 過学習対策の見直しを行う。(ニューロン数の削減、Dropoutレイヤを追加する位置など)
Acknowledgements

Go, A., Bhayani, R. and Huang, L., 2009. Twitter sentiment classification using distant supervision. CS224N Project Report, Stanford, 1(2009), p.12.

K.Y

タイトルとURLをコピーしました