Kaggle環境の構築方法(GPUなし)

以前にGoogle CloudのGPUを利用してKaggle環境を構築するという記事を書きました。
→https://qiita.com/kyotoman/items/af838f7adf84f8de0f3c
ここではテーブルデータなどGPUを必要としないコンペ用の環境を作り方について、VSCodeをどう使うかといった具体的な方法に焦点を当てて記事にしたいと思います。

# 目的
・ローカル環境において、Kaggle側と同じ環境を作ることで、データ分析で必要なフレームワークやライブラリを使う時の環境差異による問題を発生しないようにする
・VSCodeを使うことでデバグを行いやすくする(ブレークポイント、シンタックスハイライト、定義元へジャンプ)

# 手段
・Dockerを使ってKaggle側と同じ環境を作る
・VSCodeの拡張機能「Dev Containers」を使う

# 具体的な手順
### ①DockerデスクトップとVSCodeをインストールする
以後の作業で、
```
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```
というエラーが出た時はDockerデスクトップが起動していないので、その時は立ち上げましょう。

### ②vscodeの拡張機能の「Dev Containers」をインストールする
↓をインストールして有効にしておく。
![スクリーンショット 2024-01-04 9.54.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/fb8bfa52-ad51-a5bd-7f0b-3c26d3bc55fd.png)

### ③KaggleのDockerイメージをpullしてくる
KaggleのDockerイメージのうち、好きなもの(基本的には最新のものが良い)を選んでpullしてくる。
KaggleのDockerイメージはここ↓から取得。
https://console.cloud.google.com/gcr/images/kaggle-images/GLOBAL/python
例えば下の画像で囲ったイメージをpullしたい場合は、
```
docker pull gcr.io/kaggle-images/python:ci-pretest
```
としてコマンドラインで実行すれば良い。
![スクリーンショット 2024-01-04 10.05.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/31781f77-eadd-0a87-6bf3-2c5988bc1cf2.png)
実行するべきコマンドはpullしたいイメージの各行ごとにある、縦の3点から「pullコマンドを表示」をクリックすることで確認することができる(下の画像)。
![スクリーンショット 2024-01-04 10.10.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/31c3a088-0d56-22ea-7850-bcd95c5a3ffa.png)

**注意**
GPUを使いたい場合は別のイメージを取得する必要がある。
https://console.cloud.google.com/artifacts/docker/kaggle-gpu-images/us/gcr.io/python
その場合は↑からイメージの取得を行うが、NVIDIAのドライバーなど他の調整要素が必要となっており、筆者の方では確認が取れていない。
GPUを使うKaggle環境の構築については以下のページを参照。
https://qiita.com/kyotoman/items/af838f7adf84f8de0f3c

### ④pullしてきたイメージからコンテナを作成して実行する
```
docker run -itd -p 8888:8080 -v "$(pwd)"/target:/home --name kaggle gcr.io/kaggle-images/python /bin/bash 
```
をコマンドラインで実行する。

**オプションについて**
・ -itdはおまじない。-i: 対話モードでコンテナを実行、-t: 疑似TTY（端末）を割り当て、-d: バックグラウンドでコンテナを実行の3つのオプションの組み合わせたもの。

・-v "$(pwd)"/target:/homeのオプションについては、”:”よりも前の部分がコンテナにマウントしたいローカルのホストマシンのディレクトリであり、”:”より後の部分がマウント先のコンテナのディレクトリである。コンテナにディレクトリをマウントすることでデータファイルなどの展開が楽になる。

・--name kaggleでは、コンテナのイメージ名を”kaggle”と命名している。

・-p 8888:8080では、ローカルのホストマシンのポート8888をコンテナ内のポート8080にマップしています。もしホストマシンですでに8888ポートが使われてしまっている場合は代わりに8889などを使う。

**エラーが出たら**
```
E: You don't have enough free space
```
というエラーが出たら、Dockerで使うことができるストレージの容量不足なので、ホストマシンの使用可能なストレージを確認した上で、Dockerデスクトップから使用できる容量を増やせばOK。

具体的な手順は、Dockerデスクトップの歯車アイコンから「Resources」でDisk image sizeを大きくする。
![スクリーンショット 2024-01-04 11.45.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/f292549c-52e0-4e66-65ae-6a3129db3ba9.png)

ただし、繰り返しになるが、ホストマシンのストレージの余裕には気を付ける必要がある。
不用意にDockerで使うことができるストレージを増やすと、ホストマシンにおける重要な処理が行えなくなってしまう可能性があるため注意。

まだ同様のエラーが起きる場合は、おそらく以前に作成したイメージやコンテナの残骸が残っているためなので、
```
docker system prune
```
で一掃できる。
このうえでもう一度冒頭の
```
docker run -itd -p 8888:8080 -v "$(pwd)"/target:/home --name kaggle gcr.io/kaggle-images/python /bin/bash 
```
を行えば解決するはず。

