GUIから機械学習パイプライン（マルチ学習）を動かしてみる - 設計と実装方法

キーワード：MLOps、機械学習パイプライン、マルチブランチ、マルチ学習、パイプラインGUIツール

##目次
- 概要
- ケース紹介
- 課題抽出
- 設計と実装方法

##概要

これまで各社が出された製品、及びOSSの中で、マルチブランチを容易に構成と実装するツールがなく、本稿では、複雑に絡み合う前処理と複数の学習、推論、評価を機械学習パイプラインで行う際のパラメーター設定の簡素化、パイプラインのデータチャンネルの繋ぎ方をご紹介します。

##ケース紹介
A社（仮）は全国で80以上店舗を展開し、店舗毎に扱う商品は16種類です。店舗毎の商品別の時系列売り上げ予測モデルを作成するためのパイプライン構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253107/4a600567-ee5a-b6f5-b754-ffd01ff1b353.png)
図２、表2に示す通り1つの学習モデルに対して学習、推論、評価用３つのデータセットが必要となるため、モデル数*3の3,840個が必要です。イメージしやすいよう、単純に12個のDBと7つのモデル作成にしました。

　　　　 表２、パイプラインを動かすためのパラメーターは250,880個以上になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253107/48813818-8155-10ec-6e41-df799bf905d4.png)

これらの大量のパラメーター（250,880個）も効率よく*yamlを作成し、パイプラインに渡す必要があります。
パラメータ数のみならず、各データセットと各学習、各推論、各評価とどのようなパスで繋いでいるか、ステップを組む際、パスを認識しやすいようワークフロー上での配置方法も工夫が必要です。


##課題抽出
以上のケースから、以下の課題を抽出しました。
- 課題１：　大量のパラメーターの入力ミスを最小限に留めること
- 課題２：　入力パラメーター数をなるべく削減すること
- 課題３：　パラメーター間の比較もできること
- 課題４：　パラメーターの履歴も比較できること
- 課題５：　前処理時の作成したDBを容易に検索できること
- 課題６：　学習データセットと各モデル学習、推論、評価の関係性を入力しやすいこと
- 課題７：　これらの大量のパラメーターをパイプラインに伝えること。

##設計と実装方法
GUIツール上でパラメーター作成及びワークフローのステップチェーンを構成します。


####課題１：　大量のパラメーターの入力ミスを最小限に留めること
対策１：　
パラメーターの共通項目を洗い出して、共通部設定シートにまとめます。

実装方法１：　
表示３のようにデータフレームへ辞書型変換の際、深いレイヤーをもつ辞書のキーはどのレイヤに置かれるかを識別するために、上位キーと下位キーを親子関係として紐づき、また子キーのレイヤー番号を1, 2, 3のように記入します。

　　　　　　表３、共通部テーブル構成
　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253107/b4307b84-048f-9b89-b9e0-ff24e52a44bd.png)

####課題２：　入力パラメーター数をなるべく削減すること

対策２：　

エクセルの関数と類似な機能で、共通項目＋データセット名／モデル名を加味した加工値をpythonスクリプトで加工します。

実装方法２：

ステップカテゴリ毎のテーブルを用意します。
　　　　　　
　　　　　　表４、ステップ毎のテーブル構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253107/7a433dda-efc1-2496-5fed-1b9c5f7613b2.png)



####課題３：　パラメーター間の比較もできること

対策３： ステップカテゴリに、ステップ同士のパラメーターを列毎に用意します。

実装方法３：

ステップカテゴリの処理数（ここはデータセット作成数）に合わせて列を用意します。

　　　　　表５、前処理１カテゴリーに４つのDB作成のために、
　　　　　col1, col2, col3, col4を「前処理１」シートに用意します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253107/166a9a4d-680f-f3e0-eb61-d71b59c85e18.png)
####課題４：　パラメーターの履歴も比較できること

対策４：　
対策１～３より加工した最新情報をテーブルの形で保管します。
実装方法４：
方法１、（DB簡易版）python スクリプトよりパイプライン動作ディクトリーの./log/*.csvとして履歴保管します。
方法２、DBテーブルに保管・検索します。


####課題５：　前処理時の作成したDBを容易に検索できること

対策５：　前ステップ<->後ステップのデータチャンネルは実ファイルパスの代わりに、キーワードを使います。

実装方法５：
前処理より出力された学習データセットのファイルパスを入力することをやめて、表６の黄色いセル入力エリアのquery1, query2のような名称を記入します。表５の示した前処理１～より作成したデータセット実パスをpythonスクリプトより検索し、パイプラインに渡します。検索対象は実装方法４で保管された履歴情報よりデータフレームとなります。

　　　　表６、query*をキーに、対策４で保管されたテーブルで
　　　　該当学習データセットの出力した実パスを検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253107/fe0f7bbf-be72-2079-63bb-725d546df450.png)

####課題６：　学習データセットと各モデル学習、推論、評価の関係性を入力しやすいこと
対策６：　関係性をデータフレームに変換
実装方法６：
各ステップ（表７のコラム名はステップ名）のデータセット名と学習、推論、評価ステップ、学習済みのモデルと推論、評価の関係性マッピングをテーブルとしてまとめ、パイプライン上、各ステップの入出力をデータチャンネルとした形で認識します。
　　　　表７、ステップ関係性をテータフーム上でマッピング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253107/10bf6252-4048-9dc8-abf5-8ce992e7f5a9.png)
									

####課題７：　これらの大量のパラメーターをパイプラインに伝えること。
対策７：　ステップカテゴリ名、ステップ名、ステップのパラメーター名、パラメター値を辞書化としてまとめます。
実装方法７：

実際に流すジョブ数は　ステップ x query数 あるいはモデル数になるので、今回ケースではかなりのジョブ数となります。対策４で得られたテーブル情報をjson辞書型->yamlに変換し、パイプラインに読ませてあげる形、そしてjob作成をそれぞれ関数化し、
辞書１
{　
　ステップ名:
　　　　　　{
　　　　　　　　query名（あるいはデータセット名、モデル名：
　　　　　　　　{ジョブ名：ジョブの中身}
　　　　　 }
}

という辞書型にまとめます。最後に、パイプラインをオーケストレーションするモジュールに図７の関係性を見て、辞書１をパス繋ぎ設定を行います。