04.1.3
パーセント変化の推移
series.pct_change().mul(100) の 1 行で求まります。元の値の大きさに依存しないので、1000 人の店と 100 人の店のように規模の違う系列を同じ図で比べられ、+10 % と −10 % が入り乱れる棒グラフに rolling(window=14, min_periods=5).mean() の線を重ねると、日ごとのちらつきが消えて勢いの向きだけが残ります。このページでは、水準 100 のランダムウォーク 160 日分を増減率にして ax.bar で描き、14 日移動平均を ax.plot で重ね、0 の線を ax.axhline で引いて、線が 0 の上にある期間を「伸びている時期」と読む手順を示します。元の値ではなく増減率で可視化すると、トレンドの強さや変化の勢いを比較しやすくなります。
直感 #
野球部の SNS フォロワーが 1 日で 1000 人から 1050 人に、文芸部が 100 人から 120 人に増えたとき、増えた人数は 50 人と 20 人で野球部が大きいですが、前日比では 5 % と 20 % で文芸部に勢いがあります。この「前の日を基準にした割合」を毎日計算して並べたのが増減率の棒グラフで、棒が 0 の線より上なら増えた日、下なら減った日です。棒は毎日プラスとマイナスを行き来して流れが読めないので、直近 14 日分の平均をつないだ線を重ね、その線が 0 の上にあるか下にあるかで「このごろの勢い」を判断します。
何が起きているか(ステップで見る) #
コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。
見るポイント:折れ線でも軸の始点で印象が変わる。傾向を見たいなら移動平均を重ね、元データは薄く残す。
Pythonで描いてみる #
次のコードは、標準偏差 1.8 の日々の変化を累積したランダムウォークを 160 日分作り、pct_change で前日比の % に変換してから、棒(日次の増減率)と線(14 日移動平均)と 0 の水平線を 1 枚に重ねます。
| |
実行結果の読み方 #
水色の棒は 2 日目から始まり、おおむね ±4 % の範囲でプラスとマイナスを行き来します。振れ幅がこの程度なのは、1 日の変化の標準偏差 1.8 を水準 100 前後で割っているからです。赤い 14 日移動平均の線は振れ幅が小さく、0 の線より上に滞在する期間が「増える勢い」の時期、下に沈む期間が「減る勢い」の時期です。他の日より明らかに長い棒が 1 本あれば外的な出来事の合図で、元の series のその日の値と前後を series.loc["2021-07"] のように確かめます。
使いどころと落とし穴 #
増減率は元の値の大きさに依存しないので、売上 1000 万円の店と 100 万円の店、株価と販売数のように単位の違う系列を同じ図に並べたいときに pct_change を使います。ただし基準が小さいと率が暴れ、フォロワー 1 人が 2 人になれば +100 % になるので、元の値が小さい期間の棒は長さほどの意味を持ちません。+10 % のあとに −10 % でも元には戻らず(100 → 110 → 99)、増減率の足し算で累積を語ることはできないため、累積を見たいなら (1 + returns / 100).cumprod() を使います。移動平均の線が 0 を横切ったタイミングは、キャンペーンや外部イベントの影響を疑って深掘りする手がかりです。
- 日次データの基本プロット — 折れ線で全体像をつかむ
- 移動平均と移動標準偏差 — トレンドとばらつきの変化を同時に確認
- 差分による定常化を比較 — 原系列と 1 次差分で定常化の効果を比べる