はじめに
こんにちは、KCCS デジタルプラットフォーム部のヤンです。
私たちの部門ではDatabricksを活用したデータ分析基盤の構築や技術検証、Databricksの構築における課題の解決を行なっています。
AI/MLプロジェクトを進める際、モデルの精度向上と同じくらい重要なのが、「堅牢なデータパイプラインの構築」と「ベースラインモデルの迅速な確保」ではないでしょうか?
データの前処理に時間をかけすぎたり、「どのアルゴリズムを使うか」で悩みすぎてプロジェクト初期のエネルギーを浪費してしまうことはよくあります。
今回は、公開されている関西電力送配電の電力使用量データ(実績)を活用し、データ収集から前処理、そしてAutoMLを用いた需要予測モデルの構築までを一気通貫でDatabricks上で行った事例を共有します。
特に、Unity Catalog環境下でのデータ管理や、大規模データのスキーマ推論を高速化するTipsなども交えて解説します。
プロジェクト概要と技術スタック
本プロジェクトでは、関西電力送配電が提供する電力需給実績データを元に、将来の電力需要を予測しました。
- 使用データ: 関西エリアの需給実績の公表
- データ期間:2024年3月1日 〜 2025年12月8日
- 学習データ:2024/03/01 - 2025/10/31
- テストデータ:2025/11/01 - 2025/12/08
- 技術スタック
- Platform:Databricks (Runtime 16.4 LTS), Unity Catalog
- Core Logic:PySpark (Spark 3.5), Liquid Clustering
- AI/ML:Databricks AutoML, MLflow
💡 データの出典と取り扱いについて
本記事で参照している需給実績データは、経済産業省資源エネルギー庁の「系統情報の公表の考え方」に基づき、関西電力送配電株式会社が公式に公表している情報です。 ご利用にあたって等は、公式サイトに記載されている「サイトのご利用にあたって」および「取り扱い・免責事項」などの注意事項を必ずご確認ください。
⚠️ 免責事項
本記事は技術検証を目的としており、予測結果の正確性を保証するものではありません。
1. 全体アーキテクチャ
データの品質と信頼性を担保するため、Databricksが推奨するメダリオンアーキテクチャ(Bronze-Silver-Gold)を採用し、すべてのデータ資産をUnity Catalogで管理しました。
-
External Volume:元のCSVファイルを格納するUnity Catalog Volume領域
-
Bronze (Raw):元データをスキーマ変更なしでそのままロードした層
-
Silver (Feature):欠損値処理、時系列特徴量(Feature)エンジニアリング、Liquid Clusteringを適用した層
-
Gold (Inference):AutoMLモデルによる推論結果(Prediction)を保存する層
-
Data Flow:
UC Volume (CSV)→Bronze Table→Feature Engineering (Silver)→AutoML学習→Inference (Gold)
📚 参考文献
2. データ収集 (Bronze Layer)
最初のステップは、Unity Catalog Volumeに保存された大量のCSVファイルを読み込むことです。通常、inferSchema=Trueオプションは便利ですが、データ量が増えると全ファイルをスキャンするため、初期ロードの速度が著しく低下します。
そこで、samplingRatioオプションを活用してデータの一部(10%)のみをサンプリングしてスキーマを推論させることで、読み込み速度を劇的に改善しました。
💡 Expert Tip
samplingRatio オプションは、メタデータを持たない CSVやJSON などのテキスト形式データを読む際に非常に有効です。(ParquetやDelta形式はメタデータにスキーマ情報が含まれているため、この設定は不要です。)
# 設定クラス(パスやテーブル名を一元管理)
config = PipelineConfig()
def ingest_to_bronze(spark, config):
# CSV読み込み(速度最適化適用)
df_raw = (
spark.read.format("csv")
.option("header", True)
.option("inferSchema", True)
.option("samplingRatio", 0.1) # Tip: 10%のみサンプリングしてスキーマ推論(CSV/JSONで有効)
.option("encoding", "Shift-JIS")
.load(config.volume_path) # Unity Catalog Volumeパス
)
# メタデータ追加
df_bronze = df_raw.select(
F.current_date().alias("_ingest_date"),
F.input_file_name().alias("_source_file_name"),
# …… 省略 …… #
"*"
)
# Delta Tableとして保存
(df_raw.write.format("delta")
.mode("overwrite")
.saveAsTable(config.bronze_tbl)
)
📚 参考文献
3. 特徴量エンジニアリング (Silver Layer)
単なる「日時データ」だけでは、高精度な需要予測は困難です。Silver層では、モデルが時間の流れやパターンを理解しやすいように、以下の処理を行いました。
-
欠損値補間 (Imputation):関西電力のデータは非常にきれいですが、万が一のセンサーエラー等に備え、直前時間のデータで埋めるForward Fillを適用しました。
-
周期性の反映 (Cyclic Features):23時と0時は時間的に連続していますが、数値上は離れています。これをSin/Cos関数に変換し、時間の連続性を表現しました。
-
ラグ特徴量 (Lag Features):「1時間前の需要」「昨日の同時刻の需要」「先週の同曜日の需要」など、過去データを特徴量として追加しました。
-
Liquid Clusteringの適用:従来のZ-Orderインデックスに代わり、最新のLiquid Clusteringを適用して時系列クエリおよび書き込み性能を最適化しました。
💡 Deep Dive:なぜ Liquid Clustering を採用したのか?
- 柔軟なデータ配置:ディレクトリ構造を固定せず、データの増加に合わせてバックグラウンドで自動的にクラスタリングを行います。
- 時系列クエリの高速化:clusterBy("timestamp") を指定することで、特定の期間(例:学習データ期間)を抽出する際、Data Skipping(不要なファイルを読み飛ばす機能)が強力に働き、クエリが高速化されます。
- 書き込みの効率化:従来のZ-Orderに比べて書き込み時のオーバーヘッドが少なく、継続的なデータ取り込みパイプラインに適しています
def transform_to_silver(spark, config):
# ... (Timestamp変換ロジックは省略) ...
# Window定義
w_lag = Window.orderBy("timestamp")
df_features = (df_interpolated
.withColumn("hour", F.hour("timestamp"))
# [Point 1] 時間の連続性を表現 (Cyclic Features)
.withColumn("hour_sin", F.sin(2 * F.pi() * F.col("hour") / 24))
.withColumn("hour_cos", F.cos(2 * F.pi() * F.col("hour") / 24))
# [Point 2] 過去の需要パターンを反映 (Lag Features)
.withColumn("lag_1", F.lag("demand", 1).over(w_lag)) # 1時間前
.withColumn("lag_24", F.lag("demand", 24).over(w_lag)) # 1日前
.withColumn("lag_168", F.lag("demand", 168).over(w_lag)) # 1週間前
.na.drop()
)
# [最適化] Liquid Clusteringの適用
(df_features.write.format("delta")
.mode("overwrite")
.clusterBy("timestamp")
.saveAsTable(config.silver_tbl)
)
📚 参考文献
4. モデル学習:AutoML (Regression Mode)
今回のプロジェクトのハイライトです。複雑なアルゴリズム選定やハイパーパラメータチューニングを人手で行う代わりに、Databricks AutoMLを活用しました。
今回は、Silver層で自作した「ラグ特徴量」や「周期特徴量」の効果を直接検証したかったため、あえて時系列予報(Forecasting)モードではなく、 回帰(Regression)モードを選択して学習させました。
def train_automl_model(spark, config):
# 時系列基準でTrain/Test分割
train_end = "2024-11-01T00:00:00"
df_silver = spark.read.table(config.silver_tbl).orderBy(config.time_col)
train_df = df_silver.filter(F.col(config.time_col) < F.lit(train_end))
# AutoML実行 (Regressionモード)
summary = automl.regress(
dataset=train_df,
target_col="demand", # 予測ターゲット: 電力需要
time_col="timestamp", # 時間カラム(時系列スプリットに使用)
primary_metric="r2", # 評価指標
timeout_minutes=60, # 学習制限時間
experiment_name="kansai_power_prediction"
)
return summary
🔍 AutoMLが探索するアルゴリズムについて
「AutoML」と聞くと中身がブラックボックスになりがちですが、Databricks AutoML(回帰モード)は、実績のある以下の主要アルゴリズム群を総当りで検討します。
-
決定木・アンサンブル系:
- Decision Tree (scikit-learn)
- Random Forest (scikit-learn)
- XGBoost Regressor
- LightGBM Regressor
-
線形モデル系:
- Linear Regression with SGD (scikit-learn) - 正則化(Lasso/Ridge/ElasticNet)含む
今回のプロジェクトでは、これらの中からアルゴリズムの選定だけでなく、Hyperopt(ベイズ最適化) を用いて最適なハイパーパラメータの組み合わせまで自動で探索が行われました。結果として、今回はXGBoostとLightGBMが高い精度を記録しました。
💡 Expert Tip
AutoMLは実験の全過程をMLflowに自動記録します。これにより、Feature Importance(変数の重要度)やモデルごとの性能比較をGUI上で簡単に確認できます。
📚 参考文献
5. 推論と結果 (Gold Layer)
AutoMLが選定したベストモデルをロードし、テストデータ区間(未来)の電力需要を予測します。 MLflowのspark_udf機能を使えば、学習済みモデルをSparkの関数(UDF)として取り込み、分散処理で大規模な推論を実行できます。
# ベストモデルのロード (Spark UDF)
predict_udf = mlflow.pyfunc.spark_udf(spark, model_uri)
# 大規模分散推論の実行
df_result = test_df.withColumn("prediction", predict_udf(*inputs))
# 性能評価 (R2 Score)
evaluator = RegressionEvaluator(labelCol="demand", predictionCol="prediction", metricName="r2")
r2_score = evaluator.evaluate(df_result)
print(f"Test R2 Score: {r2_score:.3f}")
# gold tableに保存
df_gold = df_pred.select("timestamp", "demand", "prediction")
(df_gold.write
.format("delta")
.mode("append")
.option("mergeSchema", "true")
.clusterBy("timestamp")
.saveAsTable(config.gold_tbl)
)
結果
予測データと実データ比較
性能評価 (R2 Score)
おわりに
今回のプロジェクトを通じて、DatabricksとAutoMLの強力なシナジーを確信することができました。
-
開発効率: 手間のかかるモデルチューニングの過程を自動化することで、データアナリストは「データ品質の向上」により注力できるようになりました。
-
スケーラビリティ (Scalability): 推論ロジックをSpark UDF化しているため、Databricksの「Cluster Autoscaling」機能と組み合わせることで、 データ量に応じてコンピュートリソースを自動で拡張し、数億レコードの推論も短時間で完遂できます。
-
最新技術の適用:Liquid ClusteringやSpark Native関数の最適化を通じて、コスト効率の高いデータ処理および分析環境を実現しました。
電力需要予測のみならず、様々な時系列予測の課題に対し、このアーキテクチャと技術セットを活用してみることを強くお勧めいたします。
今後の展望:Regression vs Forecasting
今回は AutoML.regress(回帰) を使用して特徴量を自分でコントロールしましたが、次のステップとしてAutoML.forecasting(時系列予報) モードの適用も検討しています。
- Regressionモード:ラグや周期性などの特徴量を自分で細かく制御したい場合に有利。
- Forecastingモード:ProphetやARIMAなどが含まれ、特に 「祝日(Holidays)」情報を自動で考慮 してくれる点が強力です。日本のゴールデンウィークや年末年始のような不規則な需要変動を予測する場合、Forecastingモードの方が適している可能性があります。
次回は、特徴量エンジニアリングなしでAutoML.forecastingを使い、日本の祝日などの変数を自動処理する方法について試してみたいと思います。



