1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Databricks × 需要予測】#02 指数平滑法(Holt-Winters法)で需要予測を理解する(基礎編)

1
Last updated at Posted at 2026-03-26

はじめに

前回は、Databricksで需要予測を行うための環境構築を行いました。

今回は、実際に需要予測モデルの最初のステップとして
「指数平滑法(Holt-Winters法)」を使った予測を見ていきます。

このパートでは、

  • 需要予測の基本的な流れ
  • 時系列データの扱い方
  • シンプルな予測モデルの考え方

を理解することを目的とします。

01 事前確認

image.png

アクセラレータでは、データの再作成有無を設定できます。

設定 意味
true データを作り直す
false 既存データを使用

今回は既存データを利用します。

print(dbname)
print(catalog)

02 Databricksのデータ構造

Databricksではデータは以下の階層で管理されます。

Catalog
  ↓
Schema(Database)
  ↓
Table

今回の例:

hirota_fcst_catalog
    ↓
demand_planning
    ↓
part_level_demand

03 環境セットアップ

image.png

このNotebookでは、需要予測に必要なライブラリを読み込みます。
主な分類は以下の通りです。

① データ処理

import numpy as np
import pandas as pd
  • numpy:数値計算
  • pandas:データ操作

② 可視化

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.dates as md

需要推移や予測結果をグラフで確認するためのツール

③ 時系列モデル

from statsmodels.tsa.api import ExponentialSmoothing, SimpleExpSmoothing, Holt
from statsmodels.tsa.statespace.sarimax import SARIMAX
モデル 用途
SimpleExpSmoothing 単純指数平滑
Holt トレンド対応
ExponentialSmoothing 季節性対応
SARIMAX ARIMA系

④ MLflow

import mlflow

モデルや評価結果を管理するツールになります

⑤ Hyperopt

from hyperopt import hp, fmin

モデルのパラメータを自動調整するツールになります

⑥ Spark

import pyspark.sql.functions as f

大量データの処理のためのツール

補足:なぜSparkを使うのか

時系列モデルの基本として

1つの時系列 → 1つのモデル

を作成していきます。

つまり、

5商品 → 5モデル

となります。

実務では1000商品、10000商品以上の数を取り扱うことになり、この商品数のモデルを作成する必要があります。

ここで、Databricksの強みであるSparkを使うと、商品ごとに並列でモデル作成が可能となります。

04 データ整形

時系列モデルでは、データを「時間順」に整える必要があります。

image.png

pd.Series(
    pdf['Demand'].values,
    index=pdf['Date']
)

👉 Demandを値、Dateをインデックスに整形

series_df = series_df.asfreq('W-MON')

👉 週次データとして統一
※ 時系列モデルでは 時間間隔が一定であることが必須

05 学習データの作成(バックテスト)

image.png

forecast_horizon = 40

👉 未来40週を予測

is_history = [True] * (len(series_df) - forecast_horizon) + [False] * forecast_horizon
意味
True 学習データ
False 評価データ

バックテストとは

未来データがないため、
👉 過去の一部を「未来」として扱う

06 外部要因の作成

需要は外部要因にも影響されます。
image.png

例👇

  • コロナ
  • クリスマス
  • 年始
covid_breakpoint = dt.date(year=2020, month=3, day=1)

👉 コロナ開始日の定義
「2020/3/1以降はコロナ影響があるとみなす」という“境界日”を決めています

exo_df = pdf.assign(Week = pd.DatetimeIndex(pdf["Date"]).isocalendar().week.tolist()) 

👉 Week(週番号)を作る:クリスマス/年始判定に使う

exo_df = exo_df \
  .assign(covid = np.where(pdf["Date"] >= np.datetime64(covid_breakpoint), 1, 0).tolist()) \
  .assign(christmas = np.where((exo_df["Week"] >= 51) & (exo_df["Week"] <= 52) , 1, 0).tolist()) \
  .assign(new_year = np.where((exo_df["Week"] >= 1) & (exo_df["Week"] <= 4)  , 1, 0).tolist()) \
  .set_index('Date')

👉 covid / christmas / new_year の “0/1フラグ” を作る

07 指数平滑法(Holt-Winters法)

ここからモデルの話です。指数平滑法のモデルを利用して分析とモデルの比較を行います。

💡 なぜ最初に指数平滑法を使うのか

需要予測には様々なモデルがありますが、

  • シンプルで理解しやすい
  • トレンド・季節性を扱える
  • ベースラインとして使える

という理由から、まず最初に指数平滑法を使って全体像を理解します。

以下の画面では、指数平滑法で4種類のモデルを作成と各モデルの比較を行っています。

image.png
image.png

指数平滑法(Holt-Winters法)とは?

👉 時系列データの以下を扱えるモデルとなります

  • トレンド(増減)
  • 季節性(周期)

モデル作成

ExponentialSmoothing(
    train,
    seasonal_periods=3,
    trend="add",
    seasonal="add"
).fit()

パラメータ解説

seasonal_periods

データ
月次 12
週次 52
四半期 4

※ 今回はサンプルデータの都合上、seasonal_periods=3となっていますが、
通常の週次データでは52(1年周期)を設定することが一般的とされています。

trend

  • add:一定の変化
  • mul:比例変化

seasonal

  • add:一定の季節変動
  • mul:変動が大きくなる

use_boxcox

👉 データを安定させる

08 結果の確認

image.png

  • 黒:実績
  • 左側:学習
  • 右側:予測

結果の考察

結果を見ると、予測データが実績データのデータと差があるように見られます。
指数平滑法は、指数平滑法はシンプルで扱いやすい一方、

  • 外部要因を直接扱えない
  • 複雑な変動に弱い

といった特徴があります。

そのため、今回のようなデータでは精度が出にくい結果となりました。

まとめ

今回は、

  • 時系列データの扱い方
  • Holt-Wintersモデル
  • 需要予測の基本

について整理してみました。

指数平滑法では精度が出なかったため、次回はより高度なモデルであるSARIMAXを使って需要予測を行っていきます。
外部要因も考慮した予測がどのように変わるのかを見ていきたいと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?