=================
AI-API作成の流れ
=================

.. Contents:: 目次
    :local:
    :depth: 3

この章では、AI-API作成の流れを例を交えて説明します。AI-APIの作成は以下の流れで行います。

1. AI-APIの設計
2. AI-APIの実装
3. AI-APIのデプロイ用物件作成

この章の例では、検証フェーズで作成した分析手順と作成済みの分析モデルを使って、
「AAClusterに配置した作成済みの分析モデルを使って予測を行う」AI-APIを設計、実装、テストし、
最後に作成したAI-APIのデプロイ用物件を作成します。

AI-APIの設計
============

AI-APIの設計は以下の流れで行います。

1. 検証フェーズで作成した分析手順について、AI-APIとして実行できるようにする範囲を決定します。
2. AI-API化する範囲について、「AIアプリケーションにどの様な単位で機能を提供するか」を決定します。
3. 2.の結果に基づいてAI-APIの外部仕様を設計します。

また、AI-APIの実装にあたり、分析手順に含まれていない運用に必要な処理をAI-APIとして提供する場合はこの段階で設計します。
例えば、「分析モデルの再学習時に生成されたファイルを削除する」処理をAIアプリケーションに提供したいのであれば、
そのためのAI-APIを設計します。

なお、AI-APIは ``nbexec`` を利用して作成しますので、AI-APIの設計時には ``nbexec`` の利用方法を理解しておく必要があります。
``nbexec`` についての詳細は *nbexec User Guide* を参照してください。

設計例
------
「作成済みの分析モデルを使用して予測を行う」機能を提供することを目的として、AI-APIを設計します。
予測の実行にはscikit-learnを使用します。

ここでは、外部仕様としてAI-APIの利用手順と、AI-APIのリクエストパラメータを設計します。

AI-APIの利用手順は、以下のように設計します。

#. AIアプリケーションは、AAClusterの個人領域に分析データをアップロードする
#. AIアプリケーションは、AACluster上にデプロイされているAI-APIを呼び出す
#. AI-APIは、AAClusterの個人領域にある分析データを使って予測を行い、
   予測結果をAAClusterの個人領域に出力する
#. AIアプリケーションは、AAClusterの個人領域上に出力された予測結果をダウンロードする

リクエストパラメータは以下の様に設計し、分析データの場所および予測結果の出力場所、
予測に使用する分析モデルの場所をAIアプリケーションが指定できるようにします。

============ =====================================================================================
パラメータ名  説明
============ =====================================================================================
input_path   分析データ（CSVファイル）が配置されている場所。相対パスが指定された場合は、
             notebookファイルを配置したディレクトリをカレントディレクトリとして場所が決定される。
result_path  予測結果（CSVファイル）の出力先。相対パスが指定された場合は、
             notebookファイルを配置したディレクトリをカレントディレクトリとして場所が決定される。
model_path   予測に使用する分析モデルが配置されている場所。
============ =====================================================================================


AI-APIの実装
============

AI-APIの設計結果に従って、分析手順をAI-API化します。
分析手順がAI-APIとして提供する機能の単位で複数のnotebookファイルに分かれている場合は、
それらをコピーしそのままAI-APIの実装に使用します。
分析手順をAI-APIの実装単位に合わせて分割する必要がある場合は、
分析手順を元にして新しいnotebookに必要な処理だけを記載します。

AI-APIの実装では以下の作業を行います。この作業はAAClusterを利用して行います。

* 新しくコードを記述するセルを追加し、AI-APIのパラメータを定義する
* パラメータを分析手順で扱える様に他のセルを修正する
* AI-APIの設計に合わせて、実行結果の出力処理を変更（または追加）する
* 必要に応じて、不要ファイルの削除、ログ出力等の処理を追加する
* 実行に必要なファイル(属性スキーマや実行済みプロセスのエクスポート結果等)を作成する
* 作成したAI-APIの動作確認およびテストを行う
* ``nbexec`` の `Execution Document` の機能で外部仕様書を出力できるようにするため、
  notebookファイルの先頭にMarkdownを記述するセルを追加し外部仕様を記述する

実装例
------
この例では、以下の想定で「作成したモデルを使って中古車の価格を予測する」notebookファイルを使ってAI-APIを実装します。

* 分析手順として以下2つのnotebookファイルが用意されている

  * 中古車の価格を予測するモデルを作成する
  * 作成したモデルを使って中古車の価格を予測する

AI-APIの実装はAACluster上で行います。AAClusterの作成は事前に行ってください。

実装に使用するファイルのアップロード
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Notebook Dashboardの :guilabel:`[Files] タブ` で、Jupyter Notebook のルートディレクトリに
:file:`automobile` フォルダを作成します。このフォルダに移動し、以下のファイルをアップロードします。

* :download:`「作成したモデルを使って中古車の価格を予測する」notebookファイル（automobile_prediction.ipynb） <notebooks/automobile_prediction.ipynb>`
* :download:`作成済みモデル <notebooks/data/best_model.pickel>`
* :download:`動作確認用の分析データ <notebooks/data/automobile_predict.csv>`

| 作成済みモデルは、以下のデータ利用して作成しています。
| https://archive.ics.uci.edu/ml/datasets/automobile

