AI × データ分析基礎知識集 / 時系列分析

時系列分析の基礎|YoY/MoM・STL分解・移動平均・季節性補正の読み方


SEO流入・広告KPI・売上のような事業データは、強い季節性とノイズを含む時系列データです。生の数字をそのまま前年比・前月比で読むと、季節要因と施策効果が混ざり、判断を誤りやすくなります。本記事では、日次ノイズを取り除く移動平均(SMA・EWMA)、YoY・MoM・WoWの正しい使い分け、STL分解でトレンドと季節性を分離する考え方、移動平均±σで異常を検知する仕組み、そして季節性補正済みのKPIレポートの作り方までを、初学者向けに整理します。

公開2026.05.15
最終更新2026.06.11
読了 13 分 / 約5,800字
この記事をシェアポスト
AI × データ分析季節性を取り除いてから施策効果を読む

時系列分析の基礎
YoY・STL・季節性補正

SEO流入・広告KPI・売上・PVのような事業データは、強い季節性とノイズを含む時系列データです。生の数字をそのまま前日比・前年比で読むと、季節要因と施策効果が混ざり、判断を誤りやすくなります。

たとえば BtoB SaaS の日次セッション数を 1 年分眺めると、1 本の折れ線の中に「月〜金で高く土日で半減する曜日効果」「3 月期末・9 月期末の駆け込み流入」「GW・お盆・年末年始の落ち込み」「コアアップデートでの突発下落」が全部混ざっています。これを トレンド(中長期の方向)・季節性(曜日・年内パターン)・残差(突発要因)の 3 層に分けて読むのが、時系列分析の基本姿勢です。

C
結論
時系列は『トレンド × 季節性 × ノイズ』に分解して読む

時系列分析の出発点は、観測値を トレンド・季節性・残差(ノイズ) の3成分に分解することです。移動平均で日次ノイズを取り、STL分解(時系列を 3 成分に統計的に分けるアルゴリズム、04 章で詳述)で曜日効果や年内パターンを分離し、季節調整後の残差で異常検知や施策効果を語る。前年比(YoY)も曜日・祝祭日・うるう年で補正してから比較するのが原則です。

01.まず結論:時系列は『トレンド × 季節性 × ノイズ』に分解する

事業の時系列データは、見かけ上1本の折れ線でも、中身は3つの成分の足し合わせです。これを意識しないと、「先週比+10%」が施策の成果なのか曜日効果なのか、「前年同月比-5%」が劣化なのか祝祭日の位置ずれなのかを切り分けられません。

成分意味例
トレンド中長期で続く方向感(上向き/横ばい/下向き)サイト成長による地道な流入増、ブランド浸透による検索数増
季節性周期的に繰り返される動き曜日効果(BtoBの平日/週末)、月末売上、年末年始の落ち込み、新年度の伸び
残差(ノイズ)上記2つで説明できない揺らぎや突発イベントコアアップデート、TVCM、競合の参入、計測トラブル

図:時系列データの3層分解(観測 = トレンド + 季節性 + 残差)

観測値(一番上)は、3つの成分の足し合わせ。STL分解はこの3層を統計的に分離して、施策効果と季節要因を切り分けるための前処理として使う。

観測トレンド季節性残差

02.移動平均と指数平滑|日次ノイズを丸める

最初に身につけたい時系列の前処理が 移動平均 です。日次データのジリジリした上下動を均して、トレンドが見やすい形に変換します。

手法中身向く場面
単純移動平均(SMA)直近 N 日の単純平均で平滑化曜日効果を消す7日/月内変動を消す28日が定番
指数加重移動平均(EWMA)最近の値ほど重み付けして平均直近の変化に追従させたい。アラート用途
中心移動平均前後 N/2 日の平均(始端・終端は欠損)トレンドの可視化(リアルタイム監視には向かない)
ローパスフィルタ周波数領域で高周波を落とす高度な季節性除去。実装コストは高い
i
窓(ウィンドウ)とは
『一度に平均する範囲』を 1 日ずつずらしていく仕組み

