職場で
「他のアナリストと分析結果を共有しやすくして欲しい。というか共有のJupyter環境を用意して欲しい」
という話があったのですが、環境の制約で、すぐに共有のJupyterを用意することはできなそうだったので、Google Cloud Datalabを使ってもらうことにしました。
今回はその環境作りと使い方の話になります。
Google Cloud Datalab
Datalabは、簡単に言うとGCPで機械学習するのに適したJupyter Notebookを使えるサービスです。サービスといってもDatalab自体の利用には料金が発生しないので、GCEの機械学習テンプレートみたいなものでしょうか。
Datalabのインスタンスも一つを共有するのではなく、利用するユーザ分作成が必要なのが特徴です。
アイコンはここから入手しました。
Datalab構築手順
Datalabの構築は以下の公式ドキュメントを元に、一括で行いました。
- Quickstart | Cloud Datalab Documentation | Google Cloud
- Using Cloud Datalab in a team environment | Cloud Datalab Documentation | Google Cloud
1. Datalabを利用するユーザのメールアドレスを取得する
インスタンス生成時に利用するので、利用ユーザのGCPアカウントのメールアドレスを把握しておきます。
2. インスタンス名を決める
次に各ユーザのDatalabが動作する(GCEの)インスタンス名を決めます。
インスタンスがどのユーザのものかわかれば良いので、「prd-datalab-名字」で作成することにしました。
3. インスタンスを作成する
インスタンス作成の手順は、以下の通りです。
gcloud config set core/project プロジェクトID
- ゾーンを設定
gcloud config set compute/zone asia-northeast1-a
- 作成時に
--for-user
フラグを設定し、手順1のメールアドレスを入力
datalab create --for-user 作成するユーザのメールアドレス インスタンス名
注意点
初回のdatalab createはCloud Source Repositoryにdatalab-notebooksリポジトリを作成するので、オーナー権限のあるユーザが実施する必要があります。もしくは事前にdatalab-notebooksリポジトリを手動作成しておけば大丈夫のようです。
4. 対象ユーザのIAMに以下の権限を付与する
Datalabを利用するユーザに、以下の権限を付与します。
- Compute インスタンス管理者(v1)
- サービス アカウント ユーザー
ドキュメントにはroles/iam.serviceAccountActor
が必要とありますが、サービスアカウントユーザの役割を参照すると、以下のような記述があるため、これで動作します。
ユーザーに対して
compute.instanceAdmin
役割をiam.serviceAccountUser
役割と一緒に付与すると、そのユーザーはサービス アカウントを使用する Compute Engine インスタンスを作成および管理できるようになります。
5. (すぐに利用しないのであれば)インスタンスを停止する
Datalabのサービス起動後であれば、自動タイムアウトがありますが、createしただけでは動作していないため、作成したインスタンスは停止しておきます。
datalab stop インスタンス名
利用手順
Datalabはユーザ毎にインスタンスが必要なため、個別にインスタンスを作成しています。
接続方法
GCPのコンソールからGoogle Cloud Shellを起動します。
プロジェクトがDatalabのインスタンスを作成する場所になっているかを確認し、なっていなければ変更してください。
- 変更する場合は、以下のように入力する
gcloud config set core/project プロジェクト名
あとは以下の起動コマンドを実行すると起動します。
datalab connect インスタンス名
初回実行時は、ホストの登録と鍵登録の問い合わせがあるので、適切に許可してください(こだわりがなければノンパスでOK)。
後はGoogle Cloud Shellの右上にあるウェブでプレビューを使い、ポートを8081に変更して起動するとDatalabが利用できます。
*左側のメニューを表示していると、ウェブでプレビューボタンが隠れていることがあるので、その場合はメニューを閉じてください
停止方法
Datalabの停止はいくつかの手順があり、いずれかで実施してください。
datalab stop インスタンス名
- 90分操作しない(自動でインスタンスが落ちます)
Datalabを使う
Jupyterと同様、以下のような流れで利用することができます。
- Notebookを作成後
- コードブロックを追加し
- コードを書いて
- 実行して
- 結果を確認
Notebookの共有
作成したNotebookを他のメンバーと共有したい場合は、以下の手順でリポジトリにコミットします。
git管理されるのは/datalab/notebooks
配下なので、共有するNotebookを作成する場所に気をつけてください。
共有を受ける側のメンバーは、ungitを使い、fetch + mergeで自身のgitリポジトリを更新することで、他のメンバーが作成したNotebookを取得することができます。
グラフタイトルの日本語化
デフォルトのままだとグラフタイトルに日本語が使えないので、日本語フォントをなんらかの方法で設定してください。
設定はNotebookを利用して、
例えば以下のようにリポジトリ配下に置いて利用したり
import matplotlib.pyplot as plt import matplotlib as mpl import matplotlib.font_manager as fm import sys import urllib.request reload(sys) sys.setdefaultencoding('utf-8') urllib.request.urlretrieve("https://github.com/byrongibson/fonts/blob/master/backup/truetype.original/takao-gothic/TakaoPGothic.ttf?raw=true", 'TakaoPGothic.ttf') prop = fm.FontProperties(fname='./TakaoPGothic.ttf') plt.plot([1,23,2,4]) plt.ylabel('some numbers') plt.title('日本語', fontproperties=prop) plt.show()
Pythonのフォントディレクトリに配置して利用したりすると、日本語で表示することができます。
- 対象のフォントを.fontディレクトリに配置(実施後はDatalab再起動)
!mkdir -p ~/.fonts/ !cp TakaoPGothic.ttf ~/.fonts/ !fc-cache -fv !rm -rf ~/.cache/matplotlib/
- グラフの確認
import matplotlib.pyplot as plt import matplotlib as mpl import matplotlib.font_manager as fm font = {"family": "TakaoPGothic"} mpl.rc('font', **font) plt.plot([1,23,2,4]) plt.ylabel('some numbers') plt.title(u'日本語') plt.show()
Rを使うには
Rを使う方法もありそうなのですが、本家にプルリクが出ているので、これがマージされるのを待てるのであれば待ったほうがいいかもしれません。
- 使う方法:https://stackoverflow.com/questions/47721352/how-can-one-use-r-within-google-cloud-datalab-notebook
- プルリク:https://github.com/googledatalab/datalab/pull/1881
ちなみに
別のユーザのインスタンスを起動させようとすると、以下のようなエラーメッセージが表示されます。
$ datalab connect 別のユーザ用のインスタンス The specified Datalab instance was created for 本来のユーザのメールアドレス, but you are attempting to connect to it as 自分のメールアドレス. Datalab instances are single-user environments, and trying to share one is not supported. To override this behavior, re-run the command with the --no-user-checking flag.
つまり、Datalab起動時に--no-user-checkingフラグを付けると、一つのインスタンスをみんなで触ることもできるようです。
実際できました
ただ、編集がコンフリクトすることも考えると、やはり個別にインスタンスを用意するのが良いと思います。