feather - pandasの読み書きを高速化
kaggleに参加して巨大なCSVファイルを読み書きしていると、それだけで数分近くかかってしまうことがある。 そこで紹介されていたfeatherというDataFrame保存用ライブラリを使ってみた。 featherはpandasのDataFrameを高速に保存、ロードするために開発されたApache Arrowのpythonラッパーだ。
Apache Arrow特有のカラム型メモリ管理をすることで、データの読み書きを高速化しているそうだ。 ベースになっているApache Arrowが他言語や他オープンソース(SparkやHadoop)との互換性を重視しているために、feather形式で保存すればRなどでも読み込める。
featherのインストールはpipから簡単にできる。
pip install feather-format
使い方も簡単でwrite_dataframe、read_dataframeを呼ぶだけ。
import feather import pandas as pd #データフレームの読み込み df = feather.read_dataframe(path_feather) #データフレームの書き込み feather.write_dataframe(df, path_feather)
またpandasのバージョン0.20.0からpandas.DataFrame.to_featherやpandas.read_featherというメソッドが追加されているので、以下のような方法でも使える。
import pandas as pd #データフレームの読み込み df = pd.read_feather(path_feather) #データフレームの書き込み df.to_feather(path_feather)
約18列、150000行のデータのデータセットで、csvとfeatherそれぞれの読み書きの速度を計測すると、
読み込み速度
# csvからの読み込み %time df = pd.read_csv(path_csv) # feather formatからの読み込み %time df = pd.read_feather(path_feather) %time df = feather.read_dataframe(path_feather)
CPU times: user 29.1 s, sys: 27.7 s, total: 56.8 s Wall time: 1min 38s CPU times: user 5.53 s, sys: 10.1 s, total: 15.6 s Wall time: 37.7 s CPU times: user 5.46 s, sys: 11.1 s, total: 16.5 s Wall time: 35.7 s
書き込み速度
# csvへの書き込み %time df.to_csv(path_csv) # featherへの書き込み %time df.to_feather(path_feather) %time feather.write_dataframe(df, path_feather)
CPU times: user 53 s, sys: 11.4 s, total: 1min 4s Wall time: 1min 30s CPU times: user 18.3 s, sys: 10.1 s, total: 28.4 s Wall time: 39 s CPU times: user 18.8 s, sys: 8.76 s, total: 27.5 s Wall time: 35.5 s
実時間で読み書きともに約2.5倍程度と非常に高速に動作することが確認できた。データセットの保存や読み込みに使えば大幅な時間の節約になる。 長期のデータには向いていない(破損とかに弱い?)そうなので、あくまで前処理したデータのキャッシュなどに使うのがいいと思う。
Talking Data AdTracking Fraud Detection Challenge
先日開催されたTalking Data AdTracking Fraud Detection Challengeに参加した。 Talking Data AdTracking Fraud Detection Challengeは中国の広告企業TalkingData主催のコンペで、広告クリックのログから不正なクリックを検出するというコンペティションだ。
TalkingData AdTracking Fraud Detection Challenge | Kaggle
初めてのkaggleで最終的な結果は1012位/3967位、上位26%だった。最初のコンペティションとしては悪くない結果だとは思うが、個人的にはもう少し上を狙いたかった。
コンペティション概要
以下の表に示す特徴を持つ、約180,000,000のレコードを持つ巨大なデータセットが与えられた。これらの特徴は全てLabel Encodeされていて全て整数で与えられている。
特徴量 | 説明 |
---|---|
ip | クリック元のipアドレス |
os | クリック元のOSやバージョンに関する情報 |
app | クリック元のアプリ |
device | クリック元の携帯電話の種類 |
channel | クリックされた広告のid的なもの |
click_time | クリックされた時刻 |
is_attributed | 目的変数 0は通常のクリック、1は不正なクリック |
ノートパソコンで今回のコンペに参加したが到底データセット全てはメモリに乗らず、一部を利用して学習させる方針で挑んだ。以下実際に参加したログと感想。
4/17
click_timeをパースして、day、hour、minuteなどの特徴量に分解した。 また一時間ごとのipの出現回数や、一日ごとのip-osの組み合わせの出現回数を特徴に加えxgboostでデータの一部を学習した。 与えられた学習データを学習用とテスト用に分けて評価したところ、テストデータでは約96%を達成。 しかしテストデータを送信したところ94%程度しか達成できなかった。2900人中2700位とか。
4/18
データセットの前半と後半でデータの傾向が少し違うらしい。 データが膨大でメモリに乗らないので(mac book airでは厳しいものがある)後半の一部を使用。 また単位時間あたりのipアドレス数を初めとした特徴量を導入した。 これらの結果リーダーボードで96.3%を達成。3000人中1800位とか。まだまだ。
4/21
当初はxgboostを使っていたが、Kernelを見ていると多くの人がlightgbmを使っている人が多かったのでlightgbmを試してみた。 lightgbmはカテゴリ変数をいい感じに取り扱ってくれるらしくて、そのおかげか96.5%を達成できた。あとパラメータによるのかもしれないが、少し計算速度が速くなったように感じた。
4/25
Kernelで公開されていた、次のクリックまでの経過時間を表すnext_clickという特徴を導入した。 この特徴量を導入しただけで飛躍的に精度が向上し、精度97.5を達成し3100人中上位700位まで一気に順位があがった。
4/23
Test Dataには4, 5, 9, 10, 13, 14時のデータしか含まれていないという情報がKernelで流れていた。 そこで学習に使うデータも4, 5, 9, 10, 13, 14時に絞ってみたところ、精度97.82を達成して3300人中500位近くまで順位を上げることが出来た。
4/25日以降
他に何個か特徴量を試したが精度の向上に繋がることはなかった。途中で最高精度を達成したファイルを直接書き換えてしまい、ロールバックすることも出来ず精度97.5あたりをうろついていた。怒涛の勢いで追い上げをくらい、順位を3900人中1000位近くまで落としてしまった。
最終日に誰かがディスカッションボードで精度98.11(上位5%程度の精度)のKernelを公開して物議を醸していて笑った。
感想
初めてKaggleのコンペティションに参加してみての感想としては、Kernelで初心者向けのコードが公開されていたりするので、英語さえ読めれば参加のハードルは低いと思った。正直、機械学習用のsklearn、xgboost、lightgbm、kerasなどのライブラリはpythonが使えれば中身を理解していなくても動かせてしまう(それで勝てるかは別問題として)。参加してみるとDiscussionとかで色々な知識を身につけることが出来るので、機械学習とかに興味がある人はとりあえず参加してみれば力をつけることが出来るのではないかと思う。ただ常時kaggleのことが気になってしまって他の作業ができなくなるののにだけは注意方がいい。
やはり精度を上げるための肝は、いかに優れた特徴量を設計するかにかかっているように感じた。下手な特徴量では逆に精度をさげてしまうため、効率的に有効な特徴量を見つけていくノウハウを学ぶ必要がある。
今回の反省点としては、
- 試してみた特徴量やプログラムは、リーダーボードのスコアと一緒に管理しておく。
- 積極的にKernel、Discussionを見て人の意見を取り入れていくこと。
- 一度作成したモデルもしっかり保管しておく。きちんと管理しておけば、最後の最後でBaggingやStackingして少し精度を挙げられる可能性がある。
あたりであろうか。
またCERNのコンペティションやロシアの広告会社Avitoのコンペティションが開催されるようなので参加してみようかと思う。Kaggleに参加してみたいけど難しそうと思っている人は、とりあえず適当なこんぺ