窓(ウィンドウ)は、移動平均で一度に平均する範囲のことです。たとえば窓 7 日なら、毎日「その日を含む直近 7 日間」の値を平均して 1 点を出し、窓を 1 日ずつずらしながら系列全体に適用します。これがコード上の data.rolling(window=7).mean() の中身です。

窓サイズは、消したい季節性の周期の整数倍を選ぶのがコツです。週次の曜日効果(土日落ち)を消したいなら 7 日、月次の繰り返しを消したいなら 28 日(または 30 日)が定番。中途半端な日数(例:10 日)を選ぶと、特定の曜日が窓内に 2 回入ったり 1 回しか入らなかったりして、平滑化したつもりで波打ちが残ります。

# 移動平均と指数平滑(pandas)
import pandas as pd

# data: DatetimeIndex を持つ Series(日次トラフィック)
sma_7  = data.rolling(window=7).mean()      # 7日単純移動平均
sma_28 = data.rolling(window=28).mean()     # 28日単純移動平均
ewma   = data.ewm(span=14, adjust=False).mean()  # 指数加重(半減期14日相当)

# 中心移動平均(前後3.5日 = 7日窓)
sma_center = data.rolling(window=7, center=True).mean()

コードを書かずに試したい場合は、下のツールが使えます。本章のような「緩やかな増加トレンド+曜日の波」を持つ日次データを読み込んであり、線形トレンドの延長による簡易予測と95%予測区間を表示します。トレンド線が曜日の波を均してしまう(=季節性はトレンドでは捉えられない)感覚も、そのまま体感できます。

簡易未来予測ツール
ツール単体ページで開く

時系列データを古い順に貼り付けると、線形トレンドで先の期間を予測し、95%予測区間つきのグラフと予測値一覧をその場で表示します(ブラウザ内で計算、サーバー送信なし)。

入力フォーマットの例を見る

Excel・Googleスプレッドシートで範囲をコピーしてそのまま貼り付け(タブ区切り)できるほか、CSV(カンマ区切り)・スペース区切りにも対応しています。1行目が見出しの場合は自動で判定します。日付や文字列など数値でないセルは自動的に除外されるので、きれいに整形してから貼り付ける必要はありません。

月,売上(万円)
2026/01,502
2026/02,531
2026/03,520

公開データで試す

ボタンを押すと、お使いのブラウザから各公開APIへ直接アクセスして実データを取得し、入力欄へ読み込みます(当社サーバーは経由しません)。為替やビットコインなどの金融価格は「過去のトレンドが続く」前提が特に成り立ちにくいため、ツールの動きを体験する用途でお使いください。

(「期」=データ1行分の間隔。月次データなら1期=1か月)

03.YoY・MoM・WoWの正しい使い分けと罠

マーケティングのレポートでよく登場する YoY(前年同期比)・MoM(前月比)・WoW(前週比)は、便利な反面、季節性や曜日効果を含んだまま比較してしまう落とし穴があります。

比較計算向く場面罠
YoY(前年同期比)今年の値 / 前年同期の値 − 1中長期トレンドの把握。季節性をまたいだ比較祝祭日の位置ずれ、うるう年、コアアップデートの混入
MoM(前月比)今月 / 前月 − 1月次施策の効果月の日数差、月末月初の曜日ずれ
WoW(前週比)今週 / 前週 − 1短期トレンド・施策直後の反応祝日週は大きくぶれる。1週間では季節性除去不可
同一曜日比較今週月曜 / 先週月曜 − 1 等曜日効果を除去した短期比較祝日が絡むと意味が薄い
YoY同曜日比較今年の第N週月曜 / 前年第N週月曜曜日と季節性を同時に揃えた比較祝日の位置と前年祝日が同じか確認
!
祝祭日とうるう年
単純なYoYは祝祭日の位置ずれで簡単にぶれる

5月のゴールデンウィークが「5月3日が水曜」の年と「5月3日が土曜」の年では、平日数も訪問パターンも変わり、流入の YoY 比較に直接効きます。さらにうるう年(2月29日の有無)で2月のYoYが2〜3%ずれます。これらを補正せずに「YoYで-3%だから劣化」と判定するのは早計です。祝祭日カレンダーをモデルに持ち込み、当該日と隣接日を別フラグで扱うのが安全な実務です。

