pandas(Pythonのデータ処理用のライブラリ)は、条件を指定してデータを取り出したりするのに便利なライブラリです。
しかし、kaggleのコンペのように1億レコード(行)もある大量データだと、メモリ不足に陥ったり、処理速度が遅くなることがありませんか?
そこで、この記事ではpandasをつかったデータの最適化(メモリ容量の最適化)、高速化について解説します!
\IT未経験者からのサポートあり!転職サービス3選!!/
サービス名 | |||
---|---|---|---|
未経験 | 未経験OK | 未経験の転職専用 | 経験者向け |
公開の求人数 | ITエンジニア全体で1万件以上 ITエンジニア未経験で600件以上 |
未公開 | 5,000件以上 |
利用対象 | 全職種 | IT特化 | IT特化 |
特徴 | ✓誰もが知る転職サービス ✓経歴を登録しておくとオファーが来る |
✓企業担当者と条件交渉 ✓スキルの身につく企業を紹介 |
✓IT専門のエージェントが対応 ✓転職成功すると年収200万円以上の大幅アップがある |
転職サポート内容 |
|
|
|
公式サイト | リクナビネクスト | テックゲート | レバテックキャリア |
メモリ容量の最適化
pandasにread_csvだけでデータを読み込むだけでは、無駄な領域まで使ってしまい、すぐにメモリ不足に陥ります。
ここでは、pandasにおいてできるかぎり少ないメモリ容量で処理できる方法を書きます。
大前提として、使用しないメモリ(変数)が出てきたら、その都度、delで解放していきます。
データに対して型を宣言する【メモリ容量最適化】
単純にpandasにread_csvしただけでは、最もデータ領域を使う型が選択されてしまいます。たとえば、int系だとint64が使われてしまいます。
数値の範囲が、127までの場合、int16で足りるのに、int64を使っていたら無駄な領域を使うことになります。
こんなときは、型を定義して、「astype」関数を組み合わせるなどして、メモリ容量を減らすことを検討します。
コードの例は以下の通りです。
data_types_dict = {
'timestamp': 'int64',
'user_id': 'int32',
'content_id': 'int16',
'content_type_id':'int8',
'task_container_id': 'int16',
'user_answer': 'int8',
'answered_correctly': 'int8',
'prior_question_elapsed_time': 'float32',
'prior_question_had_explanation': 'bool'
}
#データは以下からダウンロードしてください
#https://www.kaggle.com/c/riiid-test-answer-prediction/data
train_df = pd.read_csv('./riiid-test-answer-prediction/train.csv',nrows = 1000000)
#型を宣言しないと、無駄にメモリを使う(例:本来int8で足りるのに、int64で確保される)のでしっかり型宣言しておく
train_df = train_df.astype(data_types_dict)
メモリ容量を最適化する処理(関数)を実行する
以下のような関数を使ってメモリ容量を最適化します。
'''Function to reduce the DF size'''
# source: https://www.kaggle.com/kernels/scriptcontent/3684066/download
def reduce_mem_usage(df):
""" iterate through all the columns of a dataframe and modify the data type
to reduce memory usage.
"""
start_mem = df.memory_usage().sum() / 1024**2
print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
for col in df.columns:
col_type = df[col].dtype
if col_type != object:
c_min = df[col].min()
c_max = df[col].max()
if str(col_type)[:3] == 'int':
if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
df[col] = df[col].astype(np.int8)
elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
df[col] = df[col].astype(np.int16)
elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
df[col] = df[col].astype(np.int32)
elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
df[col] = df[col].astype(np.int64)
else:
if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
df[col] = df[col].astype(np.float16)
elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
df[col] = df[col].astype(np.float32)
else:
df[col] = df[col].astype(np.float64)
else:
df[col] = df[col].astype('category')
end_mem = df.memory_usage().sum() / 1024**2
print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
return df
関数は、カグラーさんが作ってくれたもの(作成者が、kaggleから居なくなってしまった?)を使わせて頂きます。
上記の方法で、自動的にメモリ容量の最適をします。
私が上記の関数を試したところ、約50%〜70%ほどのメモリ容量を削減できました。
本当にすべてのデータ(レコード)が必要か検討する
Kaggleの「Riiid Answer Correctness Prediction」コンペでは、1億レコードもあるデータセットを使います。
データ全てを使用して訓練させる必要はあるのでしょうか?
1億レコードの全てを使用する必要があるのかどうかを検討します。
コンペでは、1000万レコードほどで上位に行った人もいるので、全て使用する必要も無いと言えます。
分割してデータを渡して機械学習させる
機械学習アルゴリズムによっては、一度にデータを渡す物では無く、分割して渡すことができるものがあります(例:ニューラルネットワーク=NN系)。
そんなときは、ファイルからある程度読み込むことを検討します。
以下のようなイメージです。
- ファイル全体から1/10(先頭から)ほどのデータをメモリに読み込む
- 学習モデルに渡して学習
- ファイル全体から次の1/10ほどのデータをメモリに読み込む
- 学習モデルに渡して学習
実装例あり!pandasの処理の高速化
pandasが、データ容量が多くなると処理遅くなりがちです。
特に、for文でデータの参照をするとものすごく遅くなってしまいます。
そこで、改善した方法を記載します。
改善方法は以下の通り
やりたいこと | 方法 | かかった時間 |
---|---|---|
pandasのデータ参照 | for文にてpandasのiterrowsで参照 | 1分1秒 |
pandasのデータ参照 | for文にてpandasから配列に変換して参照 | 753ミリ秒 |
pandasのデータ更新 | for文にてpandasのiterrowsで参照 更新は、pandas.atで更新する |
1分25秒 |
pandasのデータ更新 | for文にてpandasから配列に変換して参照 更新は、pandas.atで更新する |
16秒 |
pandasのデータ更新 | for文にてpandasから配列に変換して参照 更新は、一旦更新元のデータを配列に格納して、for文抜けたあとで更新 |
979ミリ秒 |
次に実装例を示します。
独学で挫折した人向け・AI(機械学習)を短期間で学ぶ方法
独学で挫折してしまった人向けに、PythonとAI(機械学習)について、短期間で効率的に学ぶ方法を紹介します。
それは、プログラミングスクールを利用することです。
プログラミングができる人でも機械学習の習得は、難しいため、プロに教えてもらったほうが遥かに最短経路で身につけることができます。
筆者は、ITエンジニアでプログラミングは得意です。
しかし、AIについては、AIの考え方を学ぶところで挫折したためAIスクールに4ヶ月ほど通いました。
だから、現役のエンジニアがAIスクールに行くことは恥ずかしくありません!
いますぐにでもAI(機械学習)が学べるプログラミングスクールを検討している方へ! [afTag id=2402] [template id="10277"] 筆者について 筆者は、AIプログラミン[…]
まとめ
最近は、データ容量が多いkaggleのコンペが増えてきました。
今後も大量データの処理のスキルも必要になってきますね。
\IT未経験者からのサポートあり!転職サービス3選!!/
サービス名 | |||
---|---|---|---|
未経験 | 未経験OK | 未経験の転職専用 | 経験者向け |
公開の求人数 | ITエンジニア全体で1万件以上 ITエンジニア未経験で600件以上 |
未公開 | 5,000件以上 |
利用対象 | 全職種 | IT特化 | IT特化 |
特徴 | ✓誰もが知る転職サービス ✓経歴を登録しておくとオファーが来る |
✓企業担当者と条件交渉 ✓スキルの身につく企業を紹介 |
✓IT専門のエージェントが対応 ✓転職成功すると年収200万円以上の大幅アップがある |
転職サポート内容 |
|
|
|
公式サイト | リクナビネクスト | テックゲート | レバテックキャリア |