nkjmkzk.net

powered by Kazuki Nakajima

膨大な量のChatterフィードから重要情報だけをピックアップする「すごいChatter分析」

コミュニケーションの中心をメールからChatterに移行すると何が変わるのでしょうか?

僕が考える答えの一つは「コミュニケーションがオープンになる」です。

メールは基本的に情報が入ってくるのを待つアプリケーションであり、一方、Chatterは情報を自発的に見にいくことができるアプリケーションです。この違いは大きい。

例えば経営者が会社で何が起こっているか知りたい場合、多くの組織では部門長からのレポートを待つほかありません。日々おこなわれているメールでのコミュニケーションはToに入っていない人には完全にクローズドになります。

一方、各プロジェクトや部門内でのコミュニケーションをChatterでおこなっている場合(そしてそれが公開グループでおこなわれている場合)、経営者は現場での出来事やコミュニケーションを部門長のレポートを介さずアクセスすることができるようになります。社内の動きをより正確に把握したいアグレッシブな経営者には重要な情報です。

ただ、会社規模が大きくなるにつれ、グループ(部門やプロジェクト)の数は増え、やりとりされているフィード数も爆発的に増加します。TwitterでもFollow数は100を超えると、閲覧方法を工夫しないと情報を追いかけることが難しくなってきます。

どのようにすれば情報の海の中から価値のある情報をクイックにピックアップできるでしょうか?

僕はひとつのアイデアとして、「キーフレーズ抽出」を提案します。

大量の文章に目を通すのは特殊な速読技術を擁さない限り、それなりの時間を根気を必要とします。もし、それらが限られた数のキーワード・キーフレーズのみに絞られて表示されれば、ダッシュボードのように一目で重要なトピックを認識し、そのトピックに関するコミュニケーションだけドリルダウンすることができるはずです。

経営者の例で言えば、各部門やプロジェクト毎に「本日のキーフレーズ」がまとまっていれば、朝の限られた10分というような時間でも会社の状態を掴むことができるかもしれません。

そのキーフレーズ抽出をどのように実現していくかを考えていきます。

日本語はそもそも単語が規則的なデリミターで区切られておらず、文章を構成単位(形態素)に分解し単語を抜き出すのが難しい言語です。その中で、キーフレーズを抽出する簡単なアルゴリズムを考える場合、まず文章の形態素を認識し、その中から固有名詞だけを抽出し、さらにその固有名詞の出現回数をもって重要度をスコアリングするようなアルゴリズムが一つ考えられます。

ただし固有名詞というくくりが必ずしもトピックのすべてとは限りませんし、出現回数だけで「キー(重要)」かどうか判断するのはやや乱暴です。

しかし、世の中には便利なサービスがあるもので、Yahoo Japanさんが日本語文章を送信するだけでそのキーフレーズを抽出&スコアリングして結果を返してくれるキーフレーズ抽出APIを提供してくれています。このサービスは無償で利用することができます。これを使ってみましょう。

一つの構成として、アーキテクチャーは下図のように設計しました。

  1. 最終的なダッシュボードを提供する外部Webサーバにアクセス
  2. Chatterから自分が参加しているグループ(今回は部門またはプロジェクトが設定されていることを想定)のリストと、それぞれのフィード情報を取得
  3. フィード情報をグループ毎に一つのテキストに結合し、Yahooキーフレーズ抽出APIに送信してキーフレーズを取得
  4. Yahooから返してくれるキーフレーズを、セットで提供されるスコアに基づいてフィルタリング、ソートし、ダッシュボードを生成

ダッシュボードを生成するWebサーバにHerokuを用いているのは、もしYahooからの応答時間がForce.comのコールアウトタイムアウトしきい値を超えた場合でもエラーを回避するため、というのが一つの理由です。こういう類いの処理は時間を要することが想定されるので、安全を見越して、ということです。

外部サービスと連携するときは、Force.comから直接のアクセスに固執すると今回のようにコールアウトの待ち時間や、同期でコールアウトが発行できる場合、できない場合があり、制限に抵触するパターンにしばしば遭遇します。中間サーバをひとつ念頭に置いておくと多くのFoce.comの制約を回避でき、よりアプリケーションの幅が広がる可能性があるではないかと思います。

実際のアプリケーションがこちらです。

すごいChatter分析

もし現在Chatterをご利用の方は実際にOAuthで認証いただくことでご自身の組織のChatterフィードをグループ毎に分析することができます。
*本アプリケーションはデモ用途専用です。HerokuからYahoo APIへの通信はHTTPでおこなわれています。ご注意ください。

画面は大きく分けてキーワードとHot Feedの2つで構成されています。

キーワードの方が今回ご紹介した仕組みで動作しており、各キーワードをクリックするとそのキーワードが出現したフィードをドリルダウンして追うことができます。

Hot Feedはコメント数とLike数にしきい値を設定し、一定以上の話題をあつめたフィードを表示するという仕組みです。

最後に、このアーキテクチャのそれぞれの処理でキーとなるAPI呼び出しをご紹介しておきます。今回のアイデアが皆様がChatterを活用したアプリを開発する上で何らかのヒントになれば幸いです。

まずHeroku (php)からChatterのAPIにアクセスし、グループ情報をフィード情報を取得する部分のコードです。

    // メンバーとなっているグループ一覧を取得
    public function get_my_chatter_groups(){
        $url = $this->instance_url . "/services/data/" . $this->api_version . "/chatter/users/me/groups";
        $this->logger->logger("URL : " . $url, __CLASS__, __FUNCTION__);
        $response = $this->callout_for_get($this->access_token, $url);
        if ($this->logger->error){
            $this->logger->set_error("Failed to get my chatter groups.", __CLASS__, __FUNCTION__);
            return(false);
        }
        return($response['groups']);
    }

    // News Feedからフィード情報を取得
    public function get_all_feeds(){
        $url = $this->instance_url . "/services/data/" . $this->api_version . "/chatter/feeds/news/me/feed-items";
        $this->logger->logger("URL : " . $url, __CLASS__, __FUNCTION__);
        $response = $this->callout_for_get($this->access_token, $url);
        if ($this->logger->error){
            $this->logger->set_error("Failed to get all feeds by group.", __CLASS__, __FUNCTION__);
            return(false);
        }
        return($response['items']);
    }

次にHeroku (php)からYahooのAPIにアクセスし、キーフレーズを抽出する部分のコードです。

    // Yahoo APIにフィード情報を送信し、キーフレーズを抽出
    public function get_keywords($sentence, $min_score){
        $api_key = urlencode($this->api_key);
        $sentence = $this->strip_mention($sentence);
        $sentence = urlencode($sentence);
        $url = "http://jlp.yahooapis.jp/KeyphraseService/V1/extract?output=json&appid=" . $api_key;
        $response = $this->callout_for_post($url, $sentence);

        $offset = 0;
        $keywords = array();
        foreach($response as $k => $v){
            if ($v < $min_score){
                continue;
            }
            $keywords[$offset]['value'] = $k;
            $keywords[$offset]['score'] = $v;
            $offset++;
        }
        return($keywords);
    }

without comments

Written by 中嶋 一樹

6月 28th, 2012 at 3:50 pm

Posted in Uncategorized

Tagged with , ,

Leave a Reply