04.STL分解|トレンド・季節性・残差の分離

STL(Seasonal and Trend decomposition using Loess)は、時系列を トレンド・季節性・残差 の3成分に分解する代表的な手法です。Loess(局所重み付き回帰)を使うため、季節パターンが少しずつ変わっていく時系列にも対応できます。

観点加法分解(Additive)乗法分解(Multiplicative)
式観測 = トレンド + 季節 + 残差観測 = トレンド × 季節 × 残差
向く場面季節変動の幅がトレンドに依存しない値が大きいほど季節変動も大きい(成長期)
例PV、定常的なCVR売上、急成長中のサイト
対処そのまま STLlog を取って加法に戻すか、`seasonal_decompose(model='multiplicative')`
# STL分解(statsmodels)
from statsmodels.tsa.seasonal import STL
import pandas as pd

# data: DatetimeIndex を持つ Series。少なくとも 2〜3 周期分のデータがあると良い
stl = STL(data, period=7, robust=True)  # 週次季節性なら period=7
res = stl.fit()

trend     = res.trend       # トレンド成分
seasonal  = res.seasonal    # 季節性成分
resid     = res.resid       # 残差(ノイズ)

# 季節調整値(観測 − 季節性)。施策効果や異常検知はこれで議論する
season_adjusted = data - seasonal

05.季節性の種類と扱い方

実務の時系列データは、複数の季節性が重なっているのが普通です。最低でも以下の4つは分けて扱えると、レポートの精度が大きく上がります。

季節性周期実務での出方
曜日効果(週次)7日BtoB:平日に高く、土日に下がる。BtoC:週末に伸びるカテゴリも
月内パターン約28〜31日給料日効果、月末締めの駆け込み、月初の予算消化
年内パターン365日夏休み・年末年始の落ち込み、新年度・受験期の伸び、業界別の繁忙期
祝祭日効果不規則GW・お盆・年末年始は曜日と組み合わさってさらに複雑
i
複数季節性
週次+年次が同時に効くなら MSTL や Prophet を検討

通常の STL 分解は1 つの周期しか扱えません。実務では「週次(7日)」と「年次(365日)」のように複数の季節性が重なっているため、片方しか扱わないと残差にもう片方が漏れ出します。

たとえば BtoB SaaS の日次セッション数を 1 年分分析するとき、「月〜金で高く土日で半減する曜日効果」と「3 月期末・9 月期末で伸びる年次効果」、さらに「GW・お盆・年末年始の落ち込み」を同時にモデル化したい。このとき選択肢になるのが次の 2 つです。

  • MSTL(Multiple STL、statsmodels 0.14+):複数の季節周期を順に Loess で分解する。MSTL(data, periods=(7, 365)).fit() のように周期のタプルを渡すだけで、週次と年次を別の成分として取り出せる。
  • Prophet(Meta 製):週次・年次の季節性を内蔵し、GW・お盆など祝祭日テーブルもデフォルトで扱える。add_regressor() で「TVCM 放映日のフラグ」「セール期間のフラグ」のような外部変数も一緒に推定でき、施策効果と季節効果を切り分けやすい。

使い分けの目安:純粋に分解して残差を見たいだけなら MSTL、祝祭日や外部キャンペーンの効果まで切り分けたいなら Prophet。SEO 流入や売上のように祝祭日と外部要因が強く効く事業データは Prophet を選ぶケースが多いです。

# Prophet で複数季節性と祝祭日・外部変数を同時に扱う
from prophet import Prophet
import pandas as pd

# ds(日付)と y(値)の2列が必要
df = data.reset_index().rename(columns={"date": "ds", "sessions": "y"})

holidays = pd.read_csv("jp_holidays.csv")  # 祝祭日カレンダー(ds, holiday列)

m = Prophet(
    weekly_seasonality=True,
    yearly_seasonality=True,
    holidays=holidays,
)
m.add_regressor("tvcm_flag")      # TVCM 放映日のフラグ
m.add_regressor("campaign_flag")  # キャンペーン期間のフラグ
m.fit(df)

