Microsoft Translator APIによる文字列の言語判定(Perl)
以下は、Microsoft Translator APIのdetectメソッドで言語判定するPerlスクリプトを書いたののメモ。「Microsoft Translator API(HTTP版)を使ってみました - kurukuru-papaのブログ」というエントリが大変参考になりました。ありがとうございました。
数十文字以下の文字列の言語を自動判定する方法[*1]を探していて、
- language-detection(オープンソースのJavaライブラリ)
- Google Translate API(有料。100万文字で20ドル)
- Microsoft Translator API(月200万文字までなら無料)
あたりが見つかる。
3番目はBing Translatorのバックエンドで使われているアルゴリズムらしい。ふだんはGoogle翻訳しか使ってないのだけど、APIは有料になっちゃったし、Bingのほうも何件かテストしてみたら悪くなかった。ので、試してみることにした。
準備
(1) Microsoftアカウントを作成
GMailのメールアドレスをそのままアカウントに使えた。
http://www.microsoft.com/ja-jp/msaccount/default.aspx
(2) Windows Azure Marketplaceで登録
右上の「2,000,000文字/月(無料)」をクリック。
https://datamarket.azure.com/dataset/1899a118-d202-492c-aa16-ba21c33c06cb
(3) 自作アプリケーションの登録
「クライアントID」は適当に決めていい。「顧客の秘密」という変な名前のAPIキーを取得できる。
https://datamarket.azure.com/developer/applications/
全体の流れ
APIにはAjax、HTTP、SOAPの3種類が用意されてる。ここでは気楽にHTTP。
http://msdn.microsoft.com/en-us/library/ff512423.aspx
(1) Access Tokenの取得
まずはAPIの利用に必要なAccess Token(有効期間は10分間)を取得する。
http://msdn.microsoft.com/en-us/library/hh454950.aspx
そのためにはHTTP POSTで、
https://datamarket.accesscontrol.windows.net/v2/OAuth2-13
に対して以下のデータを送信する(すべて必須項目)。
client_id | 申請した「クライアントID」 |
client_secret | 取得した「顧客の秘密」 |
scope | http://api.microsofttranslator.com(固定値) |
grant_type | client_credentials(固定値) |
すると、JSONで以下のデータが返ってくる。
access_token | |
token_type | http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0(固定値) |
expires_in | |
scope | http://api.microsofttranslator.com(固定値) |
access_token以外は(少なくともこの用途では)使わない。
(2) detectメソッドを叩く
先ほど取得したaccess_tokenを使い、HTTP GETで、
Authorization: Bearer <access_token>
というヘッダを付けて、
http://api.microsofttranslator.com/V2/Http.svc/Detect?appId=&text=<判定したい文字列>
のように送信する。< と > は不要。「Bearer+半角スペース」の部分は固定で、appIdは空でいいようだ(Authorizationヘッダでaccess_tokenを送っているから)。
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">fr</string>
コード体系がよく分からなかったので以下のコードでは「\S」で抜いてるけど、あとで探したらちゃんと言語コードの一覧があった。
繰り返し detect する際には、その都度ヘッダ付きでGETする。access_tokenの有効期間が切れたらどうなるかは試してないので分からない(1600件ほど処理したらちょうど9分ちょいで終わった)。
サンプルコード
#!/usr/bin/perl -w use strict; use LWP::UserAgent; use JSON; my $ua = LWP::UserAgent->new; my $res; my $text = 'なにか適当に判定したい文字列を'; # access_token取得 my $authurl = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13'; my $param = { client_id => '設定した「クライアントID」', client_secret => '取得した「顧客の秘密」', scope => 'http://api.microsofttranslator.com', grant_type => 'client_credentials' }; $res = $ua->post($authurl, $param)->content; my $access_token = JSON->new->decode($res)->{access_token}; # detect実行 my $detecturl = 'http://api.microsofttranslator.com/V2/Http.svc/Detect?text='; $res = $ua->get( $detecturl . $text, 'Authorization' => 'Bearer ' . $access_token )->content; # 言語コード抽出 $res =~ />(\S{1,})</; print $1, "\n";
*1:正確に言うとやりたいのは、書籍のタイトルの言語を判定して、本文の言語として設定するという2段階に無理のあるはなしなんだけど。