CSVが遅かったらfeather形式で読み込もう
この投稿はrioyokotalab Advent Calendar 2020 15日目の投稿です。
とりあえずCSV
機械学習においてデータというのは、切っても切れない関係にあります。データを管理する形式はいくつかあります。画像データであれば、
- ラベル情報をファイル名にして画像ファイルを保存
- テキストデータにファイルパスとラベルをセットにしてスペース区切りで保存
- テーブルデータ(pandas1のデータフレーム)形式で、ファイルパスとラベル、インデックスなどを保存(例えば、CSV)
などなど...
Kaggleでは、データに対して、交差検証用のfold_idや、データの性質をハンドラベリングしたりなど、データに新たな情報を加えることが多かったり、データやラベルの統計情報、傾向などを把握するために操作するため、pandasのデータフレーム形式で持てるようにするのが一般的です。そのため、シンプルなCSVを使ってデータの管理をすることが多いのですが、生データでの可読性がある代わりに、csvは文字データでデータを保存しているためか、データ量が多くなると洒落にならないくらい遅くなります。
この記事では、CSV以外にもpandasのデータフレームとしての取り回しやすさを保持したまま、高速にIOが行えるデータ形式であるfeather2の紹介をします。
feathreフォーマット
中身はよくわかっていません。head
コマンドで覗いてみたら、ヘッダー情報をjson形式のようなもので保持していて、その後、よくわからないバイナリ情報がだらだらと続いていました。
pyarrowってやつで読めるものらしいのですが、要は、pandasで読めるなんかしらのデータ形式です。
速度比較
pandasで読み込めるテーブルデータの保存形式の速度比較には、次の記事が参考になります。
これを見ると多少の得意不得意はあるものの、全体的に安定して、feathre形式が高速なIOを行えていることがわかります。
手元の実験環境での検証
最近の実験で使っていた Bengali.AI Handwritten Grapheme Classification | Kaggleのデータセットを加工した物を使って実験を行います。
今回、実験に使うのは、137 x 236ピクセル,uint8のベンガル語の画像データを1次元データに並び替えて格納した、200840件のテーブルデータセットです。マシンスペックはABCI3の計算ノード1つ(80スレッド)で試します。
この200840件の画像データの読み出しにかかる時間を計測します。
実験1 CSV形式
15分以上はかけましたが、終わりませんでした。
終わりました。
dtypeとかを指定すればもっと早くなったかも。
実験2 feathre形式
feathre形式はマルチスレッドも入れてくれるようなので、だいぶ早いです。これくらいの時間ならストレスフリーに実験を回せます。
実験3 pngで保存して読み出し
試しに一つの画像を保存して、その画像を200840回読み出してみます。
こちらもシングルスレッドで回しているにしてはだいぶ早いです。画像の大部分が白く、情報が少ないため、pngの圧縮がうまくはたらいて早く読み出せたのかもしれません。
まとめ
pandasにはfeathre形式を読み込むためのread_feathre
メソッドとfeathre形式に書き込むためのto_feathre
メソッドがあります。データの読み出し速度に悩んだ場合は、検討してみるといいと思います。特に、すべてのデータをとりあえずメモリ上に乗っけてしまいたいという場合には、いい選択肢になると思います。
他にもpandasが扱えるデータには、parquetと呼ばれるデータ形式やhdf5というデータ形式もあります。それぞれのデータ形式には、そのデータ形式がある理由になる得意な状況というのが存在するので、それらにも目を通して、必要に応じて様々なデータ形式を使い分けられるようになりたいですね。