チュートリアル: カスタム関数の追加
このチュートリアルでは、パッケージ化して GitHub リポジトリーに保管するカスタム関数を作成します。 その関数を、カタログに登録して計算で使用する前に、ローカル環境でテストします。
このタスクについて
このチュートリアルでは、入力項目を係数値でかけるカスタム関数 MultiplyByFactorを作成しています。 ファンクションコードの一部として、入出力項目のコントロールをどのように表現するかを定義する。 後で、入力項目と係数値を指定します。
execute_local_test メソッドを使用して、関数をテストします。 このメソッドを使用して、IoT 関数内の基本クラスから派生したすべての関数をテストします。 このメソッドは、関数のサンプル・データをローカルで生成します。 このコマンドは、作業ディレクトリー内の df_test_entitity_for_function_name という名前のファイルに結果を書き込みます。 その関数が動作したら、.NET Frameworkに登録する。
最後に、サンプルのロボット・デバイス・タイプを作成し、新しい MultiplyByFactor 関数をデバイス・タイプに適用します。
このチュートリアルでは、Pycharm IDE を使用してカスタム関数の Python パッケージを作成します。 他のIDEを使う場合は、 Python 3.9.x。
代わりに、このチュートリアルとは別に、 カスタム関数スターター・パッケージ を IoT 機能で使用することにより、独自のカスタム関数の作成を開始することができます。
始める前に
スターター・パッケージを複製し、それをローカル環境でサンプル・パッケージとして使用することができます。 スターター・パッケージを複製することで、カスタム関数用に必要なパッケージ (IoT 関数を含む) を簡単にインストールできます。 スターター・パッケージは、カスタム・パッケージに必要なディレクトリー構造の例を提供します。
- ご使用の環境に Python 3.9.x をインストールします。
- GIT をインストールします。
- Pythonの pip3 パッケージ・マネージャーをインストールします。
- コードの更新を行うには、 Xcodeなどのエディターをインストールします。
- HelloWorld スターター・パッケージ の複製
- 端末ウィンドウを開きます。
- スターター・パッケージ用の新規プロジェクト・フォルダーを作成します。 例えば、
mkdir projectなどです。 - プロジェクト・ディレクトリーに移動します。 例えば、
cd projectなどです。 - スターター・パッケージを複製します。 次のように入力します。
git clone --branch starter_package https://github.com/ibm-watson-iot/functions.git - スターター・パッケージがプロジェクト・ディレクトリーに複製されたことを確認します。
- スターター・パッケージの functions ディレクトリーに移動します。 次のように入力します。
cd functions - 次のように入力します。
git status - 後で使用できるように、作業ディレクトリーのパスをコピーします。
pwdを入力してパスをコピーします。 setup.pyファイルを開きます。setup.pyファイルは、パッケージ名と、プロジェクトに必要なパッケージのリストを定義します。nameパラメーターをcustom{your_initials}に設定します。 {your_initials} 変数を、イニシャルまたは別の固有値に置き換えます。ibm-watson-iot/functionsリポジトリーで、iotfunctionパッケージが正しいバージョンであることを確認します。 例えば、 8.8 の場合、パッケージは8.8.XGitHub ブランチのものでなければならない。 バージョンのxを別の値で置き換えないでください。 以下の文章は、setup.pyファイルの例である。 nameパラメータはcustomId、8.7.Xブランチが使用される。
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(name='customld', version='0.0.1', packages=find_packages(),
install_requires=['iotfunctions@git+https://github.com/ibm-watson-iot/functions.git@8.7.x'])
- PyCharmcommunity edition をインストールします。
- PyCharm で、ご使用の環境が複製したスターター・パッケージを指すようにします。 開く をクリックして参照し、複製したディレクトリーを見つけます。
- 新しい Pycharm 仮想環境をセットアップします。
- PyCharm > 設定 > プロジェクト <your_project> > プロジェクト・インタープリターに移動します。
- 新しい仮想環境をセットアップする場合は、次のようにします。
- 設定アイコンをクリックして、 追加をクリックします。
- プロジェクト・フォルダーの場所を指定します。
- 基本インタープリターを Python 3.9.x ディレクトリーに設定します。
- 既存の仮想環境がある場合は、プロジェクト・インタープリターを Python 3.x に設定します。
- 以下のコマンドを実行して、
iotfunctionsパッケージを Python 環境にインストールします。 ご使用のバージョンの正しいブランチ名を使用していることを確認してください。pip3 install git+https://github.com/ibm-watson-iot/functions.git@8.7.x --upgrade
IoT 関数は必ず最新バージョンを使用してください。 .NETがサポートしている各 Python モジュールのバージョンを確認する。 サポートされている正確なバージョンを使用しないと、パイプラインが切断される可能性があります。
ステップ
カスタム関数を使用してサンプル・データに計算を適用するには、以下のステップを実行します。
ステップ 1: 計算を定義する
ロボット・アームを開発する会社が、新しいロボット・アームを導入し、既存のロボット・アームだけでなくその機能もテストしています。 初期のテストでは、一部のロボットについて、テスト中の移動距離が高すぎることが発見されました。 調査の結果、チームは、テストに使用されたツールが原因で、ロボットの速度と移動時間に遅延が生じていることを発見しました。 運用管理者は、両方の値を 2 倍に調整したいと考えていますが、後でその値を変更できる柔軟性も確保する必要があります。
アナリストは、類似の計算が他の計算に役立つ可能性があり、 MultiplyByFactor クラスを作成することによって関数を一般化することを示しています。
distance * factor
ステップ 2: 関数をパッケージ化して GitHub に保管する
- 複製したスターター・パッケージ用の新規リポジトリーを GitHub に作成します。
- リポジトリーには、pip install からアクセスできる URL が必要です。
- ベスト・プラクティスとして、リポジトリーはプライベートにしてください。 リポジトリーには、個人アクセス・トークンを使用してアクセスできます。
- ファイルをリポジトリーに追加して、マスター・ブランチを作成します。 例えば、
test.mdという名前の空のファイルを追加し、Commit new fileをクリックします。 - プロジェクトを編集するために、ローカルの PyCharm 内で開きます。
- プロジェクトに以下のディレクトリー構造とファイルがあることを確認します。
functions | |__ setup.py | |__ scripts | |_ local_test_of_function.py | |__ custom | |_ functions.py |_ __init__.py - モジュール名
customを、customyourinitialsなどの固有の名前に変更します。 例えば、customldのようになります。 custom<yourinitials>でmultiplybyfactor<yourinitials>.py関数モジュールを作成し、以下のコードを貼り付けます。 ご使用の環境に合わせて<>の変数を更新します。 例えば、コードが GitHub にある場合は、PACKAGE_URLを'git+https://<XXXXXX>@github.com/github.com/jones/starter@starter_package'に設定できます。この関数では、2 つのメソッドを実装します。
executeメソッドに計算を追加します。 関数の入力引数および出力引数をbuild_uiメソッドに設定します。 これらの引数は、構成ユーザー・インターフェースを介して構成されます。import inspect import logging import datetime as dt import math from sqlalchemy.sql.sqltypes import TIMESTAMP,VARCHAR import numpy as np import pandas as pd from iotfunctions.base import BaseTransformer from iotfunctions import ui logger = logging.getLogger(__name__) # Specify the URL to your package here. # This URL must be accessible via pip install. # Example assumes the repository is private. # Replace XXXXXX with your personal access token. # After @ you must specify a branch. PACKAGE_URL = 'git+https://XXXXXX@github.com/<user_id><path_to_repository>@starter_package' class MultiplyByFactor<YourInitials>(BaseTransformer): def __init__(self, input_items, factor, output_items): self.input_items = input_items self.output_items = output_items self.factor = float(factor) super().__init__() def execute(self, df): df = df.copy() for i,input_item in enumerate(self.input_items): df[self.output_items[i]] = df[input_item] * self.factor return df @classmethod def build_ui(cls): #define arguments that behave as function inputs inputs = [] inputs.append(ui.UIMultiItem( name = 'input_items', datatype=float, description = "Data items adjust", output_item = 'output_items', is_output_datatype_derived = True) ) inputs.append(ui.UISingle( name = 'factor', datatype=float) ) outputs = [] return (inputs,outputs)
ステップ 3: 資格情報をファイルに保存する
.NETに接続するための認証情報を設定する。
-
credentials_as.jsonファイルをダウンロードします。 - 変数をデータに置き換え、ファイルをローカル・マシンに保存します。
資格情報ファイルは、関数をローカルで実行またはテストするために使用されます。 このファイルを ステップ 4内の外部リポジトリーにプッシュしないでください。
ステップ 4: ローカルの変更を GitHub リポジトリーにプッシュする
以下のステップが完了していることを確認します。
- 変更後のファイルも、引き続き、コードの複製元の GitHub リポジトリーを指しています。 リモート・リポジトリーを GitHub リポジトリーに変更してください。
- 変更を外部ディレクトリーにコミットする前に、関数コードに資格情報ファイルが含まれていないことを確認します。
関数コードを GitHub 内の外部リポジトリーにプッシュします。
- プロジェクト・フォルダーで端末ウィンドウを開きます。
- 入力:
git remote -v. リモート・リポジトリーは引き続きhttps://github.com/ibm-watson-iot/functionsを指しています。 - 以下のコマンドを使用して、リモート起点 URL を変更します。
フェッチ URL およびプッシュ URL がご使用のリポジトリーを指していることを確認します。git remote set-url origin URL_To_YOUR_GITHUB_REPOSITORY - 以下のコマンドを使用して、アップストリーム・リモートを追加します。 次のように入力します。
git remote add upstream https://github.com/ibm-watson-iot/functions.git - ファイルを GIT に追加し、コミットします。
- PyCharm で、
custom<your_initials>ディレクトリーを選択します。 - 「Git」>「Add」を選択します。
- 「Git」>「Commit」を選択します。
- 変更のコミット・ウィンドウで コミットをクリックします。
- 「Git」>「Repository」>「Push」を選択します。
- プッシュをクリックします。
- PyCharm で、
- モジュールがリポジトリー内の
starter_packageブランチにプッシュされたことを確認します。
ステップ 5: カスタム関数をローカル環境にインストールする
ローカル環境にカスタム関数をインストールします。 ご使用の環境に合わせて<>の変数を更新します。
pip3 install git+https://<XXXXXX>@github.com/<user_id><path_to_repository>@starter_package --upgrade
以下に例を示します。
pip3 install git+https://<XXXXXX>@github.com/jones/starter@starter_package --upgrade
< xxxxxx> を個人用アクセス・トークンに置き換えます。< /xxxxxx>
ステップ 6: カスタム関数をローカルでテストする
scriptsフォルダーにtest_my_custom_function.pyというスクリプトを作成します。 このスクリプトで、以下のように Python ライブラリーとパッケージをインポートします。import datetime as dt import json import pandas as pd import numpy as np from sqlalchemy import Column, Integer, String, Float, DateTime, Boolean, func from iotfunctions.base import BaseTransformer from iotfunctions.metadata import EntityType from iotfunctions.db import Database from iotfunctions import ui- に接続する。
test_my_custom_function.pyスクリプトで、以下を追加します。with open('credentials_as.json', encoding='utf-8') as F: credentials = json.loads(F.read()) db_schema = None db = Database(credentials=credentials) - 関数をインポートしてインスタンス化します。
test_my_custom_function.pyスクリプトで、以下のコードを追加します。 ご使用の環境に合わせて<>の変数を更新します。from custom<yourinitials>.multiplybyfactor<yourinitials> import MultiplyByFactor<YourInitials> fn = MultiplyByFactor<YourInitials>( input_items = ['speed', 'travel_time'], factor = '2', output_items = ['adjusted_speed', 'adjusted_travel_time'] ) df = fn.execute_local_test(db=db, db_schema=db_schema, generate_days=1,to_csv=True) print(df) - コマンド・ラインからスクリプトを実行します。 日付フレームの結果は .csv ファイルに保存されます。 スクリプト・ディレクトリーで
df_test_entity_for_multiplybyfactor<your_initials>.csvを探します。 次のように入力します。python3 test_my_custom_function.py
ステップ 7: カスタム関数を登録する
scriptsフォルダーにregister_my_custom_function.pyというスクリプトを作成します。 このスクリプトで、以下のように Python ライブラリーとパッケージをインポートします。import datetime as dt import json import pandas as pd import numpy as np from sqlalchemy import Column, Integer, String, Float, DateTime, Boolean, func from iotfunctions.base import BaseTransformer from iotfunctions.metadata import EntityType from iotfunctions.db import Database from iotfunctions import ui- に接続する。
register_my_custom_function.pyスクリプトで、以下を追加します。with open('credentials_as.json', encoding='utf-8') as F: credentials = json.loads(F.read()) db_schema = None db = Database(credentials=credentials) `` register_my_custom_function.pyスクリプトで関数を登録するには、以下のコードを追加します。 ご使用の環境に合わせて<>の変数を更新します。from custom<yourinitials>.multiplybyfactor<yourinitials> import MultiplyByFactor<YourInitials> db.register_functions([MultiplyByFactor<YourInitials>])- コマンド・ラインからスクリプトを実行します。 以下に例を示します。
python3 register_my_custom_function.py
ステップ 8: サンプル・デバイス・タイプの作成
- Setup(セットアップ) ページの Device types(デバイス・タイプ )タブで、Add device type +(デバイス・タイプの追加)をクリックし、新しいデバイス・タイプを追加します。
- 産業用ロボットのサンプルタイプのテンプレートを選択します。
- Device type name(デバイスタイプ名)フィールドでデバイスタイプに名前を付けます。
- 作成をクリックします。
- Device types(デバイスタイプ )から新しく作成したサンプルデバイスタイプを選択し、楕円ボタン(縦に並んだ3つの点)をクリックして Edit(編集 )を選択すると、サンプルデバイスタイプの Data(データ) タブが開きます。
メトリックの生成には最大 5 分かかります。
ステップ 9: カスタム関数をデバイス・タイプに適用します。
distanceメトリックを作成していない場合は、追加します。 チュートリアル: 式の追加のステップに従ってください。- 「データ」 タブで、 「メトリックの作成」をクリックします。
- カタログから
MultiplyByFactor<YourInitials>関数を選択します。 - スコープを設定し、 「次へ」をクリックします。
- 「係数」フィールドに 2 を入力します。
input_itemフィールドで、distanceを選択します。- 次へをクリックします。
- 出力の名前を「adjusted_distance」に変更します。
- 作成をクリックします。
- データ項目リストで、
adjusted_distanceを選択します。 サンプルデータに対してカスタム関数を評価するため、最大5分間待ちます。