Kibana | MISO https://alb-owned-https-576747877.ap-northeast-1.elb.amazonaws.com 未来を創造するITのミソ Tue, 27 Aug 2019 06:37:13 +0000 ja hourly 1 https://wordpress.org/?v=6.7.2 https://alb-owned-https-576747877.ap-northeast-1.elb.amazonaws.com/wp-content/uploads/2017/09/tdi_300-300-300x280.png Kibana | MISO https://alb-owned-https-576747877.ap-northeast-1.elb.amazonaws.com 32 32 Lambdaで取得したTwitterの情報をElasticsearchとKibanaで可視化したらすごいことになった話・後編 https://alb-owned-https-576747877.ap-northeast-1.elb.amazonaws.com/lambda-twitter-elasticsearch-kibana-2 Mon, 29 Jul 2019 00:00:12 +0000 https://alb-owned-https-576747877.ap-northeast-1.elb.amazonaws.com/?p=5960 こんにちは。山内です。前回、Twitterから特定のキーワードで検索したものを、ElasticsearchとKibanaで可視化する、という記事を書きましたが、長くなってしまったので2回に分けてお届けします! 前編までで…

The post Lambdaで取得したTwitterの情報をElasticsearchとKibanaで可視化したらすごいことになった話・後編 first appeared on MISO.]]>

こんにちは。山内です。前回、Twitterから特定のキーワードで検索したものを、ElasticsearchとKibanaで可視化する、という記事を書きましたが、長くなってしまったので2回に分けてお届けします!

前編までで、Lambdaを作成するところまで終了しました。
詳しくは、下記の前編をご覧ください。
今回はKibanaの設定から行います。
「作る過程は良いから、作ったものが見たい!」という方は「10.楽しむ!」までジャンプしてください。
 

6.Kibanaの設定

後述のタグクラウドを使いたいので、そのためのデータ構造の設定をします。

  1. AWSマネジメントコンソールで「Elasticsearch Service」を選択し、作成したElasticsearchのダッシュボードから、「Kibana」のURLをクリックする。
  2. 左サイドメニューの「Dev Tools」をクリックする。
  3. コンソールに下記を入力して、「実行ボタン(再生マーク)」をクリック。

    PUT twitter
    {
      "mappings" : {
        "test" : {
          "properties" : {
            "text" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              },
              "analyzer" : "kuromoji",
              "fielddata" : true
            }
          }
        }
      },
      "settings" : {
        "index" : {
          "analysis" : {
            "tokenizer" : {
              "kuromoji_user_dict" : {
                "mode" : "normal",
                "type" : "kuromoji_tokenizer"
              }
            }
          },
          "mapping.total_fields.limit" : 2000
        }
      }
    }

7.Lambdaの実行

基本的な設定は終わったので、Lambdaをテスト実行してみます。

  1. AWSマネジメントコンソールで「AWS Lambda」を選択し、作成した関数の編集画面を表示する。
  2. 「テストイベントの選択▼」をクリックする。
  3. 「テストイベントの設定」をクリックする。
  4. 下記情報を入力し、「作成」をクリックする
    • イベント名   : 任意
    • リクエスト内容 : 下記の通り(任意の文字列はTwitterで検索したいワード)

    {
      "keyword" : "任意の文字列"
    }

     

  5. 「テスト」をクリックし、実行結果に「成功」と出ればOK。

8.Kibanaでグラフの作成

ここは、Kibanaでの基本的なグラフの作成手順です。知ってるよ!って方は飛ばしていただいても構いません。

8-1.indexの作成

まず、Elasticsearchに入っているデータからindexと呼ばれるものを作成します。実際のデータなどが見れてしまうので、スクリーンショットは敢えて載せていません。

  1. Kibanaの画面で、左サイドメニューの「Management」をクリックする。
  2. 「Create index pattern」をクリックする。
  3. 下記情報を入力し、「Next step」をクリックする。
    • Index pattern : twitter(Lambdaで指定したindex名と同じ)
  4. 下記情報を入力し、「Create index pattern」をクリックする。
    • Time Filter field name : @timestamp
  5. 左サイドメニューの「Discover」をクリックし、Tweet情報が表示されればOK。※データが登録されているのに表示されない場合は、右上の表示期間を変更すると出てくる。

