glmの練習:いいね数予測


数ヶ月前のことですが、Facebookの投稿に対する「いいね数」を予測できないか、という相談がありました。
データマイニングの手法だけでなく、統計的な手法も勉強しようと思っていたので、一般化線型モデルを使ってみて解くことを考えました。それについて書こうと思います。参考にしたのはデータ解析のための統計モデリング入門――一般化線形モデル・階層ベイズモデル・MCMC (確率と情報の科学)
という書籍で、Rのglm関数を主に使用しました。コマンドやデータを示すと分かりやすくなるでしょうが、分析対象の性質上公開は控えておこうと思います。手法としても特に新しいことはありませんので、統計モデルを作っていく思考過程を示すことが本エントリの趣旨となります。

データを確認

データの取得は同僚がやってくれていたので、以下のような項目を持つCSVファイルからスタートしました。(項目名がいい加減ですが、雰囲気だけ掴んでもらえればと思います)

  • 投稿日時
  • 投稿者(投稿に対する訪問者のコメントも拾われていたので)
  • 投稿内容
  • システムメッセージ
  • 画像URL
  • いいね数
  • コメント数

分析対象はもちろん本人の投稿に対する「いいね」なので投稿者でフィルタしておきます。

いいね数の度数分布を確認したところ、ポワソン分布っぽいカーブであることが見て取れました。いいね数は非負の整数で、最大値に制限は無いと仮定できそうですから、ポワソン分布で良いだろうと考えました。
ただ、ポワソン分布は平均=分散という特徴をもつのですが、得られたデータにそのような特徴はなかったので、もっと別の分布にした方が良いかもしれません。glm関数では分布を変えることも容易なので、そのまま進めることにします。

変数を選択

いいね数を予測するとは、いいね数(従属変数)とその投稿内容の特徴(説明変数)の関係性を数式化することですから、他の項目を数値に置き換える必要がありました。ひとまず、簡単に数値化できるものだけを説明変数にしてみます。

最初の投稿からの経過日数
人によると思いますが、今回の分析対象は2年ほどの間に少しずついいね数が増えていくように見えました。これは対象をフォローする人が増加傾向にあることを示していると考えられます。本来はフォロワーの数そのものが知りたいところですが、計測できないのでそのまま経過日数を使うことにします。
投稿内容の長さ
長文か短文かは投稿の読まれやすさに影響を与えるかも知れません。とはいえ大分根拠は薄いですが簡単に数値化できるので変数に追加します。
システムメッセージの長さ
画像をアップロードした、のようなシステム的な投稿がデータには含まれていました。このような投稿はいいねされにくいので、このような投稿の長さが0かどうかは重要だと思われます。今思えばこのような投稿そのものをデータから取り除いた方が良かったかも知れません。
投稿にURLを含むかどうか
ブログを更新しました、のような投稿は投稿先まで読まないと意味が無いので、いいねされにくいでしょう。簡単なパターンマッチ(http)で、投稿にURLが含まれるかどうかを識別するダミー変数(URLを含めば1。含まなければ0)を作りました。
画像付きかどうか
画像付きの投稿の方がいいねされやすいのはデータを一目見れば分かります。画像のURLが空でなければ1、空なら0というダミー変数を用意します。

その他、コメント数は数値ですが、いいね同様、投稿からしばらく経ってからしか確認出来ないので予測には使えません。また投稿日時から時間帯毎のダミー変数を作ることも考えられますが、単純に一日24時間を分割するとサンプル数が少なくなりますし、特定の時間帯にいいね数が多いという傾向は見えなかったので保留しました。

このモデルにある程度予測力があることは一応確認しましたが、あまりに表面的・簡単すぎるのでもう少し変数を増やして面白くしたいところです。

変数の追加

先に抽出した変数はあまりに表面的だったので、投稿内容から変数を抽出することを考えます。自然言語処理でトピックを付与すると研究っぽくなりますが、いいね数の予測は全自動的に行うのではなく、人間が入力を行っても良いという条件だったため、投稿内容を目で見てトピックを付与するようなやり方で十分と考えました。あらためて投稿内容といいね数を眺めていると以下の「いいね」を集めるパターンが見えてきました。

  • 投稿者にとってうれしい出来事に対する、祝福する「いいね」
  • 人々への感謝を表明したことに対する、賞賛の「いいね」
  • 腹立たしい出来事への投稿者の怒りに対する、共感の「いいね」
  • 食事の話題には、何故か気軽に反応できる。文字通り「いいね」
  • ジョークや投稿者が可笑しいと思う写真には、笑いの「いいね」

