Jupyter(iPython)ノートブックは、コードのプロトタイプを作成し、あらゆる種類の機械学習をインタラクティブに行うための優れたツールとしてふさわしく知られています。しかし、私がそれを使用するとき、私は必然的に以下に遭遇します:
Jupyterで機械学習パイプライン全体を開発し、さまざまなソースから生データを取得し、データをクリーニングし、機能エンジニアリングを行い、トレーニングモデルを作成したとします。効率的で読みやすいコードでスクリプトを作成するのに最適なロジックは何ですか?私はこれまでいくつかの方法で取り組んできました。
.ipynbを.pyに変換し、わずかな変更を加えるだけで、ノートブックからのすべてのパイプラインを1つのpythonスクリプトにハードコーディングします。
多くの関数(1つまたは2つのセルごとに約1つの関数)を含む単一のスクリプトを作成し、パイプラインのステージを別々の関数で構成して、それに応じて名前を付けます。次に、argparse
を介してすべてのパラメーターとグローバル定数を指定します。
ポイント(2)と同じですが、クラス内のすべての関数をラップします。これで、すべてのグローバル定数と各メソッドの出力をクラス属性として保存できます。
ノートブックをいくつかのスクリプトを使用してpythonモジュールに変換します。これを試してはいませんでしたが、これが問題に対処する最も長い方法であると思われます。
この全体的な設定はデータサイエンティストの間では非常に一般的であると思われますが、驚くべきことに、役に立つアドバイスが見つかりません。
皆さん、アイデアと経験を共有してください。この問題に遭遇したことはありますか?どのように取り組みましたか?
同様の問題が発生しています。ただし、結果のプロトタイプを作成するためにいくつかのノートブックを使用していますが、これはやはりいくつかのpythonスクリプトになります。
私たちのアプローチは、これらのノートブック間で繰り返されるコードを脇に置くことです。これをpythonモジュールに配置します。このモジュールは各ノートブックによってインポートされ、本番環境でも使用されます。このモジュールを継続的に改善し、プロトタイピング中に見つかったテストを追加します。
ノートブックは、構成スクリプト(結果のpythonファイル)に単純にコピーする)と、プロダクションでは必要のないいくつかのプロトタイピングチェックと検証のようになります。
すべてのほとんどは、リファクタリングを恐れていません:)
ライフセーバー:ノートブックを作成しているときに、コードを関数にリファクタリングし、最小限の
assert
テストとドキュメント文字列を作成します。
その後、ノートブックからスクリプトへのリファクタリングは自然です。それだけでなく、長いノートを書くとき、それを他のものに変える計画がない場合でも、あなたの人生を楽にします。
「最小限の」テストとdocstringを使用したセルのコンテンツの基本的な例:
def Zip_count(f):
"""Given Zip filename, returns number of files inside.
str -> int"""
from contextlib import closing
with closing(zipfile.ZipFile(f)) as archive:
num_files = len(archive.infolist())
return num_files
Zip_filename = 'data/myfile.Zip'
# Make sure `myfile` always has three files
assert Zip_count(Zip_filename) == 3
# And total Zip size is under 2 MB
assert os.path.getsize(Zip_filename) / 1024**2 < 2
print(Zip_count(Zip_filename))
ベア.py
ファイルにエクスポートすると、コードはおそらくクラスに構造化されません。ただし、テスト用に簡単にtests.py
に移動できる一連の単純なassert
ステートメントを備えた、ドキュメント化された関数のセットを持つようにノートブックをリファクタリングする価値はあります。 pytest
、unittest
、またはあなたが持っているもの。それが理にかなっている場合、これらの関数をクラスのメソッドにバンドルすることはその後簡単です。
すべてがうまくいけば、その後に行う必要があるのは、 if __== '__main__':
とその「フック」を書くことだけです。端末から呼び出されるスクリプトを作成する場合は、 コマンドライン引数を処理する 、モジュールを書いている場合は、 __init__.py
ファイルを使用したAPI などについて考えてください。
もちろん、意図するユースケースが何であるかによって異なります。ノートブックを小さなスクリプトに変換することと、本格的なモジュールまたはパッケージに変換することには、かなりの違いがあります。
ノートブックからスクリプトへのワークフローに関するいくつかのアイデアがあります:
print
ステートメント、プロットなど。if __== '__main__'
を使用して、スクリプトの入り口を書きます。assert
ステートメントを分離し、tests.py
の最小限のテストスイートを具体化します。この問題に対処するために、最近モジュールを作成しました( NotebookScripter )。関数呼び出しを介してjupyterノートブックを呼び出すことができます。使用するのと同じくらい簡単
from NotebookScripter import run_notebook
run_notebook("./path/to/Notebook.ipynb", some_param="Provided Exteranlly")
キーワードパラメータを関数呼び出しに渡すことができます。ノートブックを外部からパラメータ化できるように簡単に適合させることができます。
.ipynbセル内
from NotebookScripter import receive_parameter
some_param = receive_parameter(some_param="Return's this value by default when matching keyword not provided by external caller")
print("some_param={0} within the invocation".format(some_param))
run_notebook()は.ipynbファイルまたは.pyファイルをサポートします。vscodeのipythonのnbconvertによって生成される可能性のある.pyファイルを簡単に使用できます。インタラクティブな使用に適した方法でコードを整理し、必要に応じて外部で再利用/カスタマイズすることもできます。