8-2.時系列データの縦棒グラフの作成

時系列データをタイムライン的に表示する縦棒グラフを作成します。いわゆるtimestamp型としてデータが入っていないと上手くグラフ化できない場合があるので、ご注意ください。

  1. Kibanaの画面で、左サイドメニューの「Visualize」をクリックする。
  2. 「Create a visualization」をクリックする。

     

  3. 「Vertical Bar」をクリックする。

     

  4. 「twitter(作成したindex名)」をクリックする。
  5. 「Buckets」項目の「X-Axis」をクリックする。
  6. 「Aggregation」で「Date Hisogram」を選択する。
  7. 「Custom Label」項目にx軸のラベル名を入力し、「反映ボタン(再生マーク)」をクリックする。
  8. グラフが更新されていることを確認する(画像は表示期間を「Last 1 hour」にしたもの)。
  9. その他見栄えなどの設定をしたら、ヘッダーメニューの「Save」で名前を付けて保存する。

8-3.タグクラウドの作成

Kibanaの設定の時に名前が出ましたが、タグクラウドを作成します。

  1. Kibanaの画面で、左サイドメニューの「Visualize」をクリックする。
  2. 「+」マークをクリックする。
  3. 「Other」の中にある「Tag Cloud」をクリックする。
  4. 「twitter(作成したindex名)」をクリックする。
  5. 「Buckets」の「Tags」をクリックする。
  6. 「Aggregation」で「Terms」を選択する。
  7. 「Field」で「text」を選択する。※「text.keyword」ではなく「text」であることに注意
  8. 「Size」に任意の数値を入れる。
  9. 「Advanced」の「Exclude」項目に下記を入力し、「反映ボタン(再生マーク)」をクリックする。※下記は任意ですが、表示されるものの除外設定なので、一文字だけのものやURLなどの表示を避けたい場合は設定してください(正規表現的に指定できます)。

    .|..|https?|[0-9]*|[w]*

  10. タグクラウドが表示されることを確認する。
  11. ヘッダーメニューの「Save」で名前を付けて保存する。

9.ダッシュボードの作成

構築手順としてはここで最後です。これまで作ってきたグラフを組み合わせて、ダッシュボードを作成します。ちなみに、最初にお見せした画面イメージは、手順を載せた以外のグラフも作成していますので、ご了承ください。

  1. Kibanaの画面で、左サイドメニューの「Dashboard」をクリックする。
  2. 「Create new dashboard」をクリックする。
  3. 「Add」をクリックする。
  4. 「Tag Cloud(保存したタグクラウドの名前)」をクリックする。
  5. 「Count per Hour(保存した縦棒グラフの名前)」をクリックする。
  6. 「×マーク」をクリックし、好きな配置にカスタマイズしたら、「Save」で名前を付けて保存する。

10.楽しむ!

ここまででTwitterの情報の可視化はできたと思います。あとは、Kibanaを使って色んな視点で見てみてください。例えばですが、「Add a filter」から「lang is ja」を設定すると、日本語だけで絞ることができます。 他のグラフが変化しましたね、面白い!

データ数としては、3万ツイートくらいですかね。タグクラウドで「プレゼント」というワードが大きく表示されています。何かしらのプレゼント企画をやっているのでしょうか。

タグクラウドの「プレゼント」というワードをクリックしてみます。 本当にプレゼント企画をやっていることが確認できました!こうなると、リツイートの情報を拾いたくないときもありそうですね。

先ほどと同じく「Add a filter」から「retweeted_status.retweeted is not false」を設定してみます。 おぉ、リツイートが消えました。すごいですね! 全体が見たいので、「プレゼント」というフィルターを消してみます。 今度は1万7千ツイートくらいですね。半分くらいリツイートだったのでしょうか…!?

タグクラウドを見ると、「楽しい」とか「面白い」といったポジティブなワードが比較的多く見受けられます。皆さん、ゲームを楽しまれているようですね!

11.おわりに

ということで、Elasticsearchを構築して、LambdaからTwitter APIを叩いてElasticsearchに蓄積、Kibanaで可視化をしてみましたが、いかがでしたでしょうか。楽しんでいただけましたでしょうか。