また、広く知られた話題やニュースにまつわる投稿は「いいね」を大きく増す効果、逆に仕事の話題には、よっぽどの関係者じゃないと反応しづらいという傾向もあるように見えました。ただし前者は投稿内容のニュース性を予測するのは人間にとっても難しいため、この効果を変数に入れることはあきらめました。

これらを踏まえて、投稿者の感情{喜び、感謝、怒り}および投稿内容の話題{お祝い事、仕事、食事、ユーモア}というトピックを仮定します。その後投稿毎に各トピックへの該当=1,非該当=0で評価したダミー変数を作ることができました。これらの変数を入れることでモデルの評価は向上します。変数に対するパラメータの符号も想定した傾向を裏付けることを確認できました。

AICによる変数選択

良い予測を行うには、オーバーフィッティングを避けることが重要とされています。オーバーフィッティングはデータ量に比べて変数が多すぎる場合に起こりやすいので、これをAICによって評価することを考えます。RのMASSパッケージにはstepAICという関数があって、変数を一つずつ減らしてAICスコアが下がる(低い方が良い)限り変数を減らしたモデルを提案してくれます。実際に実行してみたところ、「食事の話題」を示すダミー変数が削除されてしまいました。

分布の形を変えてみる

先に書いたように、今回のモデルはポワソン分布を仮定しましたが、平均と分散が一致しなかったので別の分布が良いかも知れません。ポワソン分布と似た形を持つ負の2項分布を適用した時の結果を確認してみました。クローズド評価ですが予測の当てはまりが特に改善したように見えなかったので、結局ポワソン分布のままとしておきました。ここは今後の課題と言えます。

オープンテスト

こうしてできたモデルは、指数関数と線型式の組み合わせで表現できるので、Excelなどでも簡単に計算できます。私の後を同僚が引き継いでくれて、モデル作成時に使ったデータより先の1ヶ月間の投稿について確認してくれたのですが、予測と実測のグラフはおおむね良い当てはまりを示していたようです。また何回かモデルを逸脱するいいねの跳ね上がりが観測されたそうですが、これはモデル化をあきらめた「広く知られた話題、ニュースにまつわる投稿」だったので、その意味でも想定した仮説の正しさを確認できたのではないかと思います。

まとめ

統計学が最強の学問である」に書いてあったことですが、現象に対する予測だけが目的ならデータマイニングの手法を使えばよい、ただし現象を理解したい場合は統計的なアプローチの方がふさわしい、ということを今回試してみて実感できました。立てたモデルはほぼ対象のデータをよく観察して得られた仮説を元にしたものになりましたし、それがモデル作成と評価によって支持されたことで、対象に対する理解に自信が深まりました。一方AICに基づく変数選択によって、仮説の一部が否定されましたが、このことも、直感だけでなく定量的なモデルがもたらすメリットと言えるでしょう。

最後にこの分析を通じて理解した「いいね」に対する傾向についてまとめます。

  • 「いいね」は比較的単純・機械的な反応なので、(潜在的な読者数)×投稿内容に読者が反応する要素、という単純な形で予測できる
  • 潜在的な読者数は計測できないが、普通に投稿を続けていれば時間と共に増加すると考えてよい
  • 投稿内容に読者が反応する要素には、大きく分けて、投稿者の感情への共感と投稿内容の話題の面白さがある
  • それら要素の内訳、つまり感情ならどのような種類の感情か、話題についてはどのような話題か、については投稿者と読者層によっておそらく異なる
  • しかし投稿数がそれなりにあれば、その投稿者の読者が何に反応するかは予測できる
  • 一番予測が難しいのは外的な要因、つまり投稿内容が世の中の話題にどの程度関連しているか、そしてその話題の大きさということである。

また、やるかどうか分かりませんが、今後の課題をまとめると以下のようになります。

  • モデルの評価がいい加減なので、検定の枠組みを使ってきちんとやる
  • 潜在的な読者数に良い推測を与えることができるかも知れないので、前回投稿までの傾向(いいね数や投稿間隔など)をモデルに組み込む
  • 投稿内容のトピックを自動的に判定する
  • 投稿当時の世間の話題が、いいね数にどう影響するか、入手可能なニュースソースを補ってモデル化する

以上です。モデルを考えるプロセスは面白かったので、また何か別の課題があれば試してみたいと思います。


This entry was posted in 確率・統計. Bookmark the permalink.