まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:migration

Google Apps の無料運用が終わることになり、これまで運用してきた独自ドメインのメールアカウントをどこかへ移行する必要が生じました。

いくつかの移行先候補の中で、「無料で」続けることができる数少ない選択肢が Zoho メール だと思っています。というわけで、Google Apps からの移行を視野に入れて、Zoho メールで独自ドメインのメールアカウントを運用する方法を調べました(ちなみに以下のスクリーンショットを撮った時には FireFox を使っています):
2022030500


【Zoho メールとは】
個人や小規模組織を対象に無料のメール環境を提供しています。GMail 同様、個人でも @zohomail.jp ドメインのメールアカウントを取得することもできますが、今回は独自ドメインでメールを運用できる点に絞って紹介します。なお無料で Zoho の独自ドメインメールを運用する場合の条件は以下のようになります:
・最大5ユーザー
・1ユーザーあたり 5GB のメール容量
・添付ファイルは最大 25MB まで
・Webメールとモバイルアプリのみ(POP3/IMAPなし)



【Zoho メールを独自ドメインで利用するまでの手順】
以下に実際に自分が所有しているドメイン(yellowmix.net)で利用できるようにするまでの手続きの様子を紹介します。Zoho は Zoho Japan が日本人向けのサービスも提供していますが、この Zoho メールの手続きは途中から英語のみになるので、その点にご注意ください。

まずは Zoho メールのトップページへ行き、「広告表示なしメールの使用を開始する」と書かれた箇所で「メールアドレス」を選んで「無料プランに登録する」ボタンを選択します:
2022030501


※ちなみにここで「個人向け」を選ぶと、@zohomail.jp ドメインの無料メールアカウントを取得できます。

このような画面が表示されます。この辺りは有料サービスなので下にスクロールします:
2022030502


「永久に無料のプラン」と書かれたサービスの「無料お試し登録」をクリックします:
2022030503


次の画面では新たに申し込むアカウントの設定に利用する氏名とメールアドレス(今回申し込むメールアドレスのドメインとは別のもの)、そしてパスワードを入力します(既にそのメールアドレスで Zoho のアカウントを取得している場合はログインします)。最後に「登録する」ボタンをクリックします:
2022030501


Zoho メールの設定ウィザードがスタートします。まずはドメインを追加します。今回は既に所有済みのドメインを利用するため「既存のドメインを追加する」「今すぐ追加する」ボタンをクリックします:
2022030502


以下のようなダイアログが表示されるので、登録するドメイン名(www. が表示されているので、そこに続けてドメイン名を入力)、組織名、そして組織の分類(自分は IT を選びました)を指定して「追加する」を選択します:
2022030503


すると次のような画面になり、ドメインの追加ができました。ただ本当にこのドメインを所有しているかどうかを確認する必要があります。続けて「ドメイン認証に進む」をクリックします:
2022030501


ドメインの所有権を認証する画面が表示されます。ここから先はドメインを取得したプロバイダーによって作業内容が変わると思いますが、自分の場合は GoDaddy.com でこのドメインを取得しており、GoDaddy.com の場合は左の「自分の DNS にログインする」を選ぶことで先にすすめることができました。以下、この方法を選んだ場合として説明を続けます:
2022030501


「自分の DNS にログインする」を選択すると DNS プロバイダー(自分の場合は GoDaddy.com)へのログイン認証が行われるので、該当プロバイダーへログインする ID とパスワードを入力してサインインします:
2022030502


正しくサインインできると、Zoho Mail Hosting を有効にする許可を与えるかどうかの確認画面になります。内容を確認して「接続」をクリックします:
2022030503


すると元の画面に戻り、「ドメインの所有者が確認されました」のメッセージが表示されます。これで指定したドメインを本当に自分が取得していることを証明できました。

続けてこのドメインでのユーザーを作成します。

"Your login mail address" と書かれたテキストフィールドに作成するメールアドレスを入力(@yellowmix.net は入力済みなので、その前の部分を入力)して、「作成する」をクリックします:
2022030501


すると以下のような画面が表示され、ユーザーが追加されたことが確認できます。必要に応じてここで「追加する」を選択して、このドメインのメールユーザーを(無料プランであれば最大5ユーザーまで)追加できます。ユーザーの追加が完了したら「グループの設定に進む」をクリックします:
2022030501


グループはユーザーが共有して利用することができるメールアドレスです。必要に応じて「作成する」からグループを作成してください(不要であれば作る必要はありません)。次に進む場合は「DNSの関連付けに進む」をクリックします:
2022030502


次に MX レコードなどのメール用 DNS 設定を行います。が、この前の手続きでドメイン認証が済んでいれば「MX、SPF、DKIM を自動で設定できます」ボタンをクリックするだけです:
2022030503


続いてデータ移行の画面になります。既存メール環境からのデータ移行ができるようですが、今回の自分の場合は新規のメール環境登録なので既存メール環境がありません。ここは何もせずに次の「モバイル設定に進む」を選択しました。ここは実際に試した人からの情報があればいただきたいです:
2022030501


