はじめに
オブジェクトをファイルにして保存する方法です。
機械学習では、前処理済みのデータ、学習済みのモデルなどを残したいときなどに使用します。
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ファイルを取り扱えるので、ぜひ活用してください。