CSVが遅かったらfeather形式で読み込もう

この投稿はrioyokotalab Advent Calendar 2020 15日目の投稿です。

adventar.org

とりあえずCSV

機械学習においてデータというのは、切っても切れない関係にあります。データを管理する形式はいくつかあります。画像データであれば、

  • ラベル情報をファイル名にして画像ファイルを保存
  • テキストデータにファイルパスとラベルをセットにしてスペース区切りで保存
  • テーブルデータ(pandas1のデータフレーム)形式で、ファイルパスとラベル、インデックスなどを保存(例えば、CSV

などなど...

Kaggleでは、データに対して、交差検証用のfold_idや、データの性質をハンドラベリングしたりなど、データに新たな情報を加えることが多かったり、データやラベルの統計情報、傾向などを把握するために操作するため、pandasのデータフレーム形式で持てるようにするのが一般的です。そのため、シンプルなCSVを使ってデータの管理をすることが多いのですが、生データでの可読性がある代わりに、csvは文字データでデータを保存しているためか、データ量が多くなると洒落にならないくらい遅くなります。

この記事では、CSV以外にもpandasのデータフレームとしての取り回しやすさを保持したまま、高速にIOが行えるデータ形式であるfeather2の紹介をします。

feathreフォーマット

中身はよくわかっていません。headコマンドで覗いてみたら、ヘッダー情報をjson形式のようなもので保持していて、その後、よくわからないバイナリ情報がだらだらと続いていました。

pyarrowってやつで読めるものらしいのですが、要は、pandasで読めるなんかしらのデータ形式です。

速度比較

pandasで読み込めるテーブルデータの保存形式の速度比較には、次の記事が参考になります。

towardsdatascience.com

これを見ると多少の得意不得意はあるものの、全体的に安定して、feathre形式が高速なIOを行えていることがわかります。

手元の実験環境での検証

最近の実験で使っていた Bengali.AI Handwritten Grapheme Classification | Kaggleのデータセットを加工した物を使って実験を行います。

今回、実験に使うのは、137 x 236ピクセル,uint8のベンガル語の画像データを1次元データに並び替えて格納した、200840件のテーブルデータセットです。マシンスペックはABCI3の計算ノード1つ(80スレッド)で試します。

この200840件の画像データの読み出しにかかる時間を計測します。

実験1 CSV形式

15分以上はかけましたが、終わりませんでした。 終わりました。 f:id:deoxy:20201215221753p:plain

dtypeとかを指定すればもっと早くなったかも。

実験2 feathre形式

f:id:deoxy:20201215220033p:plain

feathre形式はマルチスレッドも入れてくれるようなので、だいぶ早いです。これくらいの時間ならストレスフリーに実験を回せます。

実験3 pngで保存して読み出し

試しに一つの画像を保存して、その画像を200840回読み出してみます。

f:id:deoxy:20201215220539p:plain

こちらもシングルスレッドで回しているにしてはだいぶ早いです。画像の大部分が白く、情報が少ないため、pngの圧縮がうまくはたらいて早く読み出せたのかもしれません。

まとめ

pandasにはfeathre形式を読み込むためのread_feathreメソッドとfeathre形式に書き込むためのto_feathreメソッドがあります。データの読み出し速度に悩んだ場合は、検討してみるといいと思います。特に、すべてのデータをとりあえずメモリ上に乗っけてしまいたいという場合には、いい選択肢になると思います。

他にもpandasが扱えるデータには、parquetと呼ばれるデータ形式やhdf5というデータ形式もあります。それぞれのデータ形式には、そのデータ形式がある理由になる得意な状況というのが存在するので、それらにも目を通して、必要に応じて様々なデータ形式を使い分けられるようになりたいですね。