スマホからこのメールを使うための設定画面です。といっても実際にはモバイルアプリへのリンクがあるだけのページでした。必要であればこのページのリンクから Zoho メールのモバイルアプリをダウンロード&インストールしてください。最後に「設定の完了に進む」をクリックします:
2022030502


※上のリンクをクリックするとこのような画面になって、モバイルアプリのダウンロードができるようです:
2022030503


これで全ての設定が完了しました。「受信トレイを確認してください」をクリックします:
2022030501


新しいメール環境が確認できるようになりました。が、改めて最初からのアクセス方法を確認するため、一旦ログアウトしましょう。右上のアイコンをクリックします:
2022030502


そして「サインアウトする」を選択して、サインアウトします:
2022030503



では改めて Zoho メールに作成した独自ドメインのユーザーでログインしてメールを使ってみます。まずは Zoho メールのトップページにアクセスします:
https://www.zoho.com/jp/mail/


そして右上の「サインイン」をクリックします:
2022030501


先程登録した独自ドメインのユーザー名とパスワードでサインインします:
2022030502


初回ログイン時には2段階認証を有効にするよう注意画面が表示されます。必要に応じてここで2段階認証を有効にしてください(後から設定することも可能です)。ここでは一旦「後で確認する」をクリックして先に進みます:
2022030501


これで Zoho メールを送受信できる画面に移動できました!安全のため2段階認証も有効にしておきましょう:
2022030501



以上、独自ドメインを Zoho メールで運用する場合の設定手順を紹介しました。1ドメインあたり5ユーザーまで、というのが個人的にはちと厳しい気もするのですが、Google Apps 亡き今となっては無料で独自ドメインメール運用ができる環境の選択肢そのものが少なく、無料となると(格安のはいくつかありますが)個人的にはここしか知りません。この5ユーザーの範囲内でうまく使っていけると、Google Apps 難民にとっても有用な移行先であるように思えました。


IBM Watson から提供されている AI 系 API の中で、自然言語テキストを分類する機能を持った NLC(Natural Language Classifier) の提供が終了することがアナウンスされました。2021年9月9日までは新規インスタンスの作成が可能ですが、それ以降の新規作成はできません。また既存インスタンスは2022年8月8日まで利用できますが、それまでに移行先を決め、その移行作業を済ませておく必要があります:
https://cloud.ibm.com/docs/natural-language-classifier?topic=natural-language-classifier-migrating


NLC は個人的にも IBM Watson を使い始めるきっかけになった API で、思い入れの深いサービスだったりします。NLC を使って作った多くのデモアプリは WordCamp Tokyo や特定のお客様向けに作ったものを含めて多くの場で紹介させていただきました。感慨深いものがあります。


上記アナウンス内で、公式な移行先として同じ IBM Watson の NLU(Natural Language Understandings) が紹介されています。が、具体的な移行手順や方法に関する情報が少ないこともあり、実際に自分が NLC API を使って開発したアプリケーションをどのように NLU に移行すればよいかがわかりにくいように感じました。 自分自身の場合は普段 Node.js を使ってアプリケーションを開発しているのですが、Node.js の場合は具体的にどのようにすれば NLC から NLU へ移行できるか? という調査をしてみました。実際に Node.js でプログラムを書き、具体的にはまず NLC API を使って、
 ・認証
 ・日本語データ学習
 ・学習状況確認
 ・問い合わせ(分類)
 ・学習の削除
といった5種類のオペレーションを行えるようなアプリケーションを作りました。 そしてそのアプリケーションを NLC から NLU へ実際に移植する、といった作業を行ってみました。結論として上記5種類のオペレーションは NLU でも NLC 同様に行うことができました。ただ API には互換性はなく、ソースコードレベルではそれなりに変更が必要になるため、どの程度の変更が必要になるのか、という調査の意味も含めて作業した様子を以下に紹介します。

なお、NLC は IBM Cloud の(無料版の)ライトアカウント向けには提供されていない API である点に注意してください。ライトアカウントの状態で NLC の新規インスタンスを作成することは(9月9日以前であっても)できません。ベーシック以上の(有償の)アカウントであれば無料枠含めて提供されている API です。 一方の NLU はライトアカウントでも利用することが可能ですが、ライトアカウントの場合はライトプラン(無料)の NLU を1インスタンスのみ作成でき、1インスタンスにつき1モデルだけ学習で作成できます(要は複数の学習モデルを作成するにはベーシック以上のアカウントで、有料プランを選択する必要があります)。
2021082200



【サンプルコードのダウンロード】
以下で紹介する一連の手順を行うための Node.js 用サンプルコードを作って公開しました:
https://github.com/dotnsf/nlc2nlu

git clone するかコードをダウンロード&展開してください。以下の3つのフォルダが含まれています:
|- csvtool
|- nlc
|- nlu

