[ほぼCLI]Kaggleからデータをダウンロード/Kaggleへデータをアップロード

Kaggle Notebookを使っていると、GPUの週ごとの割り当てクオータが逼迫してきて、Google Colaboratoryなどの代用作業環境を用意したりということがあると思います。
そういった時に、Kaggle Notebookで使っているデータセットをダウンロードする必要がありますが、一つ一つをダウンロードするのは手間だし、特に大きなデータセットは非常に時間がかかります。
そこで利用したいのがkaggle APIです。
これを利用することでKaggleのデータを作業環境にダウンロードする手間が大幅に削減できます。
また、作業環境で作成したデータセットをKaggleにアップロードする時にもkaggle APIが役立ちます。
前提として、Google DriveをGoogle Colaboratoryにマウントする想定でやっていきます。
# 準備
Kaggleの[Settings](https://www.kaggle.com/settings)から、APIトークンを発行します。
「Create New Token」ボタンを押すと、`kaggle.json`ファイルがダウンロードされます。
![スクリーンショット 2024-12-15 19.30.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/8a6603d6-d2a1-6af5-8ea7-629fcb0c9055.png)
次にこの`kaggle.json`ファイルをGoogle Driveの適当なフォルダにアップロードします。
例えば、ここではマイドライブ配下の「Kaggle」フォルダを作ってアップロードしておきます。
![スクリーンショット 2024-12-15 19.33.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/64b1015e-8b65-7ceb-cbf4-2fdacc4d71e9.png)

これができたら次はGoogle ColaboratoryのNotebookを開いて、以下のセルを作って実行し、Google Driveをマウントさせます。
```python
from google.colab import drive
drive.mount("/content/gdrive")
```
このセルを実行すると、以下の画像のような誘導がいくつかくるので、逐一指示に従って認証します。
![スクリーンショット 2024-12-15 19.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/15a24102-aa54-7d60-62ee-afc0313a58e0.png)

認証ができたら次のセルを実行して、先ほどアップロードしたAPIトークンを使いダウンロードやアップロードができるようにします。
```python
import os
# kaggle.jsonをアップロードしたフォルダのパスを指定する。
os.environ['KAGGLE_CONFIG_DIR'] = '/content/gdrive/MyDrive/Kaggle'
```
ここまでで準備は完了です。
なお、Google Driveのマウントや`kaggle.json`へのパスの指定はノートブックのプロセスごとに行う必要があります。(`kaggle.json`のアップロードは初回だけでOKです)

# Kaggleデータをダウンロードする場合
例えばこの[データ](https://www.kaggle.com/datasets/denkuznetz/traffic-accident-prediction)をダウンロードしたいとします。
このデータセットのパスを控えておきます。今回の例だと`denkuznetz/traffic-accident-prediction`です。
右上の「ダウンロード」ボタンからこのパスを確認することができます。(ちなみにこのコードスペニットは`kagglehub`を使った時のダウンロード方法です。`kagglehub`も便利ですが、データセットのアップロードはできません)
![スクリーンショット 2024-12-15 19.52.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/f301f184-e8f0-47da-35f7-76fad3564e3e.png)
さて、この控えたパスを使ってダウンロードをしていきましょう。
「Kaggle」フォルダ配下の「data」フォルダにダウンロードしたいとします。
```cl
!kaggle datasets download -d denkuznetz/traffic-accident-prediction -p /content/gdrive/MyDrive/Kaggle/data
```
さらに、ダウンロードされたデータセットはzip形式(`traffic-accident-prediction.zip`)であるため解凍を行います。
```
!unzip /content/gdrive/MyDrive/Kaggle/data/traffic-accident-prediction.zip -d /content/gdrive/MyDrive/Kaggle/data
```
これでダウンロードが完了です。
正直この程度のサイズのデータセットだとそこまでKaggle APIの有り難みは感じないかもしれないですが、これがLLMモデルのような巨大なデータになると、Kaggle APIなしではかなり不自由です。

# Kaggleへデータをアップロードする場合
例えば「Kaggle > data」フォルダをKaggleへアップロードしたいとします。
![スクリーンショット 2024-12-15 20.10.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/032e2940-4e34-9ff5-19de-f175449e3b67.png)
そのためにまずはアップロードのための設定ファイル(`dataset-metadata.json`)をこのフォルダにダウンロードしてきます。
```cl
!kaggle datasets init -p /content/gdrive/MyDrive/Kaggle/data
```
この設定ファイルがダウンロードできたら、アップロードするデータセットの`title`と`id`を適当に設定します。`title`の方は何でもOKですが、`id`の方は`<ユーザーネーム(display nameではない)/適当な名前>`にする必要があります。
以上のことを決めたら以下のセルを実行してください。
```python
import json

# 設定ファイルのパス
file_path = "/content/gdrive/MyDrive/Kaggle/data/dataset-metadata.json"

# 設定ファイルを読み込み
with open(file_path, "r", encoding="utf-8") as file:
    data = json.load(file)

# 指定の要素を変更
data["title"] = "hogehoge"
data["id"] = "tatsuokoshida/hogehoge"

# 変更をJSONファイルに上書き保存
with open(file_path, "w", encoding="utf-8") as file:
    json.dump(data, file, ensure_ascii=False, indent=4)
```
それができたら以下のコマンドでいよいよデータセットをアップロードします。
```cl
!kaggle datasets create -p /content/gdrive/MyDrive/Kaggle/data --dir-mode zip
```
アップロードが成功すると、格納されたデータセットのURLが出力されます。
![スクリーンショット 2024-12-15 20.25.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/3ebe44a2-40bd-ba88-ea60-95b96dfd6291.png)
出力されたURLをクリックすると、確かにアップロードされたのが確認できます！
![スクリーンショット 2024-12-15 20.27.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/b6ad5376-13ae-50ef-447d-50f0a749f5a4.png)
アップロードもダウンロードの時と同じことですが、やはり巨大なデータセットになるとKaggleへデータセットのアップロードがかなり困難になってきます。
例えば、ファインチューニングしたLLMモデルのような数GB〜のデータセットをまずはローカルにダウンロードして、それからKaggleのUIからアップロードするというのは、おそらくそれだけで1時間くらいかかってしまいます。
Kaggleの本題はいかに精度を上げるかという取り組みなので、このような所は効率よく済ませて、時間を確保していきたいものですね。