Snowflake Notebooksで始める機械学習パイプライン構築:LightGBMとデータ前処理の実践
本記事では、2024年5月25日
に登場したSnowflake Notebooksを使い、Titanicデータセットを用いて機械学習パイプラインを構築していきます。
具体的には、データの前処理、Pandas DataFrameへの変換、scikit-learn
とLightGBM
を使った機械学習モデルの構築と評価を行います。
目次
Snowflakeとは
クラウドベースのデータウェアハウスやデータプラットフォームとしての役割を持ち、データの保存、分析、処理を行うための専用プラットフォームです。(類似サービスとして、AWSのRedshift、GCPのBigQueryが挙げられます)。
Snowparkとは
Snowparkは、Snowflakeのデータを使ってプログラムを書ける便利なツールです。データをSQLだけではなく、PythonやJava、Scalaのようなプログラミング言語でも操作できるようにするものです。
以下、3つのSnowparkのポイントを記載します。
-
データフレーム
Snowparkは、データフレームという形式でデータを扱います。データフレームは、テーブルのような形でデータを操作できる便利なツールです。例えば、Pythonの「Pandas」や「Spark」を使ったことがある人なら、同じような感覚でデータを操作できます。 -
分散処理能力
データが非常に大きくなっても、内部で自動的にデータを複数のノード(サーバー)に分散して処理します。これによって、データ量が増えても高速かつスケーラブルに処理できます。 -
PythonやScalaでデータ処理が可能
SQLが得意でなくても、PythonやScalaでデータ処理ができます。例えば、Pythonでデータを読み込んでフィルタリングしたり、集計したり、複雑な前処理をしたりするのが簡単です。
Snowflake Notebooksとは
Snowflake Notebooksは、Snowparkを使ってインタラクティブにデータ分析やプログラミングを行うためのノートブック型の開発環境です。データサイエンティストやエンジニアがSQLやPythonなどのプログラミング言語を使ってデータを操作し、リアルタイムで結果を確認できる環境を提供します。
実装
ここから、Titanicデータセットを用いて機械学習パイプラインを構築していきます。
前提として、データセットはSnowflakeのテーブルに保存されているものとします。
1. セッション取得
まず、SnowflakeのNotebook環境でアクティブなセッションを取得します。Snowflake Notebooksでは、ユーザーがNotebookを開いた時点でセッションが自動的に作成されます。
# 現在アクティブなセッションを取得(SnowflakeのNotebook環境では、ユーザーがNotebookを開いた時点で、必要な接続情報をもとに自動的にセッションが作成される仕組みがある)
from snowflake.snowpark.context import get_active_session
session = get_active_session()
get_active_session()
は、現在のアクティブなSnowflakeセッションを取得するための関数です。このセッションは、Snowflakeに接続してデータベース操作を行うために必要な接続情報を保持しています。
セッションには以下のような情報が含まれます。
- 接続先のデータベース名
- 接続先のスキーマ名
- 実行環境のウェアハウス名
- ユーザ名
- ロール名
2. SnowflakeのテーブルデータをSnowparkデータフレーム形式で取得
# "OZASA_TEST_DB"データベースの"STUDY"スキーマにある、"TITANIC"テーブルを取得
train_df = session.table("OZASA_TEST_DB.STUDY.TITANIC")
# 先頭5行を出力
train_df.limit(5)
Snowflakeのsession.table()
メソッドを使ってテーブルを取得した場合、その結果はSnowpark DataFrame
形式になります。
PASSENGERID | SURVIVED | PCLASS | NAME | SEX | AGE | SIBSP | PARCH | TICKET | FARE | CABIN | EMBARKED |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22 | 1 | 0 | A/5 21171 | 7.25 | None | S |
2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Thayer) | female | 38 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26 | 0 | 0 | STON/O2. 3101282 | 7.925 | None | S |
4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35 | 1 | 0 | 113803 | 53.1 | C123 | S |
5 | 0 | 3 | Allen, Mr. William Henry | male | 35 | 0 | 0 | 373450 | 8.05 | None | S |
3. 前処理
- 不要な列の削除: Name, Ticket, Cabin などの列を削除
- 欠損値の処理:
- Age: 欠損値を平均値で補完。
- Embarked: 欠損値を最頻値で補完。
- Sex 列の変換:
- male → 1
- female → 0
- 新しい特徴量 FamilySize の作成:
- FamilySize = SibSp + Parch + 1(自分自身を含む)
from snowflake.snowpark.functions import col, when, lit
# 1. 不要な列の削除(例: 'Name', 'Ticket', 'Cabin')
train_df_cleaned = train_df.drop("Name", "Ticket", "Cabin")
# 2. 欠損値の処理
# 'Age' の欠損値を平均値で埋める
age_mean = train_df_cleaned.select(col("Age")).agg({"Age": "avg"}).collect()[0][0]
train_df_cleaned = train_df_cleaned.fillna({"Age": age_mean})
# 'Embarked' の欠損値を最頻値で埋める
embarked_mode = train_df_cleaned.group_by("Embarked").count().order_by(col("count").desc()).limit(1).collect()[0][0]
train_df_cleaned = train_df_cleaned.fillna({"Embarked": embarked_mode})
# 3. データ型の変換
# 'Sex' 列を数値に変換('male' -> 1, 'female' -> 0)
train_df_cleaned = train_df_cleaned.with_column("Sex", when(col("Sex") == lit("male"), lit(1)).otherwise(lit(0)))
# 4. 新しい特徴量の作成
# 'FamilySize' = 'SibSp' + 'Parch' + 1 (自分自身を含む)
train_df_cleaned = train_df_cleaned.with_column("FamilySize", col("SibSp") + col("Parch") + lit(1))
# 結果を表示
train_df_cleaned.limit(5)
PASSENGERID | SURVIVED | PCLASS | AGE | SIBSP | PARCH | FARE | EMBARKED | SEX | FAMILYSIZE |
---|---|---|---|---|---|---|---|---|---|
1 | 0 | 3 | 22 | 1 | 0 | 7.25 | S | 1 | 2 |
2 | 1 | 1 | 38 | 1 | 0 | 71.2833 | C | 0 | 2 |
3 | 1 | 3 | 26 | 0 | 0 | 7.925 | S | 0 | 1 |
4 | 1 | 1 | 35 | 1 | 0 | 53.1 | S | 0 | 2 |
5 | 0 | 3 | 35 | 0 | 0 | 8.05 | S | 1 | 1 |
4. データをPandas DataFrameに変換
Snowflakeの前処理済みデータを取得し、Pandasのデータフレームに変換します。
SnowflakeのSnowpark DataFrame
をPandas DataFrame
に変換することで、機械学習ライブラリ(scikit-learn
など)を使った処理が可能になります。
# SnowflakeのデータをPandas DataFrameに変換
train_df_pandas = train_df_cleaned.to_pandas()
5. Scikit-learnで機械学習パイプラインを構築
Pandasデータフレームを使用して、Scikit-learn
で機械学習パイプラインを構築します。
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.metrics import accuracy_score
import lightgbm as lgb
# 特徴量と目的変数に分ける
X = train_df_pandas.drop('SURVIVED', axis=1)
y = train_df_pandas['SURVIVED']
# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数値データとカテゴリデータを分ける
numeric_features = ['AGE', 'SIBSP', 'PARCH', 'FARE', 'FAMILYSIZE']
categorical_features = ['SEX', 'EMBARKED']
# 数値データのスケーリングとカテゴリデータのエンコーディングを設定
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features), # 数値データのスケーリング
('cat', OneHotEncoder(), categorical_features) # カテゴリデータのOne-Hotエンコーディング
])
# LightGBMモデルを使ったパイプラインの構築
pipeline = Pipeline(steps=[
('preprocessor', preprocessor), # 前処理(スケーリングとエンコーディング)
('classifier', lgb.LGBMClassifier(random_state=42)) # LightGBM分類器
])
# モデルのトレーニング
pipeline.fit(X_train, y_train)
# テストデータで予測
y_pred = pipeline.predict(X_test)
# 精度の評価
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.4f}')
上記のセルを実行すると以下のエラーが出力されました。
ModuleNotFoundError: Line 2: Module Not Found: sklearn. To import packages from Anaconda, install them first using the package selector at the top of the page.
上記のエラーメッセージは、SnowflakeのNotebook環境(Snowflake WorksheetsやSnowparkなど)で使用しているPython環境に scikit-learn
パッケージがインストールされていないことを示しています。
SnowflakeのNotebook環境で外部Pythonライブラリを使用するためには、パッケージをインストールする必要があります。
そのため、ワークシート右上の「パッケージ」から、「Anacondaパッケージ」を開きます。
ここで、インストールしたいパッケージ(scikit-learn
)を検索してインストールします。
そしてエラーが出力されたセルを再実行します。
ModuleNotFoundError: Line 7: Module Not Found: lightgbm. To import packages from Anaconda, install them first using the package selector at the top of the page.
エラーが再度出力されました。
同様にlightgbm
をインストールします。
結果
パッケージをインストール後、再度コードを実行すると、以下のような結果が得られました。
`Accuracy: 0.8212`
約82%の精度でTitanicの生存者を予測できました。
まとめ
本記事では、Snowflake Notebooksを使って、Titanicデータセットに対して機械学習パイプラインを構築する方法を説明しました。SnowflakeのSnowparkを使ってデータを操作し、Pandas DataFrame
に変換後、scikit-learn
とLightGBM
を使ってモデルをトレーニングしました。
Snowflake Notebooks
は、SQLやPythonを使ったデータ分析や機械学習パイプラインの構築をシームレスに行える非常に強力なツールです。ぜひ使ってみてください。