csvtool は実際に NLC や NLU で使うサンプルの学習データを作成するツールです。NLC や NLU を既に使っていて、どのような学習データを用意すればよいかわかっている場合は、ご自身で学習データ(CSV ファイル)を用意いただいてもかまいませんが、そうでない人向けに Yahoo! ニュースの RSS(https://news.yahoo.co.jp/rss) を使って、その場で学習データを作成できるようにしたものです。

nlc と nlu は名前の通りで、学習データを学習させて、学習状況を確認しながら学習が完了したら、実際に適当な日本語テキストを送信して、学習データに基づくテキスト分類を実施します。また実施後に学習データを削除する、といった操作も可能です。これらの内容を NLC および NLU それぞれで行えるようにしたツールが含まれています。

ではそれぞれのフォルダの使い方を説明します。


【csvtool : 学習データの用意】
csvtool/csvgenerator.jsYahoo! ニュース RSS から学習データとしての CSV ファイルを作成します。NLC / NLU とも学習データは以下のフォーマットの CSV ファイルを用意します※:
テキスト,このテキストが属するカテゴリー
テキスト,このテキストが属するカテゴリー
テキスト,このテキストが属するカテゴリー
  :

※ NLU は JSON フォーマットでも学習データを準備して読み込むことが可能ですが、NLC からの移植を考えると NLC と同じ条件で学習データを用意するべきと考え、同じ CSV ファイルを学習データとして使うことにします。

このような(NLC 向けの)学習データを既にお持ちであればそれを使って後述の作業を続けていただいてもかまいませんが、多くの人はそのような学習データを持っていないと思うので、新たに用意することにします。その場合は csvtool/csvgenerator.js を使います。

実行方法は単純で、csvtool フォルダに移動し、まず普通に $ npm install を実行して依存ライブラリを導入します:
$ cd csvtool

$ npm install

その後、node コマンドでこのファイルを実行します。実行コマンドの最後に出力先 CSV ファイル名を指定します(以下の例だと同一フォルダ内の csvfile.csv):
$ node csvgenerator csvfile.csv

実行したタイミングで Yahoo! ニュースの RSS を参照して、その時点のニュースを取得して CSV ファイルに書き出します。なお、このツールでは「経済」、「IT」、「エンタメ」、「科学」、「スポーツ」の5つのカテゴリーのニュースを収集します。 ツールの実行が完了すると、指定した CSV ファイルが以下のような内容で生成されます:
RSS から取り出したニュース内容,このニュースのカテゴリー
RSS から取り出したニュース内容,このニュースのカテゴリー
RSS から取り出したニュース内容,このニュースのカテゴリー
   :

ここまでできれば学習データの準備は完了です。ではこのデータを NLC と NLU それぞれで学習させて問い合わせる、という作業をこれ以降で行っていきましょう。


【nlc : NLC で操作】
まずは NLC API を使って開発したアプリでこのデータを学習させ、NLC API を使って問い合わせを行ってみましょう。先ほどダウンロードしたソースコードの nlc フォルダ内にある nlc/nlc.js ファイルを使って操作します(このコードの内容については後述します)。まずは csvgenerator.js の時と同様に  $ npm install を実行して依存ライブラリを導入します:
$ cd nlc

$ npm install

その後、node コマンドでこのファイルを実行します。この nlc.js はコマンドラインアプリケーションで、その実行時パラメータによって「データ学習」、「学習状況確認」、「問い合わせ(分類)」、「学習データ削除」の4つを行うことができます:
$ node nlc create [csvfilename]  ・・・データ学習

$ node nlc status  ・・・学習状況確認

$ node nlc classify [日本語テキスト] [classifier_id]  ・・・問い合わせ(分類)

$ node nlc delete [classifier_id]  ・・・学習データ削除

では実際に nlc ツールを使いながら操作を確認してみましょう。まずは IBM Cloud にウェブブラウザでログインして、NLC インスタンスを作成し、「サービス資格情報」(を必要であれば作成して)の内容を確認します:
2021082201


この中に apikey 属性値と url 属性値が含まれているので、それらの値を nlc/settings.js ファイル内の exports.nlc_apiKey 値および exports.nlc_url 値にそれぞれコピーして保存します:
exports.nlc_apiKey = 'サービス資格情報内の apikey 属性値';
exports.nlc_url = 'サービス資格情報内の url 属性値';
exports.nlc_name = 'nlc2nlu';
exports.nlc_language = 'ja';

これで実行前の準備は完了しました。早速「データ学習」を実行してみます。「データ学習」は(前述の作業で用意した)学習データ CSV ファイルを指定して、$ node nlc create [csvfilename] を実行します。先ほどの手順で ../csvtool/csvfile.csv というファイルが作られている場合は以下のように指定して実行します:
$ node nlc create ../csvtool/csvfile.csv

これで指定した CSV ファイルを元にする学習が開始されます。この学習が完了すると問い合わせ(分類)ができるようになりますが、完了しているかどうかを確認するには以下のコマンドを実行します:
$ node nlc status

実行結果は以下のような JSON が表示されますが、この中の status 欄が "available" となっていれば学習は完了しています(データ量にもよりますが、自分が試した時はこうなるまでおよそ 10 分程度かかりました)。同時に表示されている classifier_id の値はこの後で使うので合わせてメモしておきましょう:
{
  "status": 200,
  "statusText": "OK",
  "headers": {
    "content-type": "application/json",
    "x-xss-protection": "1",
    "content-security-policy": "default-src 'none'",
    "x-content-type-options": "nosniff",
    "cache-control": "no-cache, no-store",
    "pragma": "no-cache",
    "expires": "0",
    "content-length": "428",
    "strict-transport-security": "max-age=31536000; includeSubDomains;",
    "x-dp-watson-tran-id": "e6168d25-5640-4790-a1f1-02ff089dd869",
    "x-request-id": "e6168d25-5640-4790-a1f1-02ff089dd869",
    "x-global-transaction-id": "e6168d25-5640-4790-a1f1-02ff089dd869",
    "server": "watson-gateway",
    "x-edgeconnect-midmile-rtt": "7",
    "x-edgeconnect-origin-mex-latency": "22",
    "date": "Tue, 24 Aug 2021 05:48:32 GMT",
    "connection": "close"
  },
  "result": {
    "classifier_id": "e87efex297-nlc-650",
    "name": "nlc2nlu",
    "language": "ja",
    "created": "2021-08-24T05:45:20.090Z",
    "url": "https://api.jp-tok.natural-language-classifier.watson.cloud.ibm.com/instances/f738a110-248b-419c-b771-8e6cbd45ee93/v1/classifiers/e87efex297-nlc-650",
    "status_description": "The classifier instance is now available and is ready to take classifier requests.",
    "status": "Available"
  }
}


学習が完了したら改めて日本語テキストを指定して、その内容がどのカテゴリーに属しているのかを分類してみましょう。日本語テキストと上述で確認した classifier_id 値を指定して、以下のようなコマンドを実行します:
$ node nlc classify [日本語テキスト] [classifier_id]

すると以下のような結果が表示されます。指定した日本語テキスト(「パッキャオがんばれ」)を学習データに含まれていたカテゴリー(今回作ったものだと「経済」、「IT」、「エンタメ」、「科学」、「スポーツ」)のどれに相当するものかを識別して、その可能性の高い順に結果を返しています。この例では「スポーツ」の可能性が 50% 強である、と判断されているようです:
$ node nlc classify パッキャオがんばれ e87efex297-nlc-650
{ "status": 200, "statusText": "OK", "headers": { "content-type": "application/json", "x-xss-protection": "1", "content-security-policy": "default-src 'none'", "x-content-type-options": "nosniff", "cache-control": "no-cache, no-store", "pragma": "no-cache", "expires": "0", "content-length": "679", "strict-transport-security": "max-age=31536000; includeSubDomains;", "x-dp-watson-tran-id": "102350df-e1d0-4568-ae10-6e72ba1b44b0", "x-request-id": "102350df-e1d0-4568-ae10-6e72ba1b44b0", "x-global-transaction-id": "102350df-e1d0-4568-ae10-6e72ba1b44b0", "server": "watson-gateway", "x-edgeconnect-midmile-rtt": "7", "x-edgeconnect-origin-mex-latency": "43", "date": "Tue, 24 Aug 2021 05:51:22 GMT", "connection": "close" }, "result": { "classifier_id": "e87efex297-nlc-650", "url": "https://api.jp-tok.natural-language-classifier.watson.cloud.ibm.com/instances/f738a110-248b-419c-b771-8e6cbd45ee93/v1/classifiers/e87efex297-nlc-650", "text": "パッキャオがんばれ", "top_class": "スポーツ", "classes": [ { "class_name": "スポーツ", "confidence": 0.5022989563107099 }, { "class_name": "エンタメ", "confidence": 0.20692538301831817 }, { "class_name": "経済", "confidence": 0.1200947580342344 }, { "class_name": "科学", "confidence": 0.11456564859743573 }, { "class_name": "IT", "confidence": 0.05611525403930185 } ] } }


作成した学習データを IBM Watson NLC から削除するには以下のコマンドを実行します:
$ node nlc delete [classifier_id]

ここまでのオペレーションで「データ学習」、「学習状況確認」、「問い合わせ(分類)」、「学習データ削除」の4つを NLC API を使って実現し、そのアプリケーションを実行する方法を紹介しました。


【nlu : NLU で操作】
では改めてこの nlc アプリケーションを NLU API で作り直し、同じ4つのオペレーションができることを確認してみます。先ほどダウンロードしたソースコードの nlu フォルダ内にある nlu/nlu.js ファイルを使って操作します(このコードの内容については後述します)。まずは csvgenerator.js の時と同様に  $ npm install を実行して依存ライブラリを導入します:
$ cd nlc

$ npm install

その後、node コマンドでこのファイルを実行します。この nlu.js もコマンドラインアプリケーションで、その実行時パラメータによって「データ学習」、「学習状況確認」、「問い合わせ(分類)」、「学習データ削除」の4つを行うことができます:
$ node nlu create [csvfilename]  ・・・データ学習

$ node nlu status  ・・・学習状況確認

$ node nlu analyze [日本語テキスト] [model_id]  ・・・問い合わせ(分類)

$ node nlu delete [model_id]  ・・・学習データ削除

※前述の NLC では問い合わせ時に "classify(分類)" という命令を指定していましたが、NLU では同じ作業を "analyze(解析)" と表現しているようです。またパラメータとして指定する ID も NLC では "classifier_id(分類ID)" だったのですが、NLU では "model_id(モデルID)" という表現になっていました。

では実際に nlu ツールを使いながら操作を確認してみましょう。まずは IBM Cloud にウェブブラウザでログインして、NLU インスタンスを作成し、「サービス資格情報」(を必要であれば作成して)の内容を確認します:
2021082401


この中に apikey 属性値と url 属性値が含まれているので、それらの値を nlu/settings.js ファイル内の exports.nlc_apiKey 値および exports.nlc_url 値にそれぞれコピーして保存します:
exports.nlu_apiKey = 'サービス資格情報内の apikey 属性値';
exports.nlu_url = 'サービス資格情報内の url 属性値';
exports.nlu_name = 'nlc2nlu';
exports.nlu_language = 'ja';

これで実行前の準備は完了しました。早速「データ学習」を実行してみます。「データ学習」は(前述の作業で用意した)学習データ CSV ファイルを指定して、$ node nlu create [csvfilename] を実行します。先ほどの手順で ../csvtool/csvfile.csv というファイルが作られている場合は以下のように指定して実行します:
$ node nlu create ../csvtool/csvfile.csv

これで指定した CSV ファイルを元にする学習が開始されます。この学習が完了すると問い合わせ(分類)ができるようになりますが、完了しているかどうかを確認するには以下のコマンドを実行します:
$ node nlu status

実行結果は以下のような JSON が表示されますが、この中の status 欄が "available" となっていれば学習は完了しています。同時に表示されている model_id の値はこの後で使うので合わせてメモしておきましょう。この辺りまでは前述の NLC の時とほぼ同様ですね:
{
  "status": 200,
  "statusText": "OK",
  "headers": {
    "x-powered-by": "Express",
    "content-type": "application/json; charset=utf-8",
    "content-length": "401",
    "etag": "W/\"191-CBnewThU0u/CjNzD01hil1wp9qo\"",
    "strict-transport-security": "max-age=31536000; includeSubDomains;",
    "x-dp-watson-tran-id": "15b238e1-d074-438d-8de5-44fcdfc163de",
    "x-request-id": "15b238e1-d074-438d-8de5-44fcdfc163de",
    "x-global-transaction-id": "15b238e1-d074-438d-8de5-44fcdfc163de",
    "server": "watson-gateway",
    "x-edgeconnect-midmile-rtt": "7",
    "x-edgeconnect-origin-mex-latency": "228",
    "date": "Tue, 24 Aug 2021 05:54:08 GMT",
    "connection": "close"
  },
  "result": {
    "models": [
      {
        "name": "nlc2nlu",
        "user_metadata": null,
        "language": "ja",
        "description": null,
        "model_version": "1.0.0",
        "version": "1.0.0",
        "workspace_id": null,
        "version_description": null,
        "status": "available",
        "notices": [],
        "model_id": "619ad785-0b0c-4981-8217-bd51064896a3",
        "features": [
          "classifications"
        ],
        "created": "2021-08-24T05:43:32Z",
        "last_trained": "2021-08-24T05:43:32Z",
        "last_deployed": "2021-08-24T05:50:10Z"
      }
    ]
  }
}

学習が完了したら改めて日本語テキストを指定して、その内容がどのカテゴリーに属しているのかを分類してみましょう。NLC では "classify" と指定していた部分は NLU では "analyze" となる点に注意してください。日本語テキストと上述で確認した model_id 値を指定して、以下のようなコマンドを実行します:
$ node nlu analyze [日本語テキスト] [model_id]

すると以下のような結果が表示されます。指定した日本語テキストを学習データに含まれていたカテゴリー(今回作ったものだと「経済」、「IT」、「エンタメ」、「科学」、「スポーツ」)のどれに相当するものかを識別して、その可能性の高い順に結果を返しています。同じ学習データで同じ問い合わせをして、こちらでも「スポーツ」の可能性が高いと判定されていますが、その確率や2位以下の結果には違いがあることがわかります:
$ node nlu analyze パッキャオがんばれ 619ad785-0b0c-4981-8217-bd51064896a3

{
  "status": 200,
  "statusText": "OK",
  "headers": {
    "server": "watson-gateway",
    "content-length": "499",
    "content-type": "application/json; charset=utf-8",
    "cache-control": "no-cache, no-store",
    "x-dp-watson-tran-id": "93978bcf-c49e-41e9-ad00-7f0000a34e15, 93978bcf-c49e-41e9-ad00-7f0000a34e15",
    "content-security-policy": "default-src 'none'",
    "pragma": "no-cache",
    "x-content-type-options": "nosniff",
    "x-frame-options": "DENY",
    "x-xss-protection": "1; mode=block",
    "strict-transport-security": "max-age=31536000; includeSubDomains;",
    "x-request-id": "93978bcf-c49e-41e9-ad00-7f0000a34e15",
    "x-global-transaction-id": "93978bcf-c49e-41e9-ad00-7f0000a34e15",
    "x-edgeconnect-midmile-rtt": "10",
    "x-edgeconnect-origin-mex-latency": "354",
    "date": "Tue, 24 Aug 2021 05:56:16 GMT",
    "connection": "close"
  },
  "result": {
    "usage": {
      "text_units": 1,
      "text_characters": 9,
      "features": 1
    },
    "language": "ja",
    "classifications": [
      {
        "confidence": 0.402721,
        "class_name": "スポーツ"
      },
      {
        "confidence": 0.326038,
        "class_name": "経済"
      },
      {
        "confidence": 0.314985,
        "class_name": "IT"
      },
      {
        "confidence": 0.255796,
        "class_name": "エンタメ"
      },
      {
        "confidence": 0.21978,
        "class_name": "科学"
      }
    ]
  }
}


作成した学習データを IBM Watson NLU から削除するには以下のコマンドを実行します:
$ node nlu delete [model_id]

ここまでのオペレーションで NLC 同様に NLU でも「データ学習」、「学習状況確認」、「問い合わせ(分類)」、「学習データ削除」の4つを API で実現し、そのアプリケーションを実行する方法を紹介しました。とりあえず、この4つのオペレーションについては NLC から NLU へ移行することはできそうだ、という感触が持てる結果になりました。


【API レベルの移行作業】
同じオペレーションを行う NLC のツールと NLU のツールを実際に Node.js + IBM Watson SDK で開発してわかったことを記載しておきます。

まず API に互換性はありません。IAM を使った認証部分についてはほぼ同じなのですが、今回行った4つのオペレーションを実現するためのそれぞれの API は NLC のものと NLU のものは全く異なります:
NLC の関数 オペレーションの種類 NLU の関数
IamAuthenticator() 認証 IamAuthenticator()
createClassifier() 分類器/モデルの作成 createClassificationModel()
listClassifiers() 作成した分類器/モデルの参照 listClassificationModels()
classify() 分類/解析 analyze()
deleteClassifier() 分類器/モデルの削除 deleteClassificationModel()


パラメータの指定方法など、詳しくはソースコード(nlc/nlc.js / nlu/nlu.js)を参照していただきたいのですが、大まかには上記表のような関数の違いがあります。特に Node.js + IBM Watson SDK を使っているアプリケーションにおいて NLC から NLU へ移植する場合は、表の左列にある関数を使っている箇所を右列の関数に置き換える、というのが大まかな流れになると思います(実際にはパラメータの指定方法だったり、返り値のフォーマットの違いもあったりするので、単なる文字列置換というわけにはいかないと思います)。また NLC では「分類器(Classifier)」と呼んでいたものが NLU だと「分類モデル(ClassficationModel)」と呼び名が変わっていたりもするので、資料を参照する場合の注意も必要だと思います。

加えて、上記のように NLC を使って問い合わせた結果と NLU に移植後に問い合わせた結果は必ずしも同じ結果とはいきません。このあたりの整合性についても移植の前後で意識しておく必要があります。

とはいえ、少なくとも API のレベルで NLC から NLU へアプリケーションを移植することは不可能ではなさそう、という感触も得ることができました。主要なオペレーションに関しては上述の表を使って関数を新しいものに置き換え、実行結果のフォーマットの違いをプログラミング内で吸収することができれば、ある程度の実現目途は立ちそうだと思っています。


今回の NLC のサービス終了自体は残念ではありますが、一方で見方を変えると、これまで有償サービスでしか提供されていなかった NLC の機能が、無料のライトプランで使える NLU でも利用できるようになった、とも言えます。API レベルでの互換性はありませんが、機能的には珍しくこれまでの機能の多くが移植されていて、「アプリケーションの作り変え」による対応が可能なレベルでマイグレーションができるようになっていると感じました。「料金的にも発展的なサービス統合」であると感じています。


Node.js 以外の開発言語での場合や、IBM Watson SDK の利用有無の違いをどこまで吸収できるかまでを調査したわけではないのですが、一部の言語については後述の参考資料の中でサンプルコードもあるようなので、別環境においてもぜひ挑戦していただき、情報が共有されていくことを願っています。



【参考資料】
https://cloud.ibm.com/docs/natural-language-classifier?topic=natural-language-classifier-migrating

https://cloud.ibm.com/apidocs/natural-language-understanding?code=node


IBM Bluemix が提供するデータサービスの1つに "Data Connect" があります:
2017040401


このサービスは DB2, Oracle, dashDB, MySQL, cloudant, ・・・など、異なるデータベースサーバー間でのデータマイグレーションを実現するものです。マイグレーション元とマイグレーション先を定義し、相互システム間の型変換などを考慮してデータを扱い、(必要であれば)マイグレーションの実行スケジュールを指定することでデータのマイグレーション処理をその場で行ったり自動化したりする、というサービスです。更に必要に応じて Secure Gateway サービスを併用することで、クラウド上に公開されたデータベースだけでなく、オンプレミスデータベースを対象にすることも可能です。


今回は Data Connect の紹介例として、社内システムで運用中の MySQL データベースが存在していると仮定し、このデータベースの一部の内容(people テーブルの内容)を統計処理するために、クラウド上の dashDB に週に一度追加マイグレーションしたい、という要望があるものとして、この要望を実現するための設定を紹介します:
2017040402


こういった処理は JDBC などを使ってプログラミングすることも可能ですが、作成したアプリケーションを自動的に定期実行したり、同様のアプリケーションを作る際の流用性が少なかったりします。 そのような要望を一元的に管理・実現するためのサービスが Data Connect です:
2017040403


例えば上記のようなケースであれば、
(1) (マイグレーション元とマイグレーション先の2つの)データベースへの接続を定義し、
(2) データセット(マイグレーション元)を定義し、
(3) セータセットとマイグレーション先の2つの結びつきを定義し、
(4) マイグレーションの実行タイミングを定義して実行
することになります。 以下ではそれぞれの手順を実際の画面を使って紹介します。


まず IBM Bluemix で Data Connect サービスインスタンスを作成し、そのサービスインスタンスの画面を開くと、このように表示されます。画面内の "LAUNCH" ボタンをクリックすることで Data Connect サービスのダッシュボード画面に移動します:
2017040408


Data Connect のダッシュボード画面です。左上の "Data Connect" という箇所をクリックすると、いつでもこの画面に戻ってこれます:
2017040401


まずは上記 (1) の(マイグレーション元とマイグレーション先の)2つのデータベースへの接続方法を定義します。左メニューで "Connections" を選択します。現在は何も定義されていないので、画面には何も表示されないはずです。では画面右上の "Create Now" をクリックします:
2017040402


接続データベースの種類を選択する画面です。今回のケースではまずマイグレーション元となる MySQL の定義をするため、"MySQL" を選択します:
2017040403


次に MySQL の詳細情報を入力します。接続名、説明(オプション)、ホスト名、ポート番号、データベース名、Secure Gateway の利用有無、そしてユーザー名/パスワードを入力し、最後に右上の "Create Connection" をクリックします:
2017040404


(おまけ)
なお、もし対象とするデータベースサーバーがプライベートネットワーク環境内にある等、インターネットから直接参照できないような場合は、Bluemix の Secure Gateway サービスを併用します。Secure Gateway サービスがプライベートネットワーク環境とのセキュアなトンネリングを実現し、このトンネルを経由してプライベートネットワーク環境のデータベースを対象とすることができるようになります。なお Bluemix の Secure Gateway の利用手順については別途紹介したエントリがあるのでこちらを参照ください:
2017040503


Secure Gateway サービスを利用する場合の Connection 定義は以下のようにして行います。"Use a secure gateway" にチェックを入れ、設定済みの Secure Gateway 接続名を選択します。その上でデータベースサーバーのホスト名(IPアドレス)やポート番号は、プライベートネットワーク内でのものを指定します:
2017040504


なお、この Secure Gateway を使ってプライベートネットワーク内のデータベースに接続する場合ですが、データベース側はゲートウェイクライアント(または同一ネットワーク)から指定したユーザー名とパスワードで外部接続できるような設定をあらかじめ行っておく必要がある点に注意してください。例えばあるユーザーに同一ネットワーク(192.168.0.*)からの参照アクセスを許可する場合であれば以下のような MySQL コマンドを実行することになります:
> grant select on (データベース名).* to (ユーザー名)@"192.168.0.%" identified by '(パスワード)';

このコマンドの後でないと(外部からの接続ができないため)上記の接続定義が作成できないはずです。設定変更後に再度接続定義を行ってください。
(おまけ終わり)


接続定義の作成に成功すると1つ前の画面に戻り、いま作成した MySQL データベースへの接続情報アイコンが追加されていることが確認できるはずです。では続けてもう1つの(マイグレーション先の)接続情報を定義するため再度 "Create New" をクリックします:
2017040405


再び接続先データベースの種類を選択する画面です。今回は IBM dashDB に接続するので、"IBM dashDB" を選択します:
2017040406


データベースの種類によって入力する詳細項目が異なります。接続先が IBM dashDB の場合は接続名、説明(オプション)、ホスト名、データベース名、Secure Gateway の利用有無、そしてユーザー名/パスワードを入力し、最後に "Create Connection" をクリックします:
2017040407


先程の画面に戻り、今度は dashDB の接続情報アイコンが追加されたことが確認できるはずです。今回はこの2つの接続情報だけで充分ですが、マイグレーションで対象とする接続先の数だけこの作業を繰り返します(または後から追加します):
2017040408


次に (2) のマイグレーション元となるデータセットを定義します。今回は MySQL データベース内の people というテーブルの情報を dashDB にマイグレーションすることが目的なので、データセットは MySQL 内の people テーブルということになります。

このテーブルをデータセットとして定義するため、Data Connect ダッシュボードの左メニューから "Data Sets" を選択します。ここでも定義済みのデータセットがまだ存在していないので何も表示されません。では画面右上の "New Data Set" をクリックします:
2017040401


定義済みの接続情報名が(下画面では2つ)表示されます。今回は MySQL データベース内のデータを取り出したいので、MySQL の接続情報名を選択します:
2017040402


次にこのデータベース接続で対象とするデータベース名を指定します。今回は1つしか定義していないので、ただ1つ表示されるデータベースを選択しますが、複数ある場合は対象のものを選択します:
2017040403


次に対象となるテーブルやビューを選択します。今回は people テーブルを対象としたいので、"people" を選択します:
2017040404


必要であれば、このテーブルから取り出す列をカスタマイズします。全ての列を取り出す場合はデフォルトのまま全てにチェックを入れてください。最後に画面右上の "Publish Data Set" をクリック:
2017040405


すると1つ前の画面に戻り、データセット一覧に今作成した people テーブルが追加されたことが確認できます。これで (2) の作業も完了しました:
2017040406


続いて (3) データの結びつきと (4) マイグレーションスケジュールを定義します。今回の例では MySQL データベースの people データセットを dashDB データベースにマイグレーションしたいので、この関係を定義します。

改めてダッシュボード画面の左メニューから "Activities" を選択します。ここに定義済みのアクティビティ一覧が表示されますが、この時点ではまだ何も表示されていません。画面右上の "Create New" で新たに1つ追加します:
2017040401


アクティビティではまずマイグレーション元を指定します。今回は最初に作成した people データセットをマイグレーション元とするので、"Data Sets" を選択します:
2017040402


Data Sets 一覧から people を選択(1つしかないけど)します。全ての列にチェックが入っていることを確認して、次にマイグレーション先を指定するため画面右上の "Copy to Target" をクリックします:
2017040403


マイグレーション先は dashDB のデータベースなので、"Connections" の dashDB の接続情報名を選択し、マイグレーション先となるデータベーススキーマを指定します:
2017040404


people テーブルをマイグレーションするのですが、このデータベースが指定したスキーマに存在していない場合はどのようにマイグレーションするかを選択します。下図では "Recreate the table"(テーブルごと作り直してマイグレーションする)を選択しています。これで定義自体は完了で、必要に応じてこのアクティビティ定義に名前を指定することもできます(画面左上から編集できます)。 そしてこの定義を保存(Save)するか、そのまま実行(Run)することもできますが、今回は更に実行スケジュールを指定します。画面右上の "Schedule Activity" をクリックします:
2017040405


カレンダーが表示されます。このマイグレーションアクティビティを実行する日付を指定します:
2017040406


次に実行時刻(指定日の何時に実行するのか)を指定します。1回だけ実行するのであればこのまま "APPLY" をクリックしてもいいのですが、定期的に繰り返して実行する場合は "Schedule this activity to repeat" を選択します:
2017040407


引き続いて繰り返しの条件を指定します。下図の例では毎日(Daily & Every 1 day)実行して、終了日を指定せず(Never)に定義しています。繰り返し条件が確定したら "APPLY" をクリックします:
2017040408


指定した実行スケジュール(の直近のもの)が画面右側に表示されます。内容を確認して画面右上の "Done" をクリックします:
2017040401


1つ前の画面に戻り、いま定義したアクティビティが追加されたことが確認できます。このアクティビティの内容を確認したり、内容を変更する場合はこのアクティビティを選択します:
2017040402


この画面からアクティビティそのものを編集したり、スケジュールを変更したり、或いはスケジュールに関係なく一度実行したりすることができます:
2017040403


このアクティビティが実行されると、元の(MySQL の)データが dashDB へマイグレーションされます。ちなみにこちらが両者のテーブル内をプレビューした様子です(前者が MySQL 、後者が dashDB):
2017040400
  ↑MySQL


2017040401
  ↑dashDB


マイグレーションの定義とスケジューリングができ、正しく動いていることが確認できました。今回のケースであれば、いわゆるトランザクション用途で使っていた MySQL のデータを、統計処理目的で dashDB に移したかったわけですが、それが簡単に実現できたことになります。

このような異なるデータベース間のデータマイグレーションは、まあパターンが1つ程度であればプログラミングで可能になるかもしれませんが、何種類ものデータベースを対象としたり、順序などが複雑に絡み合っていたり、その実行スケジュールを考慮したりすると、システマチックに済ませたくなります。そんなケースで手軽にマイグレーションが行える Data Connect はかなり便利だと感じました。


このページのトップヘ