gooラボ　キーワード抽出APIをGroovyを使って試してみる

gooラボが提供するキーワード抽出APIを使ってみます。無料で使用することもでき、問い合わせることにより商用利用も可能なようです。
ぼんやりとWebアプリ上でサーバーと対話的に情報交換できるサービスって作れないかなと思い始め、形態素解析、キーワード抽出を試してみたいと思います。

形態素解析、キーワード抽出関係のAPIはgooラボの他に、Yahooでも提供しているようですが、今回はgooラボを試してみます。
時間があったらyahooも試してみて比較とかしてみたいですね。

今回はキーワード抽出のみ取り上げます。形態素解析は[別記事](http://qiita.com/shohei1913/items/1efd24f6b56ced50f4cf)をあげています。
なおソースはGroovyで書いてます。最近ハマっているので。

# キーワード抽出とは
引用：[gooラボ](https://labs.goo.ne.jp/api/2015/1321/)より
> キーワード抽出APIはリクエストで送られたタイトルと本文からなる文書から、人名や地名、組織など文書を特徴づけるキーワードを抽出します。キーワードはタイトルや本文における出現位置や、文書中における出現回数、固有表現の種別などによってスコア付けされます。

# 事前準備〜APIを使えるようにするまで〜
手順はgooラボの[サイト](https://labs.goo.ne.jp/apiusage/)から

1. GitHubのアカウントを登録する
2. アプリケーションIDの取得

# APIの使い方
`https://labs.goo.ne.jp/api/keyword`に対してリクエストをなげる。application/x-www-form-urlencoded、application/json形式のPOSTのみ対応しているそうで、GETは受け付けてない点に注意。

## パラメータ一覧
app_id : アプリケーションID
request_id：リクエストID ※省略可
title：解析対象のタイトル
body：解析対象の本文
max_num：最大出力キーワード数
focus：注目固有表現種別(ORG(組織名)、PSN(人名)、LOC(地名)から、スコアを強く算出したいを1種類を指定)


# Groovyで書いてみた

```groovy:KeywordExtraction.groovy
@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.6')
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.URLENC

//引数に抽出対象文字列を指定
def title
def body
if(args.size()>=2){
  title = args[0]
  body = args[1]
}else{
  //引数に文字列が指定されていない場合
  title = 'サンプルのタイトル。１番目の引数で指定可能。東京の杉並区にあるラーメン屋さんについて。'
  body = 'サンプルの本文。２番目の引数で指定可能。西荻窪駅北口にあるひごもんずはなかなか美味しい。ラーメン評論家といえば石神秀幸が有名ですね。'
}

//抽出
def keywords = extractKeyword(title,body)

println '********** 抽出前の文章 **********'
println title
println body
println '********** 抽出後の文章 **********'
println keywords

/** 入力文をキーワード抽出する */
def extractKeyword(title,body){
    def http = new HTTPBuilder( 'https://labs.goo.ne.jp/api/keyword' )
    http.post( body: [app_id: '{登録したアプリケーションID}',
                      title: title,
                      body: body,
                      max_num: 30,
                      focus: 'LOC'],
             requestContentType: URLENC ) { resp,reader  ->

        if (resp.status == 200) {
            return reader.keywords
        }
        else if (resp.status == 404) {
            println "Access denied"
        }
        else {
            println "Unexpected failure: ${resp.statusLine}"
        }
    }
}
```

## 実行方法

以下のようにコマンドライン実行することを想定しています。

```
groovy KeywordExtraction.groovy タイトル　本文
```

## 実行結果

```
********** 抽出前の文章 **********

サンプルのタイトル。１番目の引数で指定可能。東京の杉並区にあるラーメン屋さんについて。

サンプルの本文。２番目の引数で指定可能。西荻窪駅北口にあるひごもんずはなかなか美味しい。ラーメン評論家といえば石神秀幸が有名ですね。

********** 抽出後の文章 **********

[[東京:2.8947], [杉並区:2.8947], [サンプル:1.0234], [引数:1.0234], [指定:1.0234], [タイトル:0.5789], [ラーメン屋さん:0.5789], [本文:0.3644], [西荻窪駅北口:0.2044], [卑語:0.2044], [石神秀幸:0.1867], [ラーメン評論家:0.1244]]
```
地名を高く評価するように設定しているので、東京、杉並区が高く評価されているようです。
西荻窪駅北口が一つの塊となっていて、地名とは認識されていないのは残念ですね。
サンプル、引数、指定といったキーワードはタイトルと本文の両方で使われていて頻出しているので評価が高いのかな？
ちなみに[卑語:0.2044]ってなんでしょう？笑　ひごもんずから勝手に漢字変換したのかな？


### 注目固有表現種別を変えると以下のようになります。
***

***ORG（組織）の場合***

```
[[サンプル:1.0234], [引数:1.0234], [指定:1.0234], [タイトル:0.5789], [ラーメン屋さん:0.5789], [本文:0.3644], [東京:0.2895], [杉並区:0.2895], [西荻窪駅北口:0.2044], [卑語:0.2044], [石神秀幸:0.1867], [ラーメン評論家:0.1244]]
```

***PSN（人名）の場合***

```
[[サンプル:1.0234], [引数:1.0234], [指定:1.0234], [石神秀幸:0.6222], [タイトル:0.5789], [ラーメン屋さん:0.5789], [本文:0.3644], [東京:0.2895], [杉並区:0.2895], [西荻窪駅北口:0.2044], [卑語:0.2044], [ラーメン評論家:0.1244]]
```

PSNでは[石神秀幸:0.6222]の評価が上がっていますね。それでもサンプルや引数といったキーワードより評価が低いです。LOCの場合は東京や杉並区が高評価になっているので、本文よりタイトルの評価がかなり高くなっているようですね。
ちなみに「石神さん」では人名と認識してもらえませんでした。

# 補足
利用制限にリクエスト回数とリクエストサイズがあるようなので、解析対象テキストは適度なサイズに区切った方が良さそうですね。