| Acknowledgements
| Thanks to UCI Machine Learning repository,
| Dua, D. and Graff, C. (2019). UCI Machine Learning Repository [http://archive.ics.uci.edu/ml].
| Irvine, CA: University of California, School of Information and Computer Science.

実装
~~~~

:file:`automobile_prediction.ipynb` を開き、先頭にセルを追加します。

In [ ]:

.. code-block:: python

  # nbexec: params

  # Default values of parameters
  input_path = 'input.csv'
  result_path = 'result.csv'
  model_path = 'best_model.pickel'

  # Parameter definition
  {
      'input_path': dict(type=str, desc='The path to data to predict',
                         examples=['input.csv']),
      'result_path': dict(type=str, desc='The path to output to prediction result',
                          examples=['result.csv']),
      'model_path': dict(type=str, desc='The path to the exported model for using prediction',
                         examples=['best_model.pickel']),
  }

属性設計・生成を行う処理（In [1]）を書き換え、分析データをリクエストパラメータで指定されたファイルから読み込むように修正します。

In [1]:

.. code-block:: python

    import pandas as pd

    test_df = pd.read_csv(input_path, na_values="?")
    test_df.dropna(inplace=True)
    test_df = pd.get_dummies(test_df)
    test_df.head()
    

分析モデルをリクエストパラメータで指定された場所からインポートする用に修正します。

In [3]:

.. code-block:: python

    import pickle

    loaded_model, train_list = pickle.load(open(model_path, 'rb'))
    all_columns = set(train_list + list(test_df.columns))
    for column_name in all_columns:
        if column_name not in train_list:
            del test_df[column_name]
        elif column_name not in test_df.columns:
            test_df[column_name] = [0] * test_df.shape[0]

    test_X = test_df[train_list].iloc[:, test_df.columns != 'price']
    test_Y = test_df.loc[:, 'price']
    predict_Y = loaded_model.predict(test_X)


予測結果をCSVファイルに出力する処理をNotebookの末尾に追加します。

In [ ]:

.. code-block:: python

    result = pd.DataFrame(predict_Y, columns=["predict-price"])
    result.to_csv(result_path)


以上で実装は完了です。
実装完了後は全てのセルを実行し、作成したnotebookファイルがnotebookとして動く事を確認します。

外部仕様の記述
~~~~~~~~~~~~~~

実装したAI-APIの先頭にMarkdownセルを追加し、作成したAI-APIの外部仕様を説明する文章を追加します::

    # 中古車価格の予測API

    このAPIは、作成済みの分析モデルを使用して中古車価格を予測します。

    このAPIの実行には、以下をこのファイルと同じディレクトリに配置しておく必要があります。
    * 作成済みの分析モデル
        * `pickle.dump` を利用してエクスポートしてください。
        * 配置した場所はリクエストパラメータで指定してください。

    分析データはJupyter NotebookのWebAPIを使用してアップロードしてください。
    予測結果も同様にJupyter NotebookのWebAPIを使用してダウンロードしてください。

.. note:: リクエストパラメータについては説明が自動的に生成されるため、基本的には説明を書く必要はありません

ツールバーに表示されている :guilabel:`[Execution document]` ボタンを押下し、外部仕様が表示されることを確認します。

テスト
~~~~~~

.. raw:: html
   :file: _build/nbconvert/how_to_run_api.html

AI-APIのデプロイ用物件作成
==========================

作成したAI-APIを他のAAPFデプロイ環境に配置できるようにするため、必要なファイル一式を集めたアーカイブ
（AI-APIのデプロイ用物件）を作成します。また、AI-APIの配置手順も作成します。

作成したものはアプリケーション開発者に渡すか、アプリケーション開発者に指示されたAAPFデプロイ環境に配置します。

アプリケーション開発者は渡された物件をAI-Appsの開発やAI-Appsのリリース物件の作成、デプロイに利用します。

作成例
------

Terminalを開き、実装およびテストが完了したAI-APIと、AI-APIの実行に必要なファイル一式を1つのディレクトリに集め、
:file:`zip` 形式でディレクトリを圧縮します。

::

    $ mkdir -p tmp/automobile
    $ cp automobile/automobile_prediction.ipynb tmp/automobile/
    $ cp automobile/best_model.pickel tmp/automobile/
    $ cd tmp
    $ zip -r automobile_prediction.zip automobile

圧縮ファイル :file:`tmp/automobile_prediction.zip` を Notebook Dashboardの :guilabel:`[Files] タブ`
からダウンロードします。

このファイルを使って作成したAI-APIをAAPFデプロイ環境に配置する手順を作成します。

::

    1. AAClusterを作成し、Jupyter Notebookにアクセスします。
    2. automobile_prediction.zip をアップロードします。
    3. Terminalを開き、以下のコマンドを実行します。
       $ unzip automobile_prediction.zip

以上でAI-APIの作成は完了です。作成したアーカイブは以下の情報と一緒にアプリケーション開発者に提供します。

* AI-APIをAAPFデプロイ環境に配置する手順
* AI-APIの呼び出し手順
* AI-APIの外部仕様の確認方法（または、``nbexec`` の `Execution Document` の機能で表示した外部仕様をファイルに保存したもの）

.. note::

  AI-APIの呼び出し時に使用するJupyter NotebookのURLはAAClusterごとに異なり、同じAAPFユーザー、
  AAClusterの名前であっても作成し直す度にURLが変わります。
  
  AI-APIの実行に使用するAAClusterを定期的に作成し直す場合はAAPF WebAPIを利用して、
  AI-APIを呼び出す時にJupyter NotebookのURLを取得することを推奨するようアプリケーション開発者に案内してください。

この例で実装したAI-APIは :download:`こちら <_build/archives/automobile_prediction.zip>`
からもダウンロードできます。
