Upload
hironobu-saitoh
View
576
Download
2
Embed Size (px)
DESCRIPTION
ConoHa presents - Groonga "How-To" Talks(http://groonga.doorkeeper.jp/events/12676)で発表した資料です。コードはhttps://github.com/gc37/20140904-groongaにあります
Citation preview
Groonga と Twitter StreamAPI で
お手軽データ解析
2014/09/04ConoHa presents - Groonga "How-To" Talks
自己紹介
• 斉藤弘信 (@hironobu_s)
• 開発 & インフラ屋
• 所属 :GMO インターネット最近 ConoHa の中の人になりました
あらすじ
• このイベントの雑用係として打ち合わせに参加
• そこにいた Groonga の方と Senna の話をする
• 登壇 <= イマココ
今日やること• github.com/gc37/20140904-groonga
• Groonga 初心者の体験談
• Twitter StreamAPI を使ってデータを収集
• Groonga にストア+ちょっとしたデータ解析
• PHP + GroongaHTTP サーバ
• インフラとして ConoHa VPS(CentOS6.5)
Twitter Steraming API• HTTP で接続すると永遠にツイートデータが流れ
てくる
• 流れてくるのは全ツイートの 1% 程度のサンプル
• 接続するエンドポイントによってとれる情報が違う
• 今回は日本 (lang=ja) を指定して取得してみた。
今回作ったもの
PHP と Groonga
• Groonga の HTTP サーバを使用
• PHP からは cURL でアクセス
• 簡易的な Groonga アクセスクラスを書いた(groonga.php)
• Mroonga の方が簡単だったか・・・
使用例
<?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
• インスタンスを作る
• 実行するコマンドのパラメータを配列にする
• コマンド名を渡して execute() メソッドを叩く
• いじょう
実行結果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" }
• ヒット数、列情報、実行結果がオブジェクトで返る
• 実行結果が連想配列になる
実装
/** * 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
• PHP は便利機能だらけなので、 Groonga HTTPクライアントがすぐ作れる
• http_build_query: QueryString を作ってくれる
• cURL: HTTP のことは全部面倒見てくれる
• json_decode: JSON 文字列を連想配列に変換
データ取得スクリプト概要• twapi_streaming.php
• Phirehose ライブラリを使わせていただいた (https://github.com/fennb/phirehose)
• StreamingAPI からの JSON データをパースしてGroonga 用の JSON オブジェクトを作る
• 自作 Groonga クラスと Phirehose クラスの合わせ技
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();
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
Groonga 側の構成
インデックス作成
• ツイートデータを TwSource テーブルに保存
• text カラムにツイート本文が含まれる
• このカラムに全文検索インデックスを設定
<?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);
• ここは Groonga ドキュメントの通り
• 自作 Groonga ライブラリを通してインデックスを作成する
• 今回はトークナイザに MeCab を使用した
データ分析スクリプト概要• select1.php, select2.php
• 簡単な分析をする
• 対象は 8/24 〜 9/2 までのツイートデータ4,380,001 件
• ( ただし 8/29 、 8/29 、 8/30 の一部は事故で取得失敗・・・ )
• キーワードの出現頻度を見てみましょう
急上昇ワード• Yahoo 急上昇ワードに登場するワードを、今回
の解析基盤で調べてみます。
• 8/25( 火 ) PSN 障害 ( ゲーム )
• 8/26( 水 ) ランドクルーザー( 車 )
• 8/27( 木 ) ヨンア ( モデル ) 、芝幸太郎( 実業家 )
[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 日
時事ワード• デング熱
• 急性の熱性感染症。戦後初の国内感染を確認
• ↑このニュースが出たのが 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 日はデータ取得失敗 )
まとめ
Groonga は速かった• Senna経験者で今回初めて Groonga を触った人の感想です
• とにかく速い。インデックスにあるカラムなら 400万件でも一瞬で結果が返る
• データが小さい。メモリに全部載る ( 今回のデータで 3.7GB)
• 全文検索インデックスの作成がずいぶん短い。最初はほんとに作られてるのか疑った。
• HTTP サーバは簡単にプログラムが書けたので助かった。オーバーヘッドがあるかも ?
時間がなくて試せなかった
• suggest プラグインで補完、提案を試したい
• Mroonga
• Geo データ ( ツイートには結構、緯度経度が入ってた )
ご清聴ありがとうございました
宣伝
ConoHa リニューアルしました
オブジェクトストレージ
容量無制限、転送量課金無し、今日から使えます
月額 450円 /100GB
ブログ書いてます
ConoHa支援プログラム
もちろん VPS も
ConoHa を始めてみよう
• https://www.conoha.jp/
• 全員 1500円分のクーポン付き
• さらに来場者限定で3000円クーポン
• 併せて 4500円分使えます!
• VPS でもオブジェクトストレージでも使えます!
• ストレージだけなら 10ヶ月使えます!
おわり