実行ファイルの構成
先ほどの記事で紹介した、AMLSの実行スクリプトから直接呼ばれるExperimentのRunスクリプトの構成です。
ScikitLearn準拠のRunnerという雰囲気ですが、いろいろやってみたところ、別にScikitLearnに特化した話はあまりなく、単にパラメータの受け渡し、結果の登録というところさえできれば良いようです。
あまり特色は無いので、clrライブラリを使った.NETライブラリの統合時の参考となれば。
(題材としては度々登場するBayesServerのライブラリを想定しています。実際には直接インポートするのではなく.NETのカスタムライブラリとして多少ラップしているのですが、ダイレクトに読み込んでも何とかなる代物ではあります。)
import, import, import
azuremlからはRunだけ持ってくれば、スケルトンとしての機能は果たせるようです。
sklearn周りはシンプル。
clr周りは引数に登場する型を個別にimportする必要があります。
pythonの型と.NETの型の翻訳を頭においておいてください。
import argparse
from azureml.core.run import Run
# scikit learn
import sklearn
from sklearn.model_selection import train_test_split
import joblib
# clr classes
import clr
clr.AddReference('System.Data')
clr.AddReference('System.Collections')
from System import Array, Linq, Nullable, Double
from System.Data import *
from System.Collections import *
from System.Collections.Generic import List
# estimator
from estimator import *
以下のように.NETのライブラリ自体のありかをsys.pathに指定する必要があります。
手元はWindowsの場合、AMLSのノードはLinuxなので切り替えが必要です。
ここでは.NET Standard 2.0ベースのライブラリを想定しています。
# Windows
# sys.path.append(r"C:\Users\***\Debug\netstandard2.0")
# Linux
# sys.path.append("/mnt/****")
起動スクリプト
main()関数として、必要な引数を指定した形で構成します。
この部分がAMLSとユーザースクリプトの主要なパラメータ引き渡しのやり方になります。
ScikitLearnのインターフェイスは結局全然関係ないことに気づきます。。。
コンテキストの読み込み
おまじないの類ですが、最初に行っておきます。
# get current run in context
run = Run.get_context()
datafile = "datasource.csv"
option = "option"
データ読み込み
main関数にてcsvからデータを読み込みtrain/predictで分割です。
この辺はScikitLearnの関数を利用、、してもいいし、しなくてもいい。
BNEstimatorというクラスにすべてが詰め込まれています。
実は前後で.NETクラスとPandasのデータフレーム変換が発生するのでいくつか変換コードが入りますが、ここでは省略しています。
def main():
print('starting estimater')
# parse argument of main function
parser = argparse.ArgumentParser()
parser.add_argument('--datafile', type=str, default='',
help='Data file for train/test')
parser.add_argument('--option1', type=str, default='',
help='option1')
args = parser.parse_args()
# load data from data
basepath = "./data/"
df = pd.read_csv(basepath + datafile)
target = df.pop(targetColumn)
# split data set
X_train, X_test, y_train, y_test = train_test_split(
df, target, test_size=0.2, shuffle=False)
y_test.to_csv('./logs/y_test.csv')
y = pd.concat([y_train, y_test], axis=0)
glabels = get_labels_from_dbl_series(y)
BNEstimatorというメインのクラスに実行内容をセットします。
カラムの意味指定をしている感じですが、そのうち公開します。
estimator = BNEstimator(
idColumn="id",
partitionColumn=partitionColumn,
...)
fitしてpredict
インターフェイスといっても、これだけ合わせるだけじゃん、というのが正直なところ。そしてAMLSにとっては、それすらどうでも良いらしく、Scikit Learnにラップした恩恵は皆無。。。
# fit
estimator.fit(X_train, y_train)
# store trained model
estimator.save_network("./logs/")
# predict
prediction = estimator.predict(X_test)
prediction.to_csv('./logs/prediction.csv')
結果を評価
評価の時に少しScikit Learnの恩恵を感じます。
# evaluate
eval_tupple = evaluate_prediction(y_test, prediction )
run.log('Hammloss', np.float(eval_tupple.hammloss))
run.log('Accuracy', np.float(eval_tupple.accuracy))
run.log('macro_f1', np.float(eval_tupple.macro_f1))
run.log('micro_f1', np.float(eval_tupple.micro_f1))
if __name__ == '__main__':
print('start main')
main()