forecast = m.predict(df)
# forecast["weekly"] / forecast["yearly"] / forecast["holidays"] で
# 成分ごとに分解結果が取れる。残差は y - yhat。

06.異常検知の入口|移動平均±σ・Z-score・残差

日々のKPIを監視していると、「これは普段の揺らぎなのか、本物の異常なのか」を判定したい場面が出てきます。一番シンプルで運用しやすいのが 移動平均±σ による管理図(SPC: Statistical Process Control)の発想です。

図:管理図(移動平均±2σ)による異常検知

中心線(移動平均)と上下の管理限界(±2σ)の帯から外れたら異常として検知する。SPC(統計的工程管理)の考え方をKPI監視に流用する形。

中心線+2σ-2σ日付(30日)

オレンジ点が±2σの帯から外れた異常。実務では「2σ越えが連続2点」「中心線の片側に7点連続」など Western Electric ルールも組み合わせる。

手法中身向く場面
移動平均±2σ中心線±2標準偏差の帯から外れたら異常週次・月次の安定指標。シンプルで説明しやすい
Z-score(観測 − 平均) / 標準偏差。|Z| > 2 や 3 で異常1点単位の判定。簡易ダッシュボード向き
Western Electric ルール「±2σ越え2点」「中心線片側に7点連続」など複合条件誤検知を減らしたい本番監視
Isolation Forest多次元データの異常スコアを学習で出す複数KPIを同時に監視。流入×CVR×滞在の同時異常
残差での異常検知STL分解の残差に±σを適用季節性を除いてから判定したい
!
生データで異常検知してはいけない
季節性を除いてからσを取らないと、毎週末がアラート

BtoBサイトの日次トラフィックを生のまま±2σで監視すると、毎週土日が「異常」として検知され、アラート疲れになります。必ず季節性を除いた残差で異常検知するか、曜日別に基準値を切り分けるのが運用上の必須条件です。「曜日別中央値±2σ」「STL残差±2σ」「Prophet の予測区間外れ」のいずれかが現実的な選択肢です。

07.季節性補正したKPIレポートの作り方

最後に、ここまでの考え方を組み合わせて、季節性に振り回されないKPIレポートを作るときのチェックリストをまとめます。Looker Studio・Tableau・社内ダッシュボードのどれでも応用できる骨格です。

チェック項目中身具体例
01. 比較軸を3層用意WoW・MoM・YoY を並べて、短中長期のトレンドを同時に見る短期:WoW、中期:MoM、長期:YoY
02. 曜日効果を除く7日移動平均または同一曜日比較を主軸にする「日次の生データ + 7日移動平均」の2本立て
03. 祝祭日フラグ祝祭日とその前後を別フラグで管理し、レポート上で示すGW・お盆・年末年始の期間はバナーで明示
04. STL分解 or Prophet重要KPI には季節調整値を併記売上・主要LPのCVRはトレンド成分も並べる
05. アラート閾値残差ベースの±2σで自動アラートSlack 通知 + 異常時のセグメント別ドリルダウン
06. 介入マーカーコアアップデート・大型施策の日付をグラフに重ねるLooker Studio の参照線、Tableau の注釈
07. ガードレール指標目的指標と一緒に逆方向の指標も並べるCVR ↑ と一緒に離脱率・読み込み時間も監視

08.よくある質問(FAQ)

STL分解は何日分のデータがあれば使えますか?

STL の理屈上は周期の 2 倍以上あれば計算できますが、実用上は 3〜4 周期分 を推奨します。週次季節性なら最低 28 日、できれば 8〜12 週。年次季節性なら最低 2 年分、できれば 3 年分です。データが短いとトレンドと季節成分の分離が不安定になり、ノイズに引っ張られて変な季節パターンを学習することがあります。短い場合は素直に移動平均と曜日別平均で代用するのが安全です。

移動平均と指数平滑、どちらを使うべきですか?

用途で分けます。レポートの可視化・中長期トレンドの把握は 単純移動平均(SMA) が読みやすく、直近の動きへの追従やアラートには 指数加重移動平均(EWMA) が向きます。同じデータに対して SMA と EWMA を並べてプロットすると、トレンドが加速しているか減速しているかが直感的に分かります。両者をレポートに同時表示するチームも多いです。

