Blog
Jupyter Notebook の Tips をまとめてみた
こんにちは、AI Lab の馬場です。
このブログは CyberAgent Developers Advent Calendar 2016 の11日目の記事です。
昨日は sitotkfm さんの「ログを集める時に気をつけたいポイント」という記事でした。
この記事では、僕が仕事でデータ分析をやっていく上で大変お世話になっている Jupyter Notebook の Tips をまとめてみます。Jupyter Notebook では便利な機能がたくさんあるので、ちゃんと使うと無駄作業の削減になります。僕もこれまで分析途中で「あーこれができたらなあ」と検索しては時間をつぶしてきたので、ここでまとめて記憶にとどめておきたいと思います。
図表・可視化系
notebook 内に図を表示したい
単純に jupyter notebook を起動して、pyplot などでグラフを描画しようとしても、図は notebook 内に表示されず別ウィンドウが開きそちらに表示されてしまいます。そういう場合は、
というマジックコマンドを利用すると、notebook 内に図が書き出されるようになります。
for 文で DataFrame を HTML 表示したい
単純に DataFrame の中身を表示するには以下のように変数呼び出しをすればいいのですが、
機械学習をやっていると、学習 → 予測結果をdataframe で表示 → 次の学習 → 結果をdataframeで表示 → 以下ループ、みたいなことをやりたくなります。例えば for 文の中で、上記と同様に表示しようとしてもうまくいきません(表示されない、または、HTML表示にならない)
そんなときは、 IPython.display モジュールを利用すると HTML 表示ができます。
おすすめマジックコマンド
Jupyter Notebook を利用する上で、いくつかの便利な機能が「マジックコマンド」として標準で用意されています。とても簡単な記述で様々なことができるのでよく使います。マジックコマンドは %〇〇 のような形で宣言でき、その次に記述されるコードに何らかの機能を適用できます。ここではお気に入りのマジックコマンドを勝手に紹介したいと思います。
※ ちなみに、 %〇〇 の場合は、同じ行のコードのみにマジックコマンドが適用される。 %%〇〇 (%を1つ増やす)とすると、セル内のコード全体にマジックコマンドが適用される。(詳しくは、以下の %time の例を参照)
時間を計測したい
python で時間計測する際によく使われるのは time モジュールですが、Jupyter での時間計測では %time , %timeit を利用することが可能です。
- %time :続くコードの実行時間を計測してくれる。
- %timeit :続くコードの時間計測を、何回か試し、その中で最速だった結果と平均時間を返してくれる。
※ 3つ目のセルで、 %%time と % を 2 つにして、セル内全部のコードへと適用させています。
環境変数を取得する
%env マジックコマンドを利用すると環境変数を取得できたり設定できたりします。
Shell を実行する
%%bash や %%script などによって Shell コマンドを実行することができます。また、 ! を頭につけると、Shell コマンドを実行しつつ、その結果を python の変数に格納することができて非常に便利です。
どの変数が宣言されてメモリに確保されているか知りたい
%who もしくは %whos コマンドを使えば、今宣言されている変数を知ることができます。特に %whos コマンドは型や内容まで教えてくれるのでとてもよく使います。コマンドの後に Type を書くと、それでフィルタして表示してくれるのも良い。
荒い画像をきれいにしたい
pyplot などでグラフを描画すると、あんまりいけてない解像度のグラフ画像が出力されます。
しかし、 %config マジックコマンドで以下のようにすると解像度が格段にあがったグラフが出力されます。グラフをプレゼン資料に載せる場合はこれを使ってきれいにしてから載せたりします。
おすすめ Extension たち
Jupyter Notebook には拡張機能として様々な Extension が作られています。上記で紹介したマジックコマンドは標準装備のものですが、Extension をインストールすることでそれ以上の機能を Jupyter で利用することができます。ここでもお気に入りのものを紹介したいと思います。
ipython-sql
SQL に接続する時に通常は、コネクタを用意したりフェッチしてデータを取得しなきゃいけなかったり結構めんどくさい。それを %sql と書けばそれだけでデータベースへクエリを投げることができる非常に強力な Extension です。簡単すぎてこれがないと分析できないと思えるぐらいズブズブの関係です。
https://github.com/catherinedevlin/ipython-sql
IPython-BeautifulSoup
仕事柄、サイトをクローリングすることがたまにあって、その際にとても強力に使える Extension が IPython-BeautifulSoup です。HTMLのパースがわずか3行でできるという優れもの。
https://github.com/Psycojoker/ipython-beautifulsoup
Base 16 for IPython Notebook
Notebook のテーマカラーを変えられるおしゃれな Extension の一つ。テーマカラーは Base16 カラーから選ぶことができ、かっこいい&目に優しい、黒背景で作業をすることができます。おすすめ。
https://github.com/nsonnad/base16-ipython-notebook
notedown
notebook ⇔ markdown の変換を行うことができるライブラリ。Extension というよりCLIライブラリだけど、チームメンバー内でのメイン共有が Markdown な方にはおすすめ。アドテクでは esa.io や Qiita:Team を利用しているので重宝してます。
https://github.com/aaren/notedown
その他の Extension
上記は僕がよく使っているものをピックアップしていますが、人によって気になるものは違いますよね。ipython の wiki に他の Extension も含めてまとまっているので、一度目を通しておくといいかもしれません。
Jupyter 環境設定系
.ipynb を .py ファイルに保存したい
分析したコードをちょっときれいにしてそのままバッチとして動かしたいなーと思ったり、ipynb をバージョン管理したいけど、出力部分の差分とかは無視したいと思ったりする場面があると思います。(少なくとも僕はありました汗)そんな時に出会った素晴らしい方法が mmsstt さんの記事にまとめてあったので、再掲しておきます。
各自の環境にある以下のファイルをいじります。
1 |
.jupyter\jupyter_notebook_config.py |
上記の jupyter_notebook_config.py ファイルで以下のようになっている部分を
1 |
#c.FileContentsManager.post_save_hook = None |
以下のように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import io import os from notebook.utils import to_api_path _script_exporter = None def script_post_save(model, os_path, contents_manager, **kwargs): """convert notebooks to Python script after save with nbconvert replaces `ipython notebook --script` """ from nbconvert.exporters.script import ScriptExporter if model['type'] != 'notebook': return global _script_exporter if _script_exporter is None: _script_exporter = ScriptExporter(parent=contents_manager) log = contents_manager.log base, ext = os.path.splitext(os_path) py_fname = base + '.py' script, resources = _script_exporter.from_filename(os_path) script_fname = base + resources.get('output_extension', '.txt') log.info("Saving script /%s", to_api_path(script_fname, contents_manager.root_dir)) with io.open(script_fname, 'w', encoding='utf-8') as f: f.write(script) c.FileContentsManager.post_save_hook = script_post_save |
こうすることで、〇〇.ipynb ファイルを保存するたびに、同名の 〇〇.py ファイルが作成・保存されます。
- バージョン管理したい場合は、この 〇〇.py ファイルのみを対象に管理すればコード部分の差分のみを管理することが可能です。
- また、保存された 〇〇.py を以下のコマンドで実行すれば、マジックもExtensionも問題なく実行されます。これで分析コードをそのままバッチ実行可能になります。超便利。
1$ ipython 〇〇.py
最後に
ここまでまとめてみて、改めて Jupyter はほんとに高機能で便利だなと思いました。
ひとつの Notebook で完結して様々なデータソースから分析ができるというのは、分析のハードルを一気に下げられますし、少ない記述でたくさんのことができるというのも、分析時間の短縮に大きく貢献できるのではないでしょうか。
ともあれ、これからも拡張機能を開拓していき、充実した Jupyter ライフを送りたいと思います。
※ 上記の例の中でもし間違いがあればツッコミお願いします
※ 上記にあげたもの以外で、他におすすめの機能があればご教示いただけると非常に助かります
明日は @kuro_m88 さんです。楽しみ。
Author