【Python入門】pickleファイルへ保存し、読み込む方法

pandas

はじめに

オブジェクトをファイルにして保存する方法です。

機械学習では、前処理済みのデータ、学習済みのモデルなどを残したいときなどに使用します。

Pythonの標準ライブラリpickleではなく、Pandasを使った簡単なやり方を紹介します。

オブジェクトの保存

サンプルオブジェクトの作成

pickleファイルに保存するオブジェクトを用意します。

ワインデータセットを使って、ランダムフォレストのモデルを作成します。

import numpy as np
import pandas as pd

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

from sklearn import datasets

# wine データセットを読み込む
wine = datasets.load_wine()
X = wine['data']
y = wine['target']

# 説明変数をpandas.DataFrameに入れ、カラム名を付ける
df_X = pd.DataFrame(X, columns=wine['feature_names'])

# 説明変数を2個に絞る
df_X = df_X[['magnesium', 'alcohol']]

# 学習データとテストデータに分ける
X_train, X_test, y_train, y_test = train_test_split(df_X, y,
                                                    test_size=0.2,
                                                    random_state=0,
                                                    stratify=y)

# ランダムフォレストオブジェクトの生成
forest = RandomForestClassifier(n_estimators=500, random_state=1)
# モデルを学習データに適合
forest.fit(X_train, y_train)

ワインデータセットは、scikit-learnで提供されているワインの品質データです。
 scikit-learnの公式サイト(外部リンク)

このデータを使って、ワインの種類を分類する機械学習を試すことができます。
上記のコードで、「forest」と名付けたモデルが作成されました。

モデル(オブジェクト)の中身を確認しておきます。

# オブジェクトの中身
vars(forest)

vars(オブジェクト)で、オブジェクトの中身(辞書:dict型)を見ることができます。
 Pythonの公式サイト(外部リンク)

pickleファイルとして保存

モデル(オブジェクト)をpickleファイルとして保存します。

pickleファイルは、オブジェクトをそのままの状態で保存でき、そのままの状態に読み込むことができます。

to_pickle(path)メソッド

pickleファイルへの保存は、Pandasのto_pickle(path)メソッドを使用します。
 Pandasの公式サイト(外部リンク)

pathに、pickleファイルのファイル名と保存する場所を指定します。
ファイル名のみを指定すると、カレントディレクトリに保存されます。

カレントディレクトリは、次のコマンドで確認できます。

# カレントディレクトリ名の取得
%pwd


モデル(オブジェクト)「forest」を、カレントディレクトリにファイル名「forest.pkl」として保存します。

# ファイルの保存
pd.to_pickle(forest, 'forest.pkl')

Jupyter Notebookでコードを実行すると、先ほど確認したカレントディレクトリに、「forest.pkl」が作成されているはずです。

pandas.DataFrameの保存

pandas.DataFrameもオブジェクトなので、同じようにpickleファイルに保存できます。

データフレームのオブジェクトを用意します。

# データフレームの作成
df_sample = pd.DataFrame({'ID': list(range(5))})
display(df_sample)

5行1列のデータフレームを作成しました。

pandas.DataFrame(オブジェクト)「df_sample」を、カレントディレクトリにファイル名「df_sample.pkl」として保存します。

# ファイルの保存
pd.to_pickle(df_sample, 'df_sample.pkl')

モデル(オブジェクト)の保存と全く同じですね。

このような操作を、シリアライズやシリアル化、pickle化と呼びます。

オブジェクトの読み込み

pickleファイルの読み込み

pickleファイルとして保存したモデル(オブジェクト)を読み込みます。

read_pickle(path)メソッド

pickleファイルの読み込みは、Pandasのread_pickle(path)メソッドを使用します。
 Pandasの公式サイト(外部リンク)

pathに、pickleファイルのファイル名と保存してある場所を指定します。
ファイル名のみを指定すると、カレントディレクトリから読み込みます。

# ファイルの読み込み
forest_read_pickle = pd.read_pickle("forest.pkl") 
forest_read_pickle
RandomForestClassifier(n_estimators=500, random_state=1)

保存したモデルと、別のオブジェクト名で読み込みました。

モデル(オブジェクト)の中身を確認します。

# 中身の確認
vars(forest_read_pickle)

きちんと読み込めているようです。

ファイル名を変更して、データフレームの読み込みも試してみてください。

ファイルの圧縮

Pandasのto_pickle(path)メソッドは、2種類の方法で、ファイルを圧縮することができます。
・引数の指定
・拡張子の変更

それぞれにメリット・デメリットがあるので、状況に合わせて使用してください。

引数の指定(compression=’zip’)

Pandasのto_pickle(path)メソッドは、引数を「compression=’zip’」のように指定すると、指定した形式でファイルを圧縮します。

初期値は「compression=’infer’」で、「gzip」, 「bz2」,「zip」,「xz」が使用できます。

圧縮前のファイルサイズを確認しておきます。

import os

# ファイルのサイズ
print(os.path.getsize('forest.pkl'))

>> 2937759


モデル(オブジェクト)「forest」を、カレントディレクトリにファイル名「forest_zip.pkl」として保存します。

# ファイルの保存
pd.to_pickle(forest, 'forest_zip.pkl', compression='zip')

# ファイルのサイズ
print(os.path.getsize('forest_zip.pkl'))

>> 384553

ファイルのサイズが小さくなっており、圧縮されていることがわかります。

引数を指定しないで、pickleファイルを読み込んでみます。

# ファイルの読み込み
forest_zip_read_pickle = pd.read_pickle("forest_zip.pkl") 
forest_zip_read_pickle

pickleファイルの読み込みに失敗しました。

次は、引数を指定してpickleファイルを読み込みます。

# ファイルの読み込み
forest_zip_read_pickle = pd.read_pickle("forest_zip.pkl", compression='zip') 
forest_zip_read_pickle
RandomForestClassifier(n_estimators=500, random_state=1)

今度は、うまく読み込むことができました。
圧縮されたpikleファイルは、保存した時と同じ形式を指定して読み込む必要があります。

引数を指定して圧縮すると、拡張子からpickleファイルとわかりますが、圧縮されていることや圧縮の形式がわかりません。

拡張子の変更

Pandasのto_pickle(path)メソッドは、拡張子を「.zip」のように指定すると、指定した形式でファイルを圧縮します。

モデル(オブジェクト)「forest」を、カレントディレクトリにファイル名「forest.zip」として保存します。

# ファイルの保存
pd.to_pickle(forest, 'forest.zip')

# ファイルのサイズ
print(os.path.getsize('forest.zip')

>> 384545


拡張子「.zip」のpickleファイルを読み込んでみます。

# ファイルの読み込み
forest_read_pickle = pd.read_pickle("forest.zip") 
forest_read_pickle
RandomForestClassifier(n_estimators=500, random_state=1)

拡張子「.zip」でも、きちんと読み込むことができました。

拡張子を変更して圧縮すると、拡張子から圧縮ファイルであることはわかりますが、中身がpickleファイルだとわかりません。

まとめ

  • オブジェクトをpickleファイルとして保存し、読み込む方法がわかりました。
  • オブジェクトを圧縮してpickleファイルにする方法がわかりました。

XGBoostやLightGBMなどの機械学習では、前処理済みのデータを保存しておくと、時間を節約できます。
また、複数のモデルを保存しておいて、アンサンブルにより性能の向上を目指すこともできます。

Pandasを使用すると簡単にpickleファイルを取り扱えるので、ぜひ活用してください。

関連情報

タイトルとURLをコピーしました