こういう可視化は、とにかく作っていてすごく楽しいですね!良ければ皆さんも構築してみて、タグクラウドが動く様子などを実際に見てみてください!

それから、今回のこの可視化構成の構築を通して、とても重要な教訓を得たので、その共有もしておきます(ここが今回一番すごいところ)。

今回はツイート情報の感情分析のために「Comprehend」と「Translate」というAWSのサービスを使いました。それぞれ読み込ませた文字数ごとに課金される形態なのですが、今回読み込ませた文字はなんと131,434,013文字(すごい)!料金にして、Comprehendは$415.47、Translateはなんと$1,971.51(すごい)!しかもだいたい2,3日で上記の金額だったので、もし1ヶ月フルで使っていたら、単純計算だと10倍くらい(すごい)。

よくよく考えてみれば、1つのツイートが最大200文字、平均を取って100文字くらいだとすると、15分に1回1000ツイートを取得するにしても、1日で9,600,000文字(4回 * 24h * 1000ツイート * 100文字)なので、余裕で超えちゃいますね…。最悪な事態を避けるために、アラート通知などの設定を活用しましょう!設定方法は以下の記事を参考にしてください。

皆さんも、料金は気にする癖をつけるようにしてください。でないと、すごいことになってしまいますよ。

 

※TWITTER、TWEET(ツイート)、RETWEET(リツイート)、Twitter のロゴはTwitter, Inc.またはその関連会社の登録商標です。
※KibanaはElasticsearch BVの登録商標です。

The post Lambdaで取得したTwitterの情報をElasticsearchとKibanaで可視化したらすごいことになった話・後編 first appeared on MISO.]]>
Lambdaで取得したTwitterの情報をElasticsearchとKibanaで可視化したらすごいことになった話・前編 https://alb-owned-https-576747877.ap-northeast-1.elb.amazonaws.com/lambda-twitter-elasticsearch-kibana-1 Wed, 24 Jul 2019 00:00:22 +0000 https://alb-owned-https-576747877.ap-northeast-1.elb.amazonaws.com/?p=6216 1.はじめに こんにちは!毎回記事が長いと言われる山内です。今回も長くなってしまったので、前編と後編に分けてお届けいたします!お付き合いください。 タイトルをご覧いただければお分かりになるかと思いますが、最近、Twitt…

The post Lambdaで取得したTwitterの情報をElasticsearchとKibanaで可視化したらすごいことになった話・前編 first appeared on MISO.]]>

1.はじめに

こんにちは!毎回記事が長いと言われる山内です。今回も長くなってしまったので、前編と後編に分けてお届けいたします!お付き合いください。

タイトルをご覧いただければお分かりになるかと思いますが、最近、Twitterの情報を見える化する機会があったので、今回はそのお話を書かせていただきます。

SNSが浸透してきたこの世の中、「エゴサーチ」ってしたことある人が多いんじゃないでしょうか。エゴサーチをしたことがない人も、SNSを使っていると、トレンドワードみたいなものが表示された経験がある人がほとんどかと思います。筆者も、最新のニュースなどはTwitterのトレンドで知ることが結構あります。

そこで、たくさんあるTwitterの情報を可視化したら楽しそうではないか!ということで、やってみました!(*1)もし、「作る過程は良いから、作ったものが見たい!」という方がいたら、後編の「10.楽しむ!」までジャンプしてください。

(余談ですが、TwitterはSNSじゃないそうです。Twitter社自身も明確に否定しているみたいなので、興味がある方は「Twitter SNS ではない」とかでググってみてくださいね。)

*1 AWSマネジメントコンソールの画面は2019/05/21時点のものです。

2.今回作ったもの

今回作ったものは、Twitterから特定のキーワードで検索したものを、ElasticsearchとKibanaで可視化する、といったものです。この際、AI関連のサービスであるAmazon ComprehendやAmazon Translateを活用し、ツイートの感情分析(ポジネガ分析)も行えるようにしています。本当はComprehendだけでやりたかったのですが、Comprehendが日本語に対応しておらず、Translateで英語に翻訳する処理を入れました。(このときは、まさかあんなにすごいことになるとは思いもしなかった…。)

画面イメージはこんな感じです。
 

 

それから、構成図はこんな感じです。

