IBM Cloud FunctionからNLUを呼び出す


はじめに

IBM Cloud Functionシリーズの続きです。
前の記事IBM Cloud FunctionからWatson MLのWebサービスを呼び出すを書いている時に気付いたのですが、IBM Cloud FunctionのActionでは、bxコマンドでサービスとバインドしておくと、認証情報を簡単に取れます。
この仕組みを使って、NLUのエンティティ抽出を行うサービスを作ってみました。

サービスの作成

IBM Cloudのダッシュボードから「Functions」を選択します。

下の画面が表示されたら「作成の開始」をクリックします。

次の画面では「Create Action」をクリック。

下の画面が出たら、
Action Name: nlu-servce
Runtime: Python 3
を入力して「Create」をクリック。

コード編集画面が出たら、コードの中身を下記のものに置き換えて下さい。
置き換えが終わったら、「Save」をクリックします。

#
#
# main() will be run when you invoke this action
#
# @param Cloud Functions actions accept a single parameter, which must be a JSON object.
#
# @return The output of this action, which must be a JSON object.
#
#
import sys
import json
from watson_developer_cloud import NaturalLanguageUnderstandingV1
from watson_developer_cloud.natural_language_understanding_v1 \
  import Features, EntitiesOptions, KeywordsOptions, ConceptsOptions, CategoriesOptions, RelationsOptions, SentimentOptions

def main(dict):
    # 解析対象文
    text = dict['text']

    # 認証情報の取得
    creds = dict['__bx_creds']['natural-language-understanding']
    #print(creds)
    username = creds['username']
    password = creds['password']

    # NLUクライアントインスタンス生成

    natural_language_understanding = NaturalLanguageUnderstandingV1(
        username = username,
        password = password,
        version='2018-03-16')

    # NLU呼出し
    response = natural_language_understanding.analyze( text = text, features = Features(
        #relations = RelationsOptions()
        entities = EntitiesOptions(),
        #concepts = ConceptsOptions(),
        #keywords = KeywordsOptions(),
        #sentiment = SentimentOptions(),
        #categories = CategoriesOptions()
    ))

    # 結果解析
    entities = response['entities']
    person = ''
    company = ''
    location = ''
    for item in entities:
        if item['type'] == 'Organization':
            company = item['text']
        if item['type'] == 'Person':
            person = item['text']
        if item['type'] == 'Location':
            location = item['text']

    return { 'person': person, 'company': company, 'location': location }

Cloud Functionプラグインの導入

Cloud Functionプラグインの導入がまだの場合(bx wskコマンドが使えない)は、下記リンクからプラグインの導入を行います。
Cloud Functionプラグイン

サービスのバインド

次にNLUサービスと、今作ったCloud FunctionのActionとのバインドを行います。
これを行うことにより上記コードのうち、

    creds = dict['__bx_creds']['natural-language-understanding']
    username = creds['username']
    password = creds['password']

の部分でNLUの認証情報を取得できるようになります。

まず、次のコマンドで作成したFunctionサービスの名称を確認します。
/<org_name>_<space_name>/nlu-serviceというactionが存在するはずです。

$ bx login
$ bx wsk action list

次のコマンドで、Watson NLUサービスとバインドします。

$ bx wsk service bind natural-language-understanding nlu-service

複数のNLUサービスがある場合は、以下のようにインスタンス名もオプションで追加します。

$ bx wsk service bind natural-language-understanding nlu-service --instance <instance_name>

正常にバインドされているかどうかは、次のコマンドでわかります。

bx wsk action get nlu-service

バインドされている場合、usernameやpasswordなどの情報も、__bx_credsの配下に設定されています。

パラメータの設定

Cloud Functionサービスが解析対象パラメータ(text)を受け取れるようにします。
また、テスト用にパラメータのデフォルト値も設定します。

Cloud Functionの管理画面から「アクション」->「nlu-service」を選択し、先ほど作ったCloud Functionの詳細画面を表示します。

メニューから「Parameters」を選択し、「Add」をクリックして、以下のパラメータtextとデフォルト値を設定します。
textのデフォルト値はテスト用の解析対象テキストです。なんでもいいのですが、私は下のような自己紹介文を設定しました。デフォルト値に文字列を設定する場合、ダブルクオートで囲む必要がありますので、注意して下さい。

"はじめまして。私は日本アイ・ビー・エムの山田花子です。私は大阪から来ました。"

これで準備完了です。コードのタブに戻って「invoke」をクリックします。

うまくいくと下のような結果がかえってくるはずです。
EntityとしてCompany(「日本アイ・ビー・エム」)、Person(「山田花子」)、Location(「大阪」)が取れているのがわかると思います。

うまくいかない場合は、Pythonのソースに適宜print文を入れてデバッグして下さい。
コードを修正した場合、bx wsk service bind文は再発行する必要がありますので、その点を注意して下さい。