
LookerAPIを使ってPythonと連携して分析してみた(実践編)【データ利活用の道具箱#4】
本記事では、Googleが提供するデータ仮想化プラットフォームLookerを使うためのLookerAPIを紹介します。
前回の記事「準備編」では、LookerAPIを使うための環境構築方法を紹介しました。今回はその環境を利用して、機械学習のプロセスを自動化する方法を具体的に紹介します。
1.機械学習ではデータの品質が重要になる
機械学習のプロセスを自動化するために最初にすべきことは、データの品質を整えることです。品質が悪いと、データを見つけるのに時間がかかったり、間違ったデータで学習してしまったりします。すると学習効率が下がり、アウトプットの品質も下がってしまうのです。
通常のデータ利活用でも同じことが言えますが、大量データを使う機械学習では特に、データの品質が与えるインパクトは大きくなります。
2.データの品質を担保するLooker
そこでLookerの出番です。
LookerにはLookMLと呼ばれる独自のモデリング言語があります。LookMLを使うとユーザが使うデータを限定することができます。例えば、分析する対象とは全く関係ないデータや、信頼性に問題があるデータは分析のノイズにしかなりません。Lookerを使えば、そういったデータを使えないように制御できるのです。
Lookerについて詳しく知りたい場合は、過去の記事「Lookerでデータ指標の乱立を解決する 」 や 「 LookerAPIを使ってPythonと連携して分析してみた(準備編) 」を読んでみてください。特に「Lookerでデータ指標の乱立を解決する」では、Lookerを使ったデータ統制の方法を紹介しているので、参考になると思います。
3.一般的な機械学習のプロセス
データの品質が整ったら、そのデータを学習してモデルを作成するステップへと移ります。このとき、やみくもにデータを触るのは効率が悪いので、決められた手順に従って進めます。
一般的な機械学習のプロセスは以下の通りです。

参考:MLOps: 機械学習における継続的デリバリーと自動化のパイプライン | Cloud アーキテクチャ センター | Google Cloud
4.LookerAPIを使った機械学習プロセス自動化方法
LookerAPIというのは、Lookerが提供しているAPIです。LookerAPIでは、ユーザ登録といった管理業務だけでなく、データの取得といったデータ分析に便利な機能も提供しています。詳しく知りたい方は、 「 LookerAPIを使ってPythonと連携して分析してみた(準備編) 」を読んでみてください。
#1 データの抽出
ここではLookerAPIを利用して必要なデータを取得します。
具体的には、準備編で説明したPythonコードを利用して、データを探索し、取得します。
Lookerからデータを取得する事で、複数の環境にまたがって存在しているデータであっても見つける事ができるようになり、データ収集に掛かる時間を短縮できます。
#スキーマ一覧を取得する
sdk.connection_schemas('looker-private-demo')
#テーブル名を取得する
show_tables("looker-private-demo")
#カラム一覧を取得する
get_columns(connection_name="looker-private-demo",schema_name="thelook",table_name="order_items")
#在庫データを取得する
sql_query = sdk.create_sql_query(models.SqlQueryCreate(connection_name="looker-private-demo",sql="select * from inventory_items where sold_at is not Null"))
sql_identify = sql_query["slug"]
json_data = sdk.run_sql_query(slug=sql_identify,result_format="json")
df = pd.read_json(json_data)
以上によって、データが取得できました。

これらのデータには製品の在庫に関する情報が含まれているので、在庫の寿命を予測するモデルを作ってみます。
#2 データの分析、#3 データの準備
次に、データそのものを分析し、必要な前処理や特徴量を把握します。その上で、機械学習モデルに学習させるためのデータを準備します。
やり方を細かく書くと長くなってしまうので、ここではデータの準備に相当する前処理のコードのみを記載します。
Lookerを経由してデータを取得することで、データの検証自体はLookMLに任せる事が出来ます。つまり、Lookerを使うとデータの正しさを検証するプログラムを独自に用意する必要がなくなります。
💡Tips!:Lookerを利用するとデータ分析や、データの準備が楽になる
LookerはLookMLを利用してデータが統制されているので、実は思っていたデータとは違った!ということが起きにくいです。
そのため、データが正しいのかといった確認作業や、手戻りが軽減されることで、分析やデータの準備が楽になります。
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
inventory_data = df
#不要なカラムを削除する
drop_columns = ['id', 'product_name', 'product_sku']
inventory_data = inventory_data.drop(columns=drop_columns)
#不要なデータの穴埋め処理をする
inventory_data['product_brand'].fillna('Unknown', inplace=True)
#商品が売れるまでの時間計算する
inventory_data['created_at'] = pd.to_datetime(inventory_data['created_at'])
inventory_data['sold_at'] = pd.to_datetime(inventory_data['sold_at'])
inventory_data['days_to_sell'] = (inventory_data['sold_at'] - inventory_data['created_at']).dt.days
#ラベルのエンコーディング処理をする
label_encoders = {}
categorical_columns = ['product_category', 'product_brand', 'product_department']
for col in categorical_columns:
le = LabelEncoder()
inventory_data[col] = le.fit_transform(inventory_data[col])
label_encoders[col] = le
# データセットを分割する
X = inventory_data.drop(columns=['created_at', 'sold_at', 'days_to_sell'])
y = inventory_data['days_to_sell']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=29)
この処理で加工されたデータは次のようになり、赤い枠で囲まれたデータが説明変数で、青い枠で囲まれたデータが目的変数になります。

