35
Groonga と Twitter StreamAPI と とととととととと 2014/09/04 ConoHa presents - Groonga "How-To" Talks

20140903groonga発表資料

Embed Size (px)

DESCRIPTION

ConoHa presents - Groonga "How-To" Talks(http://groonga.doorkeeper.jp/events/12676)で発表した資料です。コードはhttps://github.com/gc37/20140904-groongaにあります

Citation preview

Page 1: 20140903groonga発表資料

Groonga と Twitter StreamAPI で

お手軽データ解析

2014/09/04ConoHa presents - Groonga "How-To" Talks

Page 2: 20140903groonga発表資料

自己紹介

• 斉藤弘信 (@hironobu_s)

• 開発 & インフラ屋

• 所属 :GMO インターネット最近 ConoHa の中の人になりました

Page 3: 20140903groonga発表資料

あらすじ

• このイベントの雑用係として打ち合わせに参加

• そこにいた Groonga の方と Senna の話をする

• 登壇 <= イマココ

Page 4: 20140903groonga発表資料

今日やること• github.com/gc37/20140904-groonga

• Groonga 初心者の体験談

• Twitter StreamAPI を使ってデータを収集

• Groonga にストア+ちょっとしたデータ解析

• PHP + GroongaHTTP サーバ

• インフラとして ConoHa VPS(CentOS6.5)

Page 5: 20140903groonga発表資料

Twitter Steraming API• HTTP で接続すると永遠にツイートデータが流れ

てくる

• 流れてくるのは全ツイートの 1% 程度のサンプル

• 接続するエンドポイントによってとれる情報が違う

• 今回は日本 (lang=ja) を指定して取得してみた。

Page 6: 20140903groonga発表資料

今回作ったもの

Page 7: 20140903groonga発表資料

PHP と Groonga

• Groonga の HTTP サーバを使用

• PHP からは cURL でアクセス

• 簡易的な Groonga アクセスクラスを書いた(groonga.php)

• Mroonga の方が簡単だったか・・・

Page 8: 20140903groonga発表資料

使用例

<?phprequire_once 'groonga.php'; $groonga = new Groonga('localhost', 10041); $cond = [ 'table' => 'TableName', 'match_columns' => 'test_col', 'query' => 'hoge', 'limit' => 10, 'offset' => 0]; $r = $groonga->execute('select', $cond); // ヒット数var_dump($r->count); // 列情報var_dumP($r->headers); // 実行結果var_dumP($r->results);

• github.com/gc37/20140904-groonga

example.php

Page 9: 20140903groonga発表資料

• インスタンスを作る

• 実行するコマンドのパラメータを配列にする

• コマンド名を渡して execute() メソッドを叩く

• いじょう

Page 10: 20140903groonga発表資料

実行結果int(161) <=== ヒット数array(10) { <=== 検索結果 [0]=> array(7) { ["_id"]=> int(90032) ["created_at"]=> float(1408890604) ["date"]=> string(10) "2014-08-24" ["name"]=> string(11) "hiroshi5s38" ["screen_name"]=> string(36) " レンタルサーバーの選び方 " ["source"]=> string(11) "sakura_blog" ["text"]=> string(106) " 『サーバーの悩み』レンタルサーバー比較 - サービスの比…| http://t.co/j1AtQfUXOL" }

• ヒット数、列情報、実行結果がオブジェクトで返る

• 実行結果が連想配列になる

Page 11: 20140903groonga発表資料

実装

/** * Groonga サーバにリクエストを送信して、結果を JSON で返す * * @param string $cmd コマンド名 * @param array $params コマンドに渡すパラメータ配列 * @return array */ private function sendRequest($cmd, $params = []) { $url = sprintf('http://%s:%d/d/%s', $this->host, $this->port, $cmd); $url .= '?' . http_build_query($params); // リクエストを送信 $curl = $this->initializeCurl(); curl_setopt($curl, CURLOPT_URL, $url); $body = curl_exec($curl); if( ! $body) { throw new RuntimeException('HTTP Request fail.'); } // レスポンスをデコードする $json = json_decode($body, true); if( ! $json) { throw new RuntimeException('Incorrect datatype for JSON.'); }  // この要素が 0 未満の場合はコマンド実行失敗で、 [0][3] にメッセージが入るっぽい。 if($json[0][0] < 0) { throw new RuntimeException($json[0][3]); } return $json; }

• github.com/gc37/20140904-groonga

Page 12: 20140903groonga発表資料

• PHP は便利機能だらけなので、 Groonga HTTPクライアントがすぐ作れる

• http_build_query: QueryString を作ってくれる

• cURL: HTTP のことは全部面倒見てくれる

• json_decode: JSON 文字列を連想配列に変換

Page 13: 20140903groonga発表資料

データ取得スクリプト概要• twapi_streaming.php

• Phirehose ライブラリを使わせていただいた (https://github.com/fennb/phirehose)

• StreamingAPI からの JSON データをパースしてGroonga 用の JSON オブジェクトを作る

• 自作 Groonga クラスと Phirehose クラスの合わせ技

Page 14: 20140903groonga発表資料

Phirehose ライブラリの使い方<?php require_once 'phirehose/lib/Phirehose.php';require_once 'phirehose/lib/OauthPhirehose.php'; // OAuth$access_token = '************************************************';$access_token_secret = '******************************************'; class TestStream extends OauthPhirehose{ public function enqueueStatus($status) { // ここに実装を書くだけ // $status が 1 ツイートの JSON データになっている // // また今回の場合、自動的に以下のエンドポイントが選択される // https://stream.twitter.com/1.1/statuses/filter.json  }}

$s = new TestStream($access_token, $access_token_secret);$s->setLang('ja');$s->consume();

Page 15: 20140903groonga発表資料

Groonga への保存

<?php // Groonga にデータを保存する// $data はツイートオブジェクト$tweet = [ '_key' => $data->id_str, 'text' => $data->text, 'source' => $data->source, 'name' => $data->user->name, 'screen_name' => $data->user->screen_name, 'created_at' => $time]; if($data->geo != null) { $geo = $data->geo->coordinates[0] . 'x' . $data->geo->coordinates[1]; $tweet['geo'] = $geo;} $data = [ 'table' => 'TwSource', 'values' =>json_encode([ $tweet ])]; $r = $this->groonga->execute('load', $data);

• twapi_streaming.php

Page 16: 20140903groonga発表資料

Groonga 側の構成

Page 17: 20140903groonga発表資料

インデックス作成

• ツイートデータを TwSource テーブルに保存

• text カラムにツイート本文が含まれる

• このカラムに全文検索インデックスを設定

Page 18: 20140903groonga発表資料

<?php$g = new Groonga('localhost', 10041); // 既存テーブル削除try { $params = [ 'name' => 'TwIndex' ]; $g->execute('table_remove', $params);} catch(Exception $e) {} // インデックステーブルを作成$params = [ 'name' => 'TwIndex', 'flags' => 'TABLE_PAT_KEY|KEY_NORMALIZE', 'key_type' => 'ShortText', 'default_tokenizer' => 'TokenMecab',];$g->execute('table_create', $params); // インデックスカラムを作成$params = [ 'table' => 'TwIndex', 'name' => 'text', 'flags' => 'COLUMN_INDEX|WITH_POSITION', 'type' => 'TwSource', 'source' => 'text'];$g->execute('column_create', $params);

Page 19: 20140903groonga発表資料

• ここは Groonga ドキュメントの通り

• 自作 Groonga ライブラリを通してインデックスを作成する

• 今回はトークナイザに MeCab を使用した

Page 20: 20140903groonga発表資料

データ分析スクリプト概要• select1.php, select2.php

• 簡単な分析をする

• 対象は 8/24 〜 9/2 までのツイートデータ4,380,001 件

• ( ただし 8/29 、 8/29 、 8/30 の一部は事故で取得失敗・・・ )

• キーワードの出現頻度を見てみましょう

Page 22: 20140903groonga発表資料

[hiro@MBP]# ./select_burst.php PSN 障害2014-08-24: 152014-08-25: 162014-08-26: 122014-08-27: 22014-08-28: 02014-08-29: 02014-08-30: 02014-08-31: 02014-09-01: 0

[hiro@MBP]# ./select_burst.php ランドクルーザー2014-08-24: 02014-08-25: 842014-08-26: 202014-08-27: 52014-08-28: 42014-08-29: 02014-08-30: 02014-08-31: 12014-09-01: 5

[hiro@MBP]# ./select_burst.php ヨンア2014-08-24: 02014-08-25: 22014-08-26: 2092014-08-27: 292014-08-28: 142014-08-29: 02014-08-30: 02014-08-31: 02014-09-01: 2[hiro@MBP]# ./select_burst.php 芝幸太郎2014-08-24: 02014-08-25: 02014-08-26: 1352014-08-27: 102014-08-28: 12014-08-29: 02014-08-30: 02014-08-31: 02014-09-01: 0

25 日

26 日

27 日

Page 23: 20140903groonga発表資料

時事ワード• デング熱

• 急性の熱性感染症。戦後初の国内感染を確認

• ↑このニュースが出たのが 27 日

[hiro@MBP]# ./select_burst.php デング熱2014-08-24: 02014-08-25: 02014-08-26: 02014-08-27: 3322014-08-28: 7562014-08-29: 02014-08-30: 02014-08-31: 382014-09-01: 837

(29 日、 30 日、 31 日はデータ取得失敗 )

Page 24: 20140903groonga発表資料

まとめ

Page 25: 20140903groonga発表資料

Groonga は速かった• Senna経験者で今回初めて Groonga を触った人の感想です

• とにかく速い。インデックスにあるカラムなら 400万件でも一瞬で結果が返る

• データが小さい。メモリに全部載る ( 今回のデータで 3.7GB)

• 全文検索インデックスの作成がずいぶん短い。最初はほんとに作られてるのか疑った。

• HTTP サーバは簡単にプログラムが書けたので助かった。オーバーヘッドがあるかも ?

Page 26: 20140903groonga発表資料

時間がなくて試せなかった

• suggest プラグインで補完、提案を試したい

• Mroonga

• Geo データ ( ツイートには結構、緯度経度が入ってた )

Page 27: 20140903groonga発表資料

ご清聴ありがとうございました

Page 28: 20140903groonga発表資料

宣伝

Page 29: 20140903groonga発表資料

ConoHa リニューアルしました

Page 30: 20140903groonga発表資料

オブジェクトストレージ

容量無制限、転送量課金無し、今日から使えます

月額 450円 /100GB

Page 31: 20140903groonga発表資料

ブログ書いてます

Page 32: 20140903groonga発表資料

ConoHa支援プログラム

Page 33: 20140903groonga発表資料

もちろん VPS も

Page 34: 20140903groonga発表資料
Page 35: 20140903groonga発表資料

ConoHa を始めてみよう

• https://www.conoha.jp/

• 全員 1500円分のクーポン付き

• さらに来場者限定で3000円クーポン

• 併せて 4500円分使えます!

• VPS でもオブジェクトストレージでも使えます!

• ストレージだけなら 10ヶ月使えます!

おわり