3.Twitter APIを利用する準備

まず、Twitter APIを利用するための準備として、APIへのアクセス情報を取得する必要があります。下記の手順で、アクセス情報を取得してください。

  1. TwitterのDeveloper Accountを取得する。(取得の仕方は既にネット上にたくさん記事があるので、そちらをご参照ください。)

  2. 下記4つの項目をメモする。

    • API key
    • API secret key
    • Access token
    • Access token secret

4.Elasticsearchを作成する

次に、今回のテーマである「可視化」を行うためのデータを蓄積するElasticsearchを構築していきます。

  1. AWSマネジメントコンソールで「Elasticsearch Service」を選択する。
  2. 「新しいドメインの作成」をクリックする。
  3. 下記情報を入力し、「次へ」をクリックする。
    • デプロイタイプ : 任意(今回は「開発およびテスト」)
    • バージョン   : 任意(今回は「6.5」)

  4. 下記情報を入力し、「次へ」をクリックする。
    • ドメイン名     : 任意(今回は「sns-analysis-demo」)
    • インスタンスタイプ : 任意(今回は「t2.medium.elasticsearch」)

  5. 下記情報を入力し、「次へ」をクリックする。
    • ネットワーク構成 : 任意(今回は「パブリックアクセス」)
    • アクセスポリシー : 任意(今回は「テンプレートを選択」→「ドメインへのオープンアクセスを許可」)

    今回の設定はかなりのセキュリティリスクを伴うため、本来は設定すべきではありません。今回はデモ用の簡易的な環境構築のため、上記設定を行っています。実際はアクセス制限など、しっかり設定してください。

  6. 設定した項目を再度確認し、「確認」をクリックする。
  7. ドメインのステータスが「アクティブ」になればOK。