ここでは
①欠損値の除去・不要なカラムの除去
②カテゴリデータのカテゴリ変数への変換
③説明変数、目的変数の作成(今回は在庫の寿命)、データセットの分割
を実施しました。
参考までに、今回はPython側で前処理を実施しましたが、SQLを工夫する事で前処理をLooker側で実行させることもできます。
#4 モデルのトレーニング
今回は在庫の寿命予測モデルをランダムフォレストというアルゴリズムを使ってトレーニングを進めていきます。このアルゴリズムを使うと、複数の場合分けがなされた木構造のモデルが作成されます。そして、各木構造のモデルごとに予測値の平均を出し、それを使って在庫寿命を予測するモデルが出来上がります。

例えば、「scikit-learn」と呼ばれるライブラリを利用して上のようなモデルのトレーニングを自動で実行するコードがこちらです。
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error, mean_squared_error
# ランダムフォレストモデルを学習させる
rf_regressor = RandomForestRegressor(n_estimators=100, random_state=42)
rf_regressor.fit(X_train, y_train)
これで、在庫の寿命予測を実行するモデルを作る事ができました。
#5 モデルの評価
テスト用のデータを利用して、モデルの精度を評価します。
# 予測データをセットする
y_pred = rf_regressor.predict(X_test)
# MAE,MSEを計算してみる
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print(f"mae:{mae}, mse:{mse}")
目標の精度を下回っていた場合、再度分析をしたりアリゴリズムを変えたりして、モデルの精度を向上させます。
#6 モデルの検証
今回作ったモデルを例えば、在庫回転率が高い製品Xに適用することを考えてみます。もし、このモデルが比較的、寿命を長く予測するのであれば、ビジネス目的を満たさないと判断して導入を見送ります。なぜなら、このモデルを採用してしまうと製品Xが在庫切れを起こすリスクが高くなるからです。
このように、モデルの予測結果がビジネスに与える影響を踏まえてモデルの適用を判断します。
#7 モデルの提供、#8 モデルのモニタリング
検証が終わったモデルは、然るべき環境にデプロイし、利用者に提供します。このとき、モデルのメタ情報をBigQueryなどのDWHに登録します。メタ情報というのは、モデルの名前、バージョン、精度、保存場所などのことです。こういった情報を登録しておくことで、古いモデルにロールバックできたり、新しいモデルが古いモデルよりも精度が良いかどうか確認できるメリットがあります。
モデルをデプロイした後は、実際に運用しながら継続してモニタリングを行います。ここでも、Lookerが活躍します。
5.Lookerを活用したモデルのモニタリング方法
機械学習のモデルは、学習した時点のデータを利用して予測をします。一方で現実世界では、刻一刻とその実態は変化していきます。そのため、機械学習のモデルは時間が経つにつれて精度が下がる事が多いです。そのため、モデルの精度を監視して、精度が悪ければモデルを更新する必要があります。LookerはBIツールとしての機能も持っているので、Lookerと接続したDWHに予測結果を送信し、Looker上に精度監視モニタを作る事で、機械学習モデルの運用なども出来るようになります。

おわりに
この「データ利活用の道具箱」は、データ利活用を推進したり、データをもっと活用したいと奮闘している皆さんに役立つ情報をnoteで発信しています。ぜひ他の記事もご覧ください!
ウルシステムズでは「現場で使える!コンサル道具箱」でご紹介したコンテンツにまつわる知見・経験豊富なコンサルタントが多数在籍しております。ぜひお気軽にご相談ください。