gooラボ 形態素解析APIを試してみる
これはPowerShell Advent Calendar 2014 : ATND 13日目の記事です。
PowerShell で REST API
近年、RESTfullなAPIで提供されるWebサービスが非常に増えているように感じます。
そんな中、ちょっと気になるAPIがあったら、気軽に試したりしたいですよね。
「PowerShellを使えば、お手軽にREST API がお試しできますよ!」
という事で、最近見かけた、gooラボの形態素解析APIを試してみたいと思います。
NTTレゾナント、gooで開発・蓄積した「日本語解析API」を公開、ビッグデータ解析機能なども提供予定:CodeZine
と、4種類のAPIが提供されています。
この中から今回は形態素解析APIを使います。
上の記事の内容を見る限りですと、文を語句に分割するだけ?のように思えますが、「PowerShell, 名詞, パワーシェル」の様に、分割した「語句」の「品詞(形態素)」と「読み」を付けて返してくれます。
形態素解析API:日本語文字列を語句に分割する技術 - gooラボ
Invoke-RestMethod でPOST
- リクエスト先URL
https://labs.goo.ne.jp/api/morph- リクエストパラメータ
application/x-www-form-urlencoded、application/json形式でのPOSTを受け付けます。
とあります。
Invoke-RestMethod
コマンドレットで試してみます。今回はapplication/jsonでPOSTします。
リクエストパラメータ
app_id
アプリケーションID。
必須項目。 こちら(https://labs.goo.ne.jp/apiusage/)で取得した、アプリケーションIDを設定します。(IDの取得にはGitHubアカウントが必要になります。)request_id
リクエストID。
省略時は”labs.goo.ne.jp[タブ文字]リクエスト受付時刻[タブ文字]連番”となります。sentence
解析対象テキスト。
必須項目。info_filter
形態素情報フィルタ。
form(表記)、pos(形態素)、read(読み)のうち、出力する情報を文字列で指定します。pos_filter
形態素品詞フィルタ。
出力対象とする品詞を”|”で区切って指定します。
リクエストパラメータは、HashTebleで作成し、Invoke-RestMethod
のBody
パラメータに指定します。
今回は、とりあえず必須項目のapp_id
とsentence
のみを使用します。
PS C:\> $text = "Windows PowerShell は、マイクロソフトが開発した拡張可能なコマンドラインインターフェース (CLI) シェルおよびスクリプト言語である。" + ` "オブジェクト指向に基づいて設計されており、.NET Framework 2.0 を基盤としている。" PS C:\> $res = Invoke-RestMethod -Method Post ` -Uri https://labs.goo.ne.jp/api/morph ` -Body @{ app_id = "your application id"; sentence = $text; }
レスポンスの取得
レスポンスパラメータは、以下の通りです。
request_id
リクエストID。
リクエストと同じ値となります。info_filter
形態素情報フィルタ。
入力と同じ値となります。pos_filter
形態素品詞フィルタ。
入力と同じ値となります。word_list
形態素リスト。
形態素リストは文ごとに分かれた文単位形態素リストの配列となります。
文単位形態素リストは形態素情報の配列で、形態素情報には表記・形態素・読みのうち形態素情報フィルタで指定された要素が含まれます。
例:
Invoke-RestMethod では、JSONで帰ってきたレスポンスパラメータをPSObjectにデシリアライズして返してくれます。大変便利ですね。
PS:\> $res request_id word_list ---------- --------- labs.goo.ne.jp 1418127883 0 {System.Object[] System.Object[] Sys...
解析結果の本体は、word_listにあります。展開してみましょう。
PS C:\> $res.word_list |%{$_} Windows åè© ã¦ã£ã³ãã¼ãº ç©ºç½ ï¼ Power åè© ãã¯ã¼ Shell åè© ã·ã§ã« ...
ん!? 文字化けしちゃってますね
レスポンスのエンコーディングについて
Invoke-RestMethod コマンドレットは、レスポンスヘッダ(Content-Type ;charset?) を見てエンコーディングしてくれるようなのですが、
このAPIのレスポンスヘッダにはcharsetの指定が無いようなのです。
その場合ってどうなるの?
どうやらcahrsetの指定がない場合は ISO-8859-1
でエンコーディングされるらしい。
確認してみましょう。生のレスポンスが必要なのでInvoke-RestMethod
ではなく、Invoke-WebRequest
コマンドの方を使います。
レスポンスの Content
に格納されている文字列を一旦Byte列に戻してからUtf-8でエンコーディングし直してみます。
PS C:\> $res = Invoke-WebRequest -Method Post ` -Uri https://labs.goo.ne.jp/api/morph ` -Body @{ app_id = "your application id"; sentence = $text; } PS C:\> $res.Content {"request_id":"labs.goo.ne.jp\t1418129359\t0","word_list":[[["Windows","åè©" ,"ã¦ã£ã³ãã¼ãº"],[" ","空ç½","ï¼"],["Power","åè©","ãã¯ã¼"],["Sh ell","åè©","ã·ã§ã«"],[" ","空ç½","ï¼"],["ã¯","é£ç¨å©è©","ã"],[" ... PS C:\> [System.Text.Encoding]::Utf8.GetString( ` [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($res.Content)) {"request_id":"labs.goo.ne.jp\t1418129359\t0","word_list":[[["Windows","名詞","ウィ ンドーズ"],[" ","空白","$"],["Power","名詞","パワー"],["Shell","名詞","シェル"],[" ","空白","$"], ["は","連用助詞","ハ"],["、","読点","$"],["マイクロソフト","名詞","マイクロソフト"],["が","格助詞","ガ"],["開発 ...
おおー、ちゃんと読めるようになりました!
なお、レスポンスのクラスにはRawContentStream というプロパティがあり、ここからエンコード前のByte配列が取れるので、 こちらを使った方が1手間減って良いかもしれません。
PS C:\>$data = [System.Text.Encoding]::Utf8.GetString($res.RawContentStream.GetBuffer()))
データをもう少し扱いやすくする
解析結果の本体が格納された word_list
は配列が入れ子になっていて扱いづらいので、少し手を加えます。
# 以下のように入れ子になっているのを 単語(n) = [form(表記), pos(形態素), read(読み)] 文(n) = [単語(1), 単語(2), 単語(3),...] word_list = [文(1), 文(2), 文(3),...] # 以下のように平坦化します word_list = [@{SentenceNum(文番号), Form(表記), Pos(形態素), Read(読み)}, @{SentenceNum(文番号), Form(表記), Pos(形態素), Read(読み)}, @{SentenceNum(文番号), Form(表記), Pos(形態素), Read(読み)}, @{SentenceNum(文番号), Form(表記), Pos(形態素), Read(読み)},...]
PS C:\> $obj = $data | ConvertFrom-Json | %{$_.word_list} | % -Begin{ $n=0 } { $_ | % { [PSCustomObject]@{ SentenceNum=$n; Form=$_[0]; Pos=$_[1]; Read=$_[2] } }; $n++; } PS C:\> $obj SentenceNum Form Pos Read ----------- ---- --- ---- 0 Windows 名詞 ウィンドーズ 0 空白 $ 0 Power 名詞 パワー 0 Shell 名詞 シェル 0 空白 $ 0 は 連用助詞 ハ 0 、 読点 $ 0 マイクロソフト 名詞 マイクロソフト 0 が 格助詞 ガ 0 開発 名詞 カイハツ 0 し 動詞活用語尾 シ 0 た 動詞接尾辞 タ 0 拡張 名詞 カクチョウ 0 可能 名詞 カノウ 0 な 判定詞 ナ 0 コマンド 名詞 コマンド 0 ライン 名詞 ライン 0 インターフェース 名詞 インターフェース 0 空白 $ 1 ( 括弧 $ 1 CLI Alphabet シーエルアイ 1 ) 括弧 $ 1 空白 $ 2 シェル 名詞 シェル 2 および 連体詞 オヨビ 2 スクリプト 名詞 スクリプト 2 言語 名詞 ゲンゴ 2 で 判定詞 デ 2 あ 動詞語幹 ア 2 る 動詞接尾辞 ル 2 。 句点 $
これで大分扱いやすくなったと思います。
後の集計などは、PowerShellならお手の物ですよね。
名詞のみを抽出する
PS C:\> $obj | where {$_.Pos -eq "名詞"} | %{$_.Form} Windows Power Shell マイクロソフト 開発 拡張 可能 コマンド ライン インターフェース シェル スクリプト 言語 オブジェクト 指向 設計 NET Framework 基盤
形態素(品詞)のランキング
$obj | Group-Object Pos | Sort-Object count -Descending Count Name Group ----- ---- ----- 19 名詞 {@{SentenceNum=0; Form=Windows; Pos=名詞; Read=ウィンドーズ}, @{SentenceNum=0; Form=Power; Pos=名詞; Read=パワー}, @{SentenceNum=0; Form=Shell; Pos=名詞; Read=シェル}, @{SentenceNum=0; Form=マイク... 7 空白 {@{SentenceNum=0; Form= ; Pos=空白; Read=$}, @{SentenceNum=0; Form= ; Pos=空白; Read=$}, @{SentenceNum=0; Form= ; Pos=空白; Read=$}, @{SentenceNum=1; Form= ; Pos=空白; Read=$}...} 7 動詞接尾辞 {@{SentenceNum=0; Form=た; Pos=動詞接尾辞; Read=タ}, @{SentenceNum=2; Form=る; Pos=動詞接尾辞; Read=ル}, @{SentenceNum=3; Form=て; Pos=動詞接尾辞; Read=テ}, @{SentenceNum=3; Form=れ; Pos=動詞接尾辞; Rea... 4 格助詞 {@{SentenceNum=0; Form=が; Pos=格助詞; Read=ガ}, @{SentenceNum=3; Form=に; Pos=格助詞; Read=ニ}, @{SentenceNum=3; Form=を; Pos=格助詞; Read=ヲ}, @{SentenceNum=3; Form=として; Pos=格助詞; Read=トシテ}} 4 動詞語幹 {@{SentenceNum=2; Form=あ; Pos=動詞語幹; Read=ア}, @{SentenceNum=3; Form=基づ; Pos=動詞語幹; Read=モトヅ}, @{SentenceNum=3; Form=お; Pos=動詞語幹; Read=オ}, @{SentenceNum=3; Form=い; Pos=動詞語幹; Read... 3 動詞活用語尾 {@{SentenceNum=0; Form=し; Pos=動詞活用語尾; Read=シ}, @{SentenceNum=3; Form=い; Pos=動詞活用語尾; Read=イ}, @{SentenceNum=3; Form=さ; Pos=動詞活用語尾; Read=サ}} 3 句点 {@{SentenceNum=2; Form=。; Pos=句点; Read=$}, @{SentenceNum=3; Form=.; Pos=句点; Read=$}, @{SentenceNum=3; Form=。; Pos=句点; Read=$}} 2 読点 {@{SentenceNum=0; Form=、; Pos=読点; Read=$}, @{SentenceNum=3; Form=、; Pos=読点; Read=$}} 2 判定詞 {@{SentenceNum=0; Form=な; Pos=判定詞; Read=ナ}, @{SentenceNum=2; Form=で; Pos=判定詞; Read=デ}} 2 括弧 {@{SentenceNum=1; Form=(; Pos=括弧; Read=$}, @{SentenceNum=1; Form=); Pos=括弧; Read=$}} 1 連用助詞 {@{SentenceNum=0; Form=は; Pos=連用助詞; Read=ハ}} 1 Alphabet {@{SentenceNum=1; Form=CLI; Pos=Alphabet; Read=シーエルアイ}} 1 連体詞 {@{SentenceNum=2; Form=および; Pos=連体詞; Read=オヨビ}} 1 Number {@{SentenceNum=3; Form=2.0; Pos=Number; Read=ニテンゼロ}}
まとめ
(レスポンスのエンコーディングのところは予定外でしたが、)
Invoke-RestMethod
あるいはInvoke-WebRequest
コマンドレット1つでWeb APIを試すことが出来ました。
返却されるJSON(やXML)のデータも直ぐにオブジェクトとして扱うことが出来るのも良いですね。
皆さんも、気になるWeb API がありましたら、PowerShellでお試ししてみましょう!