俺もビッグデータの分析とかやってみたいなー
→Twitterとか身近なビッグデータっぽくて扱いやすそう
→よし、アイドル(坂道シリーズ)に関するツイート集めて分析してみよう

という軽いノリでFluentd + ElasticSearch + Kibanaというよくある構成で分析基盤(?)を作ってみました。

今回は基盤作るまでのインストール&設定地獄の備忘録。(自力でやんなくてもDockerやChefで一発で構築できるモノが出回ってそうですが…)

全体構成

Fluentdのfluent-plugin-twitterを使ってStreamingAPI経由で乃木坂、欅坂に関するデータを取得
→データをElasticSearchにぶん投げる。kuromojiのanalyzerで日本語の形態素解析
→Kibanaでビジュアライゼーション

という構成

architecture-fluentd-es-kibana

KibanaやElasticSearch自身にも認証機構を持たせることが出来るっぽいですが、設定が面倒だし設定箇所が分散するので、前段にnginxをリバプロとして置いて、nginx側でBasic認証をかけることで認証を一元的に行うようにしました。

スペックは以下のとおり

  • OS:Ubuntu 14.04(64bit)
  • Platform:DigitalOcean
  • Plan:1GB / 1CPU($10)

nginxのインストール&設定

nginxのインストール。Basic認証使うのでhtpasswdコマンドも。

Basic認証の設定

リバプロとして利用するので以下の様な設定を/etc/nginx/sites-available/defaultとかに記載しておく

Basic認証かけるとはいえ非SSLは論外だと思いますし、署名付きの証明書が無料で手に入る時代でオレオレ式は微妙だと思ったのでLet’s EncryptでSSL証明書取ってきました。

証明書取得に関するドメインバリデーションは、既存のWebサーバを使う方法と使わない方法の二種類あり、webroot指定の場合は既存のWebサーバ(今回はnginx)を使う方法になります。ACMEというプロトコルによってバリデーションが行われるようで、webサーバのドキュメントルート内に認証用のファイルを置いて、Let’s Encrypt側で指定されたURL(ドメイン)に対して認証用のファイルを取得&中身の検証が出来れば認証が通り、署名付きの証明書が生成される、というフローになります。

Let’s Encryptを使った場合、nginxの証明書、秘密鍵の指定は以下のようになります。

Kibanaのインストール&設定

kibanaのダウンロードリンクからソースをダウンロード

リバプロしている関係で以下のように{kibana_path}/config/kibana.ymlを書き換えます

ElasticSearchのインストール・設定

elasticsearchのダウンロードリンクからソースをダウンロード

Java無いと動かないのでインストール

日本語の形態素解析をやってくれるkuromojiをインストール

{elasticsearch_path}/config/elasticsearch.ymlで以下のようにデフォルトでkuromojiのtokenizerとpos_filterが効く設定に変更。stoptagsは除外するものをちゃんと指定しないとうまく動かなかったのでズラズラーっと書いてます

{elasticsearch_path}/config/userdict_ja.txtにユーザ辞書を登録しておく。形態素解析の時にここで登録したワードが切り出されます

管理用のプラグインも一応インストールしておく。無くても動きますが、あると色々便利です。

Fluentdのインストール・設定

Ruby、gemがインストールされている必要があります。インストールされていない場合はrbenv使った方が色々都合が良さそうなので、rbenv経由で以下のようにしてインストールする。

あとはfluentd関連のパッケージをgemで入れまくる

設定ファイルはgistに突っ込んでます。bigqueryも使う場合はfluent-plugin-bigqueryも入れてください。

Supervisorのインストール・設定

kibana、fluentd、elasticsearchはサービスとして登録されていないため、デーモンとして動きません。Supervisorでこれらをデーモン化します。

設定ファイルは echo_supervisord_conf で自動生成して、サービス毎に設定する感じで。HTTPのインターフェースも設定しておくと便利かも。elasticsearch、kibana、fluentdは以下の様な記述でOKです。設定ファイルの場所はどこでもOKですが、公式で配布されているinitscriptを使う場合は、 /etc/supervisor/supervisord.conf に置くと良いです。

実行ファイルパスは適宜修正する感じで。

pipでインストールした場合はinitscriptを書く必要があります。以下のリンクを参考に/etc/init.d/supervisordのファイルを作成します。(supervisorの実行ファイルパス等は適宜修正)

Supervisor/initscripts: User-contributed OS init scripts for Supervisor

initscriptを書いたらサービス化して起動

エラーになる場合はinitscriptに記載されているファイルのパスやパーミッションを確認する。

kibanaで見てみる&結果の考察

一日あたりのワードカウントで円グラフを書くとこんな感じ。

termscount_sakamichi

某S社のギガのCMメンバーが強い…。特に西野七瀬は乃木坂メンバー内でのツイート率が常に一位でした(サンプル期間は1日~)。また、上位陣はアイドル好き女子大生が選んだ〝生〟アイドルランキング!!のメンバーと一致しています。

上記設定で収集したら一日あたりのツイート数は27,000程度。S3にJSON全て保存していますが、gzipにして20MB、生データだと一日あたり200MB程度でした。(ツイートの種別?によってサイズが結構変わるので参考値程度で)

「RT」が一位であったり、「拡散」「希望」がほぼ同数で数も多いことから、リツイートして拡散させているようなツイートが非常に多いです。RT以外のツイートはデイリーの27,000ツイート中3,500程度なので8割以上占めている感じです。「相互フォロー」系も多いです。さらに残った3500ツイートもボットが多そうな雰囲気がしているので、もう少し精査が必要そうです。

また、今回はユーザ辞書にグループ名とメンバーの氏名を入れましたが、普通にツイートしててグループ名やメンバーの氏名を書くことは無く(俺感覚)、「白石麻衣」→「まいやん」とアダ名で書いたりすることが多いです。かといって、「まいやん」をキーワードにすると「まいやん」違いで全国のマイさんに関するツイートを拾ってきてしまうし、全員のアダ名を書くとキーワード数が増えてしまうため、キーワードの選定が非常に難しいです。

今後の課題

  • ElasticSearch、Kibanaの使い方に習熟し、異なる条件、指標でツイートを分析
  • Twitter Streaming APIにおけるキーワード精査
  • ツイート自体の精査(RTが含まれるツイートは除外する等)
  • ツイート以外の有用なデータの検討
  • 全文検索エンジンとは異なるアプローチ(例えばBigQueryAnalytics Cloud等のカラム指向DB)で分析
  • Norikra等のリアルタイム処理を入れて、特定のメンバー、グループに関するツイートが増えた時に通知(何かのイベントが行われている可能性が高い)

参考URL

 

なんかネタで考えて色々やってたらいつの間にかガチになっていた