異常検知の閾値は何σが良いですか?

ビジネス指標の本番監視では ±2σ を起点にするのが運用しやすいラインです。±2σ は理論上 約 4.55% の確率で偶然超えるので、毎日監視していると 約 22 日に 1 回はアラートが出る計算になります。アラート疲れが起きるなら ±3σ(年に数回レベル)に緩め、逆に静かすぎるなら Western Electric ルール(±2σ越え2点連続、中心線片側に7点連続など)を組み合わせて感度を上げます。生データではなく 季節調整後の残差で σ を取る のが大前提です。

週次と年次の季節性が同時にあるとき、どう扱えば良いですか?

通常のSTL分解は単一周期を前提にしているため、週次(7日)と年次(365日)が同時に効くデータには MSTL(Multiple STL、statsmodels 0.14+)または Prophet(Meta製)が向きます。Prophet はトレンド・複数の季節性・祝祭日効果・外部変数を一括で扱える設計で、コードもシンプルなので実務での定番になっています。SEO 流入や売上のような複合季節性データには Prophet を第一候補にする運用が多いです。

Prophetは使うべきですか?scikit-learnやARIMAで十分ですか?

マーケや事業データの予測・KPI 監視なら、Prophet が扱いやすく短コードで済むため第一選択になりやすいです。理論的な厳密さ・小サンプルなら ARIMA/SARIMA、説明可能性を重視するなら線形回帰や状態空間モデル(statsmodels の UnobservedComponents)も選択肢です。Prophet はトレンドの自動チェンジポイント検出、祝祭日効果、外部変数の追加が標準装備なので、最初の一手として広く使われています。

YoY比較で『前年が異常値だった』場合、どう処理すれば良いですか?

前年の異常値をそのまま比較対象に使うと、施策効果と前年の異常イベントが混ざります。対処は2系統。1つは 補正YoY として、前年の異常値を年間トレンドや前々年で補完した推定値に置き換えて比較する。もう1つは 注釈付きYoY として、生のYoYに「前年は◯月に障害/コアアップデートで-15%だった」のような注釈を必ず併記する。BIツール側で異常区間に網掛けやマーカーを出す機能が使えるならそれが便利です。

09.まとめ

時系列分析の基礎は、観測値を トレンド・季節性・残差 の3層に分解することから始まります。日次ノイズは移動平均で丸め、曜日や年次の季節性は STL 分解や Prophet で分離し、施策効果や異常は季節調整後の残差で議論する。これだけで、生データで議論していた頃の判断ミスの大半は防げます。

YoY・MoM・WoW は便利ですが、祝祭日・曜日・うるう年で簡単にぶれます。同一曜日比較と祝祭日補正を当たり前にしておくと、レポート品質が一段上がります。複雑なモデルに踏み込む前に、まずはここまでを徹底するのがおすすめです。

お問い合わせ

KPI 設計と時系列ダッシュボード構築をご相談ください

季節性補正済みのKPIレポート設計、Looker Studio・BigQueryでの異常検知パイプライン構築の伴走支援を行っています。お気軽にお問い合わせください。

お問い合わせはこちら

データ分析・アルゴリズム 基礎知識集

一覧に戻る →
07

モデル構築の自動化

SEO・AI検索 基礎知識集

一覧に戻る →
この記事をシェア
澤田 翔太(Shota Sawada)
この記事を書いた人

澤田 翔太

株式会社クリプタル 代表取締役

1988年生まれ、慶應義塾大学卒。創業メンバーとして関わった株式会社セールスサポートを株式会社ネオマーケティング(東証STD 4196)に売却。株式会社クリプタルでも複数の事業立ち上げと売却を経験し、2022年9月には婚活・恋愛メディア「シッテク」「婚活会議」を株式会社ベビーカレンダー(東証GRT 7363)へ売却。現在はAI業務支援事業、TANTOU事業、グロースハック支援事業、メディア事業、SEOコンサルティング事業を手がける。