K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

パーセント変化の推移

入門

04.1.3

パーセント変化の推移

最終更新 2020-02-07 読了時間 2 分
まとめ
パーセント変化(増減率)は、前の日の値を基準に「今日は何 % 増えたか」を表す値 \((x_t - x_{t-1}) / x_{t-1} \times 100\) で、pandas では 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 枚に重ねます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

rng = np.random.default_rng(7)
dates = pd.date_range("2021-05-01", periods=160, freq="D")
level = 100 + np.cumsum(rng.normal(0, 1.8, size=len(dates)))
series = pd.Series(level, index=dates)

returns = series.pct_change().mul(100)
rolling_mean = returns.rolling(window=14, min_periods=5).mean()

fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(returns.index, returns, width=0.8, color="#cbd5f5", label="日次の増減率")
ax.plot(rolling_mean.index, rolling_mean, color="#ef4444", linewidth=2, label="14日移動平均")
ax.axhline(0, color="#475569", linewidth=1)
ax.set_title("日次パーセント変化の推移")
ax.set_xlabel("日付")
ax.set_ylabel("変化率(%)")
ax.legend()
ax.grid(alpha=0.3, axis="y")

fig.tight_layout()
fig.savefig("static/images/timeseries/percent_change.svg")

パーセント変化の推移の図

実行結果の読み方 #

水色の棒は 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 を横切ったタイミングは、キャンペーンや外部イベントの影響を疑って深掘りする手がかりです。