### ⑤VSCodeを使ってコンテナ内で作業を行う
まず、作成したコンテナが起動しているか確かめる。
コマンドラインでdocker psと打ち込めば、起動しているコンテナが表示される(下画像)。
![スクリーンショット 2024-01-04 10.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/018963b2-9c66-c72a-d306-689805e1b3fa.png)
おそらく④の作業を行なった後ではすでに起動しているはず。
起動していない場合はdocker start kaggleと打ち込むことでコンテナを起動できる。

コンテナが起動していることが確認出来たら、VSCodeでCtrl + Shift + pでコマンドパレットを開き、「開発コンテナ：実行中のコンテナにアタッチ」を選択する。

![スクリーンショット 2024-01-04 10.50.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/1a5beea1-43bd-e741-c20d-fa186fbe278f.png)

コンテナの中に入ると、rootディレクトリがデフォルトで開かれている。
自分で指定したマウントディレクトリを開くと作業が便利なので、VSCodeのメニューバーにある「ファイル」から「フォルダを開く」で、指定したディレクトリを開く。
今回の例では、rootディレクトリと同列のhomeディレクトリがマウントしたディレクトリであるから、homeディレクトリを開く。

### Jupyterの拡張機能
コンテナ内のVSCodeでJupyterの拡張機能を入れる。
VSCodeでJupyter Notebookが使えると、KaggleのNotebookと同じ使い方ができて便利である。
しかし、ローカルのホストマシンにはすでにJupyterの拡張機能が入っているかもしれないが、コンテナ内のVSCodeにはJupyterの拡張機能がまだ入っていないので入れておく。

下の画像は、Kaggleで使っているnotebookをVSCodeで開いている時のものである。
Jupyterの拡張機能を入れることで、このファイルの実行を行うことができる。

![スクリーンショット 2024-01-04 11.21.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/2be7a4f8-68d0-d732-7634-3618f3c1e76f.png)

# Tips
### DeepLを活用する

・chromeの拡張機能としてdeeplを入れる＆DeepLのアプリを使う

Kaggleは基本的に英語なので、英語が苦手な人はその部分でも認知に負荷がかかる。
そんなところに認知のリソースを使ってしまうと、肝心なデータ分析などに思考力が使えなくなるのでなんとかしたい。
そこでchromeの拡張機能にはDeepL翻訳があるので、それを利用するとかなり作業効率が上がる。
![スクリーンショット 2024-01-04 15.27.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/3cbd21eb-2dd3-a671-0112-9720573b31c2.png)
以下の画像はKaggleのページで、chromeの拡張機能としてのDeepLを使っている例。
翻訳したい文章をハイライトして端にあるDeepLのマークをクリックすると翻訳が表示される。
![スクリーンショット 2024-01-04 15.29.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/20c41371-d2ec-d0d1-39ce-a2fcb39a51ac.png)

ただしこのchromeの拡張機能は、当然ながらVSCodeの環境や、chromeであってもkaggleの編集中のnotebookに記載されている外国語を翻訳することはできない(下の画像参照)。

![スクリーンショット 2024-01-04 15.35.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/9c047e85-f136-e5c9-46a7-ec59fb546eac.png)

上の画像はKaggleでnotebookを編集している時のようすだが、英語の文章をハイライトしてもDeepLの拡張機能が動作しない。

そこで使いたいのがDeepLのアプリである。

アプリ版を使うことでどの環境であっても「Ctrl + C + C」ですぐに翻訳できる(ただしウィンドウの画面が遷移してしまうため、chromeの拡張機能に比べると使い勝手は劣る)。
以下の画像が、先ほどのKaggleのnotebookを編集している時のハイライト部分を翻訳しているときのようすである。
![スクリーンショット 2024-01-04 15.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/a0a3b6a0-e4e3-033f-2b0c-0f3528fc2b44.png)

### ブレークポイントを使ってnotebookのデバッグを行う
VSCodeにはブレークポイントという便利なデバッグ機能が備わっている。
この機能はプログラムのソースファイルの任意の場所で実行を一時停止して、その時の変数の値などを確認できる機能である。
この機能によって想定外の変数の値を見つけてバグの発見をすることができる。

ブレークポイントの使い方はこちら↓を参照。
https://qiita.com/_ken_/items/c5aa4841be74b06530b4

しかしipynb形式のnotebookのファイルには「ブレークポイント」を立てることはできるのだが、その地点で処理が一時停止されずにデバッグを行うことが出来ない。
そこで、notebookでも満足にブレークポイント機能を使うことができるようにする。

端的にその手段を述べると、notebookファイルをPythonファイルに変換して、その変換したPythonファイルにブレークポイントを立てることによって実現する。

具体的な手順としては、notebookファイルを開いた時の上部にある横並びの3点をクリックし、「エクスポート」を行う。(下画像)
![スクリーンショット 2024-01-04 11.28.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/5312c23f-8be1-d4ae-2a96-2d0b1c6f740b.png)

上記のnotebookファイルをPythonファイルに変換したものが下の画像。
このファイルにブレークポイントを立てることによってデバッグを行いやすくなる。

![スクリーンショット 2024-01-04 11.33.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/32408b32-a7cb-1c30-2eab-f0918ddb36b8.png)