5.Lambdaを作成する

  1. AWSマネジメントコンソールで「AWS Lambda」を選択する。
  2. 「関数の作成」をクリックする。
  3. 下記情報を入力し、「関数の作成」をクリックする。
    • 関数名   : 任意(今回は「sns-analysis-demo」)
    • ランタイム : Node.js 10.x

  4. 下記コードを転記し、右上の「保存」をクリックする。※requireしているモジュールを合わせてZIPファイルをアップロードする。

    /** モジュールのimport */
    const twitter       = require('twitter');
    const elasticSearch = require('elasticsearch');
    const AWS           = require('aws-sdk');
    
    /** 各クライアントの生成 */
    // elasticsearch用のクライアント
    const elasticsearchClient = new elasticSearch.Client({
        service : 'es',
        region  : process.env.ES_REGION,
        host    : process.env.ES_HOST
    });
    
    // Twitter用のクライアント
    const twitterClient = new twitter({
      consumer_key        : process.env.TW_CONSUMER_KEY,        // API Key
      consumer_secret     : process.env.TW_CONSUMER_SECRET,     // API Secret Key
      access_token_key    : process.env.TW_ACCESS_TOKEN_KEY,    // Access Token
      access_token_secret : process.env.TW_ACCESS_TOKEN_SECRET, // Access Token Secret
    });
    
    // 翻訳用
    const translate       = new AWS.Translate();
    const translateParams = {
      SourceLanguageCode: 'ja',
      TargetLanguageCode: 'en',
      Text: ''
    };
    
    // 感情分析用
    const comprehend = new AWS.Comprehend({region: 'us-east-1'});
    
    /**
     * Elasticsearchにデータを登録します。
     */
    var createIndexAndStreamDataOnES = function(indexName, id, body) {
      // Elasticsearchに登録
      elasticsearchClient.create({
        index : indexName,
        type  : 'test',
        id    : id,
        body  : body
      }, function(err, data) {
          if (err) {
              console.log("Error on creating data", err);
          } else {
              console.log("data reply received", data);
          }
      });
    };
    
    /**
     * 与えられた文字列の感情分析をします。
     */
    const detectSentiment = function (text) {
      return new Promise((resolve, reject) => {
        let params = {
          LanguageCode: "en",
          Text: text
        };
        comprehend.detectSentiment(params, function (err, data) {
          if (err) {
            console.log(err, err.stack);
            reject(err);
          } else {
            resolve(data.Sentiment);
          }
        });
      });
    };
    
    /**
     * 引数に与えられた文字列を含むTweetを検索し、
     * 検索結果をElasticsearchに登録します。
     */
    function searchTweet(queryArg, nextResultsMaxIdArg = null) {
      // Tweetを検索
      twitterClient.get('search/tweets', { q: queryArg, count: 100, max_id: nextResultsMaxIdArg }, (error, searchData, response) => {
        // エラーが発生した場合
        if (error) {
          console.log(error);
          return 1;
        }
    
        // Tweetの検索結果が存在していた場合
        if (searchData !== undefined) {
          var item = null;
          for (item in searchData.statuses) {
            // tweet情報
            let tweet = searchData.statuses[item];
    
            // タイムスタンプ情報を保持
            tweet["@timestamp"] = new Date(tweet["created_at"]);
    
            // 検索条件を保持
            tweet["searchParam"] = queryArg;
    
            // 英語に翻訳
            translateParams["Text"] = tweet.text;
            translate.translateText(translateParams, function(err, translateResult) {
              if (err) {
                console.log(err, err.stack); // an error occurred
              } else {
                // 英訳したテキストの感情を分析
                detectSentiment(translateResult.TranslatedText).then(function(sentiment) {
                  // 分析結果を保持して、elaseticsearchに登録
                  tweet["sentiment"] = sentiment;
                  createIndexAndStreamDataOnES("twitter", tweet["id_str"], tweet);
                });
              }
            });
          }
    
          if (searchData.search_metadata == undefined) {
            return 0;
          } else if (searchData.search_metadata.next_results) {
            let maxId = searchData.search_metadata.next_results.match(/\?max_id=(\d*)/);
    
            if (maxId[1] == null) {
              return 0;
            }
            searchTweet(queryArg, maxId[1]);
          } else {
            return 0;
          }
        }
      });
    }
    
    /**
     * Lambdaのハンドラー関数です。
     */
    exports.handler = function (event) {
      // ツイートを検索
      searchTweet(event.keyword);
    
      // レスポンスを返す
      const response = {
          statusCode: 200,
          body: JSON.stringify('Success!'),
      };
      return response;
    };

  5. 「基本設定」内の下記項目を設定し、「保存」をクリックする。
    • 説明     : 任意
    • タイムアウト : 15分

  6. 「環境変数」に下記情報を登録する。
    • ホスト
      • キー : ES_HOST
      • 値  : (Elasticsearchの「エンドポイント」の「https://」を除いたもの
    • Elasticsearchを作成したリージョン
      • キー : ES_REGION
      • 値  : (今回は「ap-northeast-1」)
    • Twitter APIへのアクセス情報(API Key)
      • キー : TW_CONSUMER_KEY
      • 値  : TwitterのDeveloper Account作成時にメモしたもの(API Key)
    • Twitter APIへのアクセス情報(API Secret Key)
      • キー : TW_CONSUMER_SECRET
      • 値  : TwitterのDeveloper Account作成時にメモしたもの(API Secret Key)
    • Twitter APIへのアクセス情報(Access Token)
      • キー : TW_ACCESS_TOKEN_KEY
      • 値  : TwitterのDeveloper Account作成時にメモしたもの(Access Token)
    • Twitter APIへのアクセス情報(Access Token Secret)
      • キー : TW_ACCESS_TOKEN_SECRET
      • 値  : TwitterのDeveloper Account作成時にメモしたもの(Access Token Secret)

  7. 「実行ロール」内の「~~~~ロールを表示」リンクをクリックする。
  8. 「ポリシーをアタッチします」をクリックする。
  9. 下記ポリシーをチェックし、「ポリシーのアタッチ」をクリックする。
      • ConprehendReadOnly
      • TransolateReadOnly

 

ここまででElasticsearchとLambdaの作成は終わりです。次回、後編ではKibanaを設定するところからご説明いたします。お楽しみに!

※TWITTER、TWEET(ツイート)、RETWEET(リツイート)、Twitter のロゴはTwitter, Inc.またはその関連会社の登録商標です。
※KibanaはElasticsearch BVの登録商標です。

The post Lambdaで取得したTwitterの情報をElasticsearchとKibanaで可視化したらすごいことになった話・前編 first appeared on MISO.]]>