Watson NLUのClassification Modelのトレーニングをやってみる

昨日、IBM WatsonのNatural Language Classifier(NLC)の廃止が発表されたことを書きました。

IBMの公式見解では、NLCの廃止後はNatural Language Understanding(NLU)のカスタムモデルを使えば代替できるということです。

NLCとNLUの違い

NLCは由緒あるサービスで、IBM Watsonのクラウドサービスとしての登場時から存在します。一方、NLUは私の書いた書籍では、2016年の「初めてのWatson」の頃は登場しておらず、2017年の「ワトソンで体感する人工知能」の時にもなくて、2018年に「初めてのWatson 改訂版」を出した時に初めて紹介したのでした。

NLCはその名のとおり自然言語を分類するためのカスタムモデルを作成するサービス(プレビルドモデルは存在しない)である一方、NLUは自然言語からキーワードや評判、カテゴリといった要素を抽出するサービスで、そのためにプレビルドモデルが提供されており、独自のトレーニングは不要という違いがありました。

それが、NLUでカスタムモデルを作成する機能が提供されるようになり、独自のラベルで分類するモデルも作成可能となったため、NLCを代替できるという判断になったものと思います。

NLUのトレーニングを試す(Curl)

NLUのカスタムモデルは、NLCの代替となる分類モデルだけでなく、下記のモデルを作成することが可能です。

  • カスタムエンティティ、カスタムリレーション(Watson Knowledge Studioを使用)
  • カスタムセンチメント
  • カスタムカテゴリー
  • カスタム分類 ← NLCの代替

ここでは、カスタム分類についてモデルを作成してみます。

トレーニングデータは、リファレンスによればJSON形式のほか、NLCと同様のCSV形式も使用可能です。

JSON形式は下記のようなものです。(リファレンスから引用)

[
    {
        "text": "Example 1",
        "labels": ["label1"]
    },
    {
        "text": "Example 2",
        "labels": ["label1", "label2"]
    }
]

ここでは、NLCからの移行を念頭にNLCのトレーニングで用いていた、下記のCSV形式のデータを使います。

ログインできない,login
ユーザIDが分からない,login
ユーザIDを忘れた,login
アカウントを忘れた,login
パスワードが分からない,login
パスワードを忘れた,login
サービスにアクセスできない,login
どうしたらログインできますか,login
アクセスの方法を教えてください,login
サービスが使えない,login
ユーザ登録したい,register
登録の方法を教えてください,register
入会したい,register
入会の方法を教えて,register
契約したい,register
会員になりたい,register
アカウントを作りたい,register
アカウントの登録方法を知りたい,register
どうしたら使えるようになりますか,register
サービスを使えるようにしたい,register

まず、トレーニングをCurlでやってみましょう。
CSVを使用する場合は、typeとしてtext/csvを指定することがポイントです。

curl -X POST -u "apikey:{apikey}" -H "Content-Type: multipart/form-data" -F "name=MyClassificationModel" -F "language=ja" -F "training_data=@nlc_training.csv;type=text/csv" https://api.us-south.natural-language-understanding.watson.cloud.ibm.com/v1/models/classifications?version=2021-03-23

このようなレスポンスが返ってきます。model_idがセットされていますね。

{"name":"MyClassificationModel","user_metadata":null,"language":"ja","description":null,"model_version":null,"version":null,"workspace_id":null,"version_description":null,"status":"starting","notices":[],"model_id":"44fa46b5-100c-4618-b40e-5b892a6b2292","features":["classifications"],"created":"2021-08-10T12:57:47Z","last_trained":"2021-08-10T12:57:47Z","last_deployed":null}

モデルの詳細は下記のように取得できます。トレーニング状況の照会ができます。

curl -X GET -u "apikey:{apikey}" https://api.us-south.natural-language-understanding.watson.cloud.ibm.com/v1/models/classifications/44fa46b5-100c-4618-b40e-5b892a6b2292?version=2021-03-23

レスポンスは下記のようなものです。

{"name":"MyClassificationModel","user_metadata":null,"language":"ja","description":null,"model_version":null,"version":null,"workspace_id":null,"version_description":null,"status":"available","notices":[],"model_id":"44fa46b5-100c-4618-b40e-5b892a6b2292","features":["classifications"],"created":"2021-08-10T12:57:47Z","last_trained":"2021-08-10T12:57:47Z","last_deployed":"2021-08-10T13:05:10Z"}

トレーニングにPythonを使う

Python SDKを使用する場合は、下記のようになります。レスポンスはCurlの場合と同様のため、省略します。

まずはトレーニング。指定しているパラメータはCurlの場合と同様ですね。

from os.path import join, dirname
from ibm_watson import NaturalLanguageUnderstandingV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

authenticator = IAMAuthenticator('{apikey}')
nlu = NaturalLanguageUnderstandingV1(
    version='2021-03-25',
    authenticator=authenticator
)

nlu.set_service_url('https://api.us-south.natural-language-understanding.watson.cloud.ibm.com')

with open(join('nlc_training.csv'), 'rb') as file:
    model = nlu.create_classifications_model(
        language='ja',
        training_data=file,
        training_data_content_type='text/csv',
        name='MyClassificationsModel',
    ).get_result()
model

モデルのリストは下記のように取得します。

nlu.list_classifications_models().get_result()

モデルの詳細情報は下記のように取得します。

nlu.get_classifications_model('44fa46b5-100c-4618-b40e-5b892a6b2292').get_result()

ちなみに、NLUのライトプランではカスタムモデルは1つまでしか作成できません。そのため、下記のように削除しながら試してみると良いでしょう。

nlu.delete_classifications_model('d03364ed-8ba2-4ab1-9f5b-a48129273eb2').get_result()

NLUからカスタム分類モデルを使用した結果を取得する

NLUはさまざまな種類の情報抽出を行うことができるため、features引数に抽出したい項目を指定(複数の指定も可能)します。カスタム分類モデルを使用する場合はclassifications引数にClassificationsOptionsクラスのインスタンスを指定し、そこでカスタム分類モデルのIDをセットします。

from ibm_watson.natural_language_understanding_v1 import Features, ClassificationsOptions

nlu.analyze(
    text='ログインできない', 
    language='ja', 
    features=Features(classifications=ClassificationsOptions(model='44fa46b5-100c-4618-b40e-5b892a6b2292'))
).get_result()

このような結果が得られました。

{'usage': {'text_units': 1, 'text_characters': 8, 'features': 1},
 'language': 'ja',
 'classifications': [{'confidence': 0.95398, 'class_name': 'login'},
  {'confidence': 0.04467, 'class_name': 'register'}]}

classificationsのところで、ラベル(class)ごとの確信度(confidence)が表示されています。確信度が最も高いラベルを分類結果として用いることになります。

このように、NLCのトレーニングデータを用いて、NLUのカスタム分類モデルを作成することができました。
おそらく内部のトレーニングアルゴリズムが異なるので、同じトレーニングデータならNLCとまったく同じ結果になる・・・ということはないと思いますが、機能としては充分、代替可能なのではないでしょうか。

この記事を書いた人

井上 研一

株式会社ビビンコ代表取締役、ITエンジニア/経済産業省推進資格ITコーディネータ。AI・IoTに強いITコーディネータとして活動。2018年、株式会社ビビンコを北九州市に創業。IoTソリューションの開発・導入や、画像認識モデルを活用したアプリの開発などを行っている。近著に「使ってわかった AWSのAI」、「ワトソンで体感する人工知能」。日本全国でセミナー・研修講師としての登壇も多数。