Exploratory アワー #790 - 相互相関分析を行う方法

時系列データを分析する際、ある事象が別の事象に影響を与えるまでに時間のズレ(タイムラグ)が生じることがあります。例えば、広告を出した数日後に売上が伸びる、あるいは金利の変動が数ヶ月後の住宅着工件数に影響するといったケースです。

このような「時間のズレ」を考慮した上で、2つのデータがどれくらい連動しているかを測定する手法が「相互相関分析(CCF:Cross-Correlation Function)」です。今回は、Exploratoryを使用して、最適なラグ(ズレ)を特定し、データの連動性を正しく把握する方法を紹介します。

問題

2つの時系列データの相関を調べる際、単純に同じ日のデータ同士を比較するだけでは、本来あるはずの関連性を見落としてしまうことがあります。

解決方法

まずは、特定の期間だけデータをずらして連動性を確認する方法を説明します。今回使用するサンプルデータは、1日ごとの「アニメの検索数」と「漫画の検索数」が記録されたデータです。

チャートで確認すると、アニメの検索数が変動した数日後に漫画の検索数が連動しているように見えます。

このズレを考慮するために、特定の列をずらした新しい列を作成します。

列ヘッダメニューから「計算を作成」の「標準」を選択します。

今回は、後の値を取得するためにlead関数を使用します。計算エディタには以下のように指定します。

lead(manga_search, n=7)

この設定により、7日先の値を取得した新しい列が作成されます。例えば、1月1日の行には1月8日の値が入ることになります。

この新しく作成した列をチャートのY軸に追加して元のデータと比較することで、7日間のズレを考慮した際に、アニメと漫画の検索数が非常に強く連動していることを確認できます。

カスタムRコマンドによる相互相関分析

次に、手動で日数を確認するのではなく、プラスマイナス30日などの範囲内で「どのラグが最も相関が高いか」を一括で計算する方法を説明します。

Exploratoryのステップメニューから「Rコマンド」を選択します。

相互相関を計算するために以下のスクリプトを実行します。この処理では、データ内の数値列の全ペアに対して、指定した範囲(例:-30日から+30日)のラグごとの相関係数を算出します。

{
# 数値列のみ取り出す(dateを除外)
numeric_cols <- keep(., is.numeric) %>% names()

# 全ペアの組み合わせを作る(自己相関は除外、A→BとB→Aは両方残す)
pairs <- expand_grid(x_var = numeric_cols, y_var = numeric_cols) %>%
  filter(x_var != y_var)

# データフレームを一旦退避
input_df <- .

# 各ペアに対してCCFを計算
pmap_dfr(pairs, function(x_var, y_var) {
  ccf_res <- ccf(
    x = input_df[[x_var]],
    y = input_df[[y_var]],
    lag.max = 30,
    type = "correlation",
    plot = FALSE,
    na.action = na.pass
  )
  
  tibble(
    x_var = x_var,
    y_var = y_var,
    lag = as.vector(ccf_res$lag),
    correlation = as.vector(ccf_res$acf)
  )
}) %>%
  mutate(
    ci_threshold = qnorm(0.975) / sqrt(nrow(input_df)),
    is_significant = abs(correlation) > ci_threshold,
    abs_correlation = abs(correlation)
  )
}

実行すると、XとYの変数の組み合わせ、ラグの日数、そしてその時の相関係数(コーリレーション)がまとめられたデータが得られます。

この結果をバーチャートで可視化し、X軸に「ラグ」、Y軸に「相関係数」を割り当てることで、どのタイミングで相関が最大になるかを一目で判断できます。例えば、ラグが「-7」の時にバーが最も高ければ、7日間のズレがある時に最も親和性が高いことが分かります。

最適なラグの自動抽出

最後に、膨大な組み合わせの中から、各ペアで最も相関が強かったラグだけを抽出する方法を説明します。

再度「Rコマンド」を選択します。

Rコマンドにグループ化とスライス機能を利用した以下のスクリプトを実行します。

group_by(x_var, y_var) %>%
slice_max(abs_correlation, n = 1, with_ties = FALSE) %>%
ungroup() %>%
arrange(desc(abs_correlation))

この操作では、変数ペア(xとy)ごとにグループ化を行い、相関係数が最大となる行だけをピックアップします。

実行することで、1つずつチャートを確認することなく、どの変数同士が何日のズレを持って最も強く連動しているのかを一覧表として得ることができます。

この相互相関分析を活用することで、広告費と売上の関係や、先行指標と遅行指標の関係をデータに基づいて正確に特定し、より精度の高い意思決定や予測に役立てることが可能になります。

ビデオ

Export Chart Image
Output Format
PNG SVG
Background
Set background transparent
Size
Width (Pixel)
Height (Pixel)
Pixel Ratio