0
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?

Pythonで学ぶ時系列予測 ― e-learningで基礎から実践まで Part 2

0
Last updated at Posted at 2026-10-11

Pythonで学ぶ時系列予測 ― e-learningで基礎から実践まで Part 2

はじめに

Part 1では、時系列予測の入り口として、次の内容を確認しました。

時間順に並んだ観測値
        ↓
t-1 / t / t+1
        ↓
Forecast Horizon
        ↓
Sliding Window
        ↓
入力 X / 正解 y

最後は、1本の時系列を教師あり学習で扱える形へ変換するところまで進みました。

Part 2では、その一歩手前にあるデータの準備を扱います。

実際の仕事では、いきなりモデルへ渡せるデータが手に入ることはあまりありません。

例えばCSVを開くと、次のようなことが普通にあります。

日時が文字列になっている
観測日が途中で抜けている
同じ日時が2行ある
値の時間間隔がそろっていない
過去値を特徴量として作りたい
短期的なばらつきを少し滑らかにしたい

この状態でモデル作りへ進むと、後から思わぬところでつまずきます。

そこでPart 2では、まず時系列を観察しやすく、加工しやすく、学習へ渡しやすい形へ整えるところに集中します。

今回もPart 1と同じく、Docker + JupyterLabを使います。

読む
 ↓
Notebookで試す
 ↓
表やグラフを見る
 ↓
条件を変える
 ↓
確認問題

という流れは変えません。


1. Part 1からPart 2へ

Part 1で覚えたSliding Windowは、時系列から過去値を切り出す考え方でした。

Part 2では、その考え方をpandasの機能と結び付けます。

03_part1_to_part2.png

Part 2が終わるころには、CSVを受け取ってから、時系列解析へ入る前までの基本的な処理を自分で組み立てられるようにします。


2. Part 2 ― Data Preparation

原書のPart 2はChapter 4からChapter 9までです。

このe-learningでは、その6章をそのまま6つのLessonとして進めます。

Lesson 内容 主に使う機能
Lesson 4 CSVを読み、時系列として確認する read_csv() / DatetimeIndex
Lesson 5 基本的な特徴量を作る shift() / rolling() / expanding()
Lesson 6 時系列を可視化する Matplotlib / pandas plotting
Lesson 7 ResamplingとInterpolation resample() / interpolate()
Lesson 8 Power Transform sqrt / log / Box-Cox
Lesson 9 Moving Average rolling().mean()

Part 2全体を大まかに見ると、次のような流れになります。

03_part1_to_part2.png

ただし、実際には一本道ではありません。

途中で何度もグラフを描いて、変換前後を見比べます。

データを読む
    ↓
状態を見る
    ↓
必要な処理をする
    ↓
もう一度見る

この繰り返しがPart 2の中心です。


3. Part 2のゴール

Part 2を終えた時点で、次のことができれば十分です。

  • CSVをpandasで読み込める
  • 日時列をDatetimeIndexとして扱える
  • 観測期間、件数、欠測、重複を確認できる
  • 日時から曜日や月などの特徴量を作れる
  • shift()でLag特徴量を作れる
  • rolling()で過去のWindow統計量を作れる
  • 時系列を複数のグラフで確認できる
  • UpsamplingとDownsamplingの違いを説明できる
  • Interpolationが何をしているか説明できる
  • 平方根、対数、Box-Cox変換の目的が分かる
  • Moving Averageを平滑化、特徴量、簡単な予測として使い分けられる

ここではまだ「最も良い予測モデル」を探しません。

まずは、モデルへ渡す前のデータを自分で確認できるようにします。


4. 学習環境はPart 1をそのまま使う

Part 2でも、Part 1で作ったDocker + JupyterLab環境をそのまま使います。

04_docker_jupyterlab.png

Part 1の環境が残っていれば、起動は次だけです。

docker compose up

Windows側のブラウザーから、起動時に表示されたJupyterLabのURLを開きます。

このPartでは、Notebookを次のように増やします。

notebooks/
├── 01_environment.ipynb
├── 02_load_explore.ipynb
├── 03_feature_engineering.ipynb
├── 04_visualization.ipynb
├── 05_resampling_interpolation.ipynb
├── 06_power_transforms.ipynb
└── 07_moving_average.ipynb

Part 1のNotebookを消す必要はありません。

同じプロジェクトへ少しずつ教材を積み上げていきます。


5. 今回使うサンプルデータ

Part 2では、外部サイトへアクセスしなくても最後まで試せるよう、学習用CSVを同梱します。

data/
├── sample_daily_raw.csv
├── sample_daily.csv
└── sample_growth.csv

sample_daily_raw.csv は、データ確認を練習するために、あえて次の問題を入れています。

  • 抜けている日付
  • 同じ日時の重複

sample_daily.csv は、後半のLessonで使いやすいように整えた日次データです。

sample_growth.csv は、値が大きくなるほど変動幅も大きくなるように作った正の時系列で、Power Transformの練習に使います。

どれも実在する観測データではなく、教材用に生成したデータです。


Lesson 4 ― CSVを読み、時系列として確認する

学習目標

Lesson 4では、次の内容を確認します。

  • CSVをpandasで読み込む
  • 日時列を日時型へ変換する
  • DatetimeIndexを作る
  • 先頭・末尾・件数を確認する
  • 日時の重複を確認する
  • 抜けている日付を確認する
  • 基本統計量を見る
  • 日付範囲でデータを取り出す

Part 2では、最初から加工を始めません。

まず読み込んだデータが自分の想定どおりなのか確認するところから始めます。


6.1 CSVをそのまま読む

02_load_explore.ipynb を開きます。

最初は、日時を特別扱いせずに読みます。

"""学習用CSVをpandasで読み込みます。"""

from __future__ import annotations

from pathlib import Path

import pandas as pd

raw_path = Path("../data/sample_daily_raw.csv")

# まずは通常のCSVとして読み込みます。
# timestamp列がどの型として扱われるかも、このあと確認します。
raw = pd.read_csv(raw_path)

raw.head()

ここで最初に見るのは、値そのものよりもデータの形です。

# shapeで行数と列数を確認します。
print(f"shape: {raw.shape}")

# dtypesで各列がどの型として読み込まれたか確認します。
print(raw.dtypes)

CSVでは、見た目が日付でも文字列として読み込まれる場合があります。

時系列では日付を単なる文字ではなく、時間として扱える状態にしておくことが重要です。


6.2 日時として読み込む

parse_datesを使います。

frame = pd.read_csv(
    raw_path,
    parse_dates=["timestamp"],
)

次に、timestampをIndexへ移します。

# 日時をIndexへ設定し、古い時刻から順に並べます。
frame = frame.set_index("timestamp").sort_index()

frame.head()

これでIndexはDatetimeIndexになります。

print(type(frame.index))

時系列では、この形にしておくと後の処理がかなり楽になります。

04_csv_to_datetimeindex.png


6.3 重複している日時を見る

同じ日時が複数行あると、後の集計やResamplingで意図しない結果になることがあります。

# keep=Falseにすると、重複グループの全行を取り出せます。
duplicated_rows = frame[frame.index.duplicated(keep=False)]

duplicated_rows

重複を見つけたら、すぐ削除するのではなく、なぜ重複したのかを確認します。

例えば、

  • 同じセンサーから二重送信された
  • 複数地点を1列へ混ぜてしまった
  • 再観測値が追加された

といった可能性があります。

教材では平均値へまとめますが、実務ではデータの意味を確認してから処理方法を決めます。

cleaned = frame.groupby(level=0).mean(numeric_only=True)

6.4 抜けている日付を見る

CSVに行がない場合、isna()だけでは気づけません。

そもそも行自体が存在しないからです。

そこで、「本来あるはずのIndex」と比較します。

expected_index = pd.date_range(
    start=cleaned.index.min(),
    end=cleaned.index.max(),
    freq="D",
)

missing_dates = expected_index.difference(cleaned.index)
missing_dates

ここは大事なところです。

値がNaN

と、

時刻そのものが存在しない

は別の状態です。


6.5 日次の連続Indexへそろえる

抜けた日も含めたIndexへ並べ直します。

cleaned = cleaned.reindex(expected_index)
cleaned.index.name = "timestamp"

元CSVになかった日付にはNaNが入ります。

これで初めて、欠測値として扱えるようになりました。


6.6 Interpolationで補間する

ここでは学習用として、時間方向の線形補間を使います。

cleaned["observed_value"] = cleaned["observed_value"].interpolate(
    method="time"
)

ただし、補間は万能ではありません。

例えば集中豪雨のピークが欠測していた場合、前後2点を直線でつなぐだけでは実際のピークを再現できない可能性があります。

データの性質と欠測時間の長さを見て判断します。


6.7 基本統計量を見る

cleaned["observed_value"].describe()

describe()では、

  • 件数
  • 平均
  • 標準偏差
  • 最小値
  • 四分位数
  • 最大値

をまとめて確認できます。

これだけでデータの性質を判断することはできませんが、桁違いの値や読み込みミスへ気づくきっかけになります。


6.8 日付で抽出する

DatetimeIndexにしておくと、期間をそのまま指定できます。

cleaned.loc["2026-02-01":"2026-02-10"]

この書き方はPart 2以降でも頻繁に使います。


Lesson 4 確認問題

問:isna()だけを見ていれば、時系列の欠測をすべて見つけられるでしょうか。

答えと解説を見る

見つけられません。

ある日時の行そのものがCSVに存在しない場合、その日時についてNaNを調べる行もありません。

そのため、

期待する日時Index
       ↓
実際の日時Indexと比較
       ↓
存在しない日時を探す

という確認も必要です。


Lesson 4 まとめ

まず覚えておきたいのは、CSVを読めたことと、時系列として正しく読めたことは同じではないという点です。

CSVを読む
   ↓
日時型を確認
   ↓
DatetimeIndex
   ↓
並び順
   ↓
重複
   ↓
抜けた日時
   ↓
値の欠測
   ↓
基本統計量

ここまで見てから、次の加工へ進みます。


Lesson 5 ― 基本的な特徴量を作る

学習目標

Lesson 5では、Part 1で扱ったSliding Windowをpandasで具体化します。

扱うのは次の4種類です。

  • Date Time Features
  • Lag Features
  • Rolling Window Statistics
  • Expanding Window Statistics

7.1 Feature Engineeringとは

時系列は、そのままでは1本の値の並びです。

t1  20.1
t2  21.3
t3  19.8
t4  22.0

機械学習へ渡すには、入力Xと正解yの形を作ります。

過去の情報 X  →  現在または未来 y

ここで、元データから新しい入力項目を作る作業がFeature Engineeringです。


7.2 日時から特徴量を作る

DatetimeIndexからは、さまざまなカレンダー情報を取り出せます。

features = series.to_frame(name="y")

features["year"] = features.index.year
features["month"] = features.index.month
features["day"] = features.index.day
features["dayofweek"] = features.index.dayofweek
features["dayofyear"] = features.index.dayofyear

曜日によって需要が変わるデータならdayofweekが役立つかもしれません。

月や季節で変わるデータならmonthやdayofyearに意味が出ることがあります。

ただし、列を増やせば必ず予測が良くなるわけではありません。

目的は「作れる特徴量を全部作る」ことではなく、予測対象との関係を表せる情報を作ることです。


7.3 Lag特徴量

Part 1で使った、

t-2  t-1  →  t

を列として作ります。

features["lag_1"] = series.shift(1)
features["lag_2"] = series.shift(2)
features["lag_7"] = series.shift(7)

05_lag_features.png

shift(1)は、値を1行ずらして「1時刻前の値」を現在行へ持ってきます。


7.4 Rolling Window

次は、過去の複数値を要約します。

例えば過去3日平均なら、

t-3
 t-2
  t-1
   ↓
平均
   ↓
tの特徴量

という形です。

ここで注意したいのが現在値を平均へ混ぜないことです。

y(t)を予測するのに、y(t)自身を入力へ含めたら予測になりません。

そこで、先に1時刻ずらします。

past = series.shift(1)

features["rolling_mean_3"] = past.rolling(window=3).mean()
features["rolling_std_3"] = past.rolling(window=3).std()
features["rolling_mean_7"] = past.rolling(window=7).mean()

06_rolling_window.png

このshift(1)は、今後の機械学習でも重要です。

未来情報が入力へ混ざることを**Data Leakage(情報漏洩)**と呼びます。

時系列では特に起こしやすいので、常に「この値は予測時点で本当に分かっているか」を確認します。


7.5 Expanding Window

Rolling Windowが一定幅なのに対し、Expanding Windowは開始時点から過去すべてを使います。

features["expanding_mean"] = (
    series.shift(1)
    .expanding(min_periods=3)
    .mean()
)

イメージは次のようになります。

1回目  [過去3点]
2回目  [過去4点]
3回目  [過去5点]
4回目  [過去6点]
            ...

RollingとExpandingは似ていますが、見ている期間が違います。


7.6 先頭のNaNは異常ではない

LagやRollingを作ると、先頭にNaNができます。

例えば7日前の値を使うなら、最初の7日には7日前の観測値がありません。

日1   lag_7 = NaN
日2   lag_7 = NaN
...
日7   lag_7 = NaN
日8   lag_7 = 日1の値

このNaNは処理ミスではなく、履歴不足によるものです。

学習に使う段階では、必要な特徴量がそろった行だけを取り出します。

model_table = features.dropna().copy()

Lesson 5 確認問題

問:rolling(window=7)をそのまま現在値へ適用せず、先にshift(1)するのはなぜでしょうか。

答えと解説を見る

予測対象である現在値を特徴量へ混ぜないためです。

y(t)を予測する入力は、原則として予測時点ですでに得られている情報だけで作ります。

利用可能
t-7 ... t-2 t-1

予測対象
t

現在値や未来値が入力へ入ると、実運用では再現できない高い精度が出てしまうことがあります。


Lesson 6 ― 時系列を可視化する

学習目標

Lesson 6では、同じ時系列をいくつかの角度から見ます。

  • Line Plot
  • Histogram
  • Box Plot
  • Heat Map
  • Lag Plot
  • Autocorrelation Plot

グラフは見栄えのためではなく、データに何が起きているのかを考えるために使います。


8.1 Line Plot

まず基本になる折れ線グラフです。

ax = series.plot(
    figsize=(11, 4),
    title="Daily observations",
    marker="o",
    markersize=2,
)

ax.set_xlabel("Date")
ax.set_ylabel("Observed value")
ax.grid(True, alpha=0.3)

Line Plotでは、

  • 上昇・下降
  • 繰り返し
  • 急な変化
  • 異常に見える値

などを時間順に確認します。


8.2 Histogram

Histogramでは時間順序をいったん外して、値の分布を見ます。

series.plot.hist(
    bins=15,
    figsize=(7, 4),
    title="Distribution of observations",
)

Line Plotとは見ているものが違います。

Line Plot
  → いつ変化したか

Histogram
  → どの値がどれくらい多いか

8.3 Box Plot

曜日や月などのグループごとに分布を比較できます。

plot_frame = series.to_frame(name="value")
plot_frame["dayofweek"] = plot_frame.index.dayofweek

plot_frame.boxplot(
    column="value",
    by="dayofweek",
    figsize=(9, 4),
)

曜日ごとの違いがあるデータなら、Feature Engineeringのヒントにもなります。


8.4 Heat Map

時系列を行と列へ並べ直して、値の大きさを色で見ます。

例えば、

行 = 週
列 = 曜日

にすると、週周期のパターンが見つけやすくなります。

07_visualization_views.png


8.5 Lag Plot

y(t-1)とy(t)の関係を散布図で見ます。

from pandas.plotting import lag_plot

lag_plot(series, lag=1)

点が一定の方向へまとまるなら、前の値と現在値に関係がある可能性があります。

Part 3では、この関係を自己相関としてもう少し詳しく調べます。


8.6 Autocorrelation Plot

from pandas.plotting import autocorrelation_plot

autocorrelation_plot(series)

どの程度離れた過去値まで関係が残っていそうかを眺めるための入り口になります。

ここではまだ厳密なモデル選択には使いません。

Part 3、Part 5で改めて扱います。


Lesson 6 確認問題

問:Line PlotとHistogramは同じデータを描いています。何が違うのでしょうか。

答えと解説を見る

Line Plotは時間順序を残したまま変化を見ます。

Histogramは時間順序を外して、値の分布を見ます。

同じデータでも、目的によって見方を変える必要があります。


Lesson 7 ― ResamplingとInterpolation

学習目標

Lesson 7では、時系列の時間間隔を変えます。

  • Upsampling
  • Interpolation
  • Downsampling
  • 集約方法の違い

9.1 Resamplingとは

観測データが日次だからといって、分析も必ず日次で行うとは限りません。

例えば、

10分値 → 1時間値
日値   → 週値
月値   → 日値

のように時間間隔を変えることがあります。

大きく2種類に分けられます。

Upsampling
粗い間隔 → 細かい間隔

Downsampling
細かい間隔 → 粗い間隔

9.2 Upsampling

日次データを12時間間隔へ変えてみます。

upsampled = series.resample("12h").asfreq()

元データにない12:00の行が新しくできます。

ただし、そこには観測値がありません。

2026-01-01 00:00   20.1
2026-01-01 12:00    NaN
2026-01-02 00:00   22.0

時間を細かくしても、実測データそのものが増えるわけではありません。


9.3 Interpolation

新しくできた空欄を補間します。

interpolated = upsampled.interpolate(method="time")

線形補間なら、前後の観測値をつないで途中値を推定します。

08_upsampling_interpolation.png

補間値は観測値ではありません。

この区別は忘れないようにします。


9.4 Downsampling

日次データを週単位へまとめます。

weekly_mean = series.resample("7D").mean()

ここで大切なのは、何で集約するかです。

weekly_mean = series.resample("7D").mean()
weekly_max = series.resample("7D").max()
weekly_sum = series.resample("7D").sum()

どれが正しいかはデータの意味で変わります。

例えば雨量なら、期間雨量を求めるためにsum()を使う場面があります。

河川水位なら平均値より最大水位を見たいこともあります。


9.5 「時間間隔を変える」と「情報を増やす」は違う

Upsamplingで1時間値を10分値に変換しても、新しい観測事実が5点増えるわけではありません。

実測
10:00  10
11:00  16

補間後
10:00  10  ← 実測
10:10  11  ← 推定
10:20  12  ← 推定
...
11:00  16  ← 実測

分析やモデル作成では、どこまでが実測でどこからが補間なのかを意識します。


Lesson 7 確認問題

問:日雨量から月雨量を作る場合、mean()とsum()のどちらを使えばよいでしょうか。

答えと解説を見る

月間の総雨量を求めたいなら、通常はsum()です。

一方で「その月の日雨量の平均」を求めたいならmean()になります。

関数名から決めるのではなく、求めたい量と単位から決めます。


Lesson 8 ― Power Transform

学習目標

Lesson 8では、値そのものを変換します。

  • Square Root Transform
  • Log Transform
  • Box-Cox Transform
  • 変換を使う理由
  • 変換時の注意点

10.1 なぜ変換するのか

時系列によっては、値が大きくなるにつれて変動幅も広がることがあります。

小さい値のとき
10, 11, 9, 12

大きい値のとき
100, 140, 80, 160

このような系列では、変換によって値のスケールや分布を扱いやすくできることがあります。

09_power_transform.png


10.2 Square Root Transform

sqrt_series = np.sqrt(growth)

平方根を取ると、大きな値ほど圧縮されます。

カウントデータなどで使われることがあります。


10.3 Log Transform

log_series = np.log(growth)

対数変換も大きい値を強く圧縮します。

ただし、そのままの対数は0以下へ適用できません。

assert (growth > 0).all()

実務では、この条件をコードで確認してから変換する方が安全です。


10.4 Box-Cox Transform

Box-Cox変換では、データに合わせて変換の強さを表すlambdaを求めます。

from scipy import stats

boxcox_values, fitted_lambda = stats.boxcox(
    growth.to_numpy()
)

lambdaの値によって、対数変換に近い形や平方根に近い形などが選ばれます。

Box-Coxも基本的に正の値が必要です。


10.5 予測後には元の単位へ戻す

例えば元データが水量や売上なら、対数変換後の値をそのまま最終結果として出しても利用者には分かりません。

モデルを変換後の空間で作った場合、最終的には逆変換して元の単位へ戻す必要があります。

元データ
   ↓
変換
   ↓
モデル
   ↓
予測値
   ↓
逆変換
   ↓
元の単位で結果表示

この考え方は後の予測モデルでも使います。


Lesson 8 確認問題

問:0を含む系列へnp.log()をそのまま適用してよいでしょうか。

答えと解説を見る

そのままでは使えません。

対数の定義域を確認する必要があります。

必要に応じて別の変換を選ぶ、データの意味を確認した上でオフセットを検討するなどの対応を取ります。

単にエラーを避けるためだけに機械的に値を足すのではなく、元データの意味を壊していないかも確認します。


Lesson 9 ― Moving Average Smoothing

学習目標

Part 2の最後はMoving Averageです。

Moving Averageにはいくつかの使い方があります。

このLessonでは、

  1. 平滑化として使う
  2. 特徴量として使う
  3. 単純な予測として使う

の3つを分けて確認します。


11.1 Moving Averageとは

幅3のTrailing Moving Averageなら、

t-2
 t-1
  t
  ↓
平均

を各時刻で繰り返します。

100 110 108 → 106.0
    110 108 115 → 111.0
        108 115 120 → 114.3

Windowを1つずつずらしながら平均するためMoving Averageと呼ばれます。


11.2 CenteredとTrailing

Moving Averageには、中心時刻の前後を使うCentered Moving Averageと、現在以前だけを使うTrailing Moving Averageがあります。

Centered
 t-1  t  t+1
       ↓
     mean

Trailing
 t-2  t-1  t
          ↓
        mean

予測では未来値t+1をまだ知りません。

そのため、予測用途ではTrailingの考え方が基本になります。


11.3 平滑化として使う

ma7 = series.rolling(window=7).mean()

元系列と重ねると、細かい上下が弱まり、ゆっくりした動きが見えやすくなります。

10_moving_average_roles.png


11.4 特徴量として使う

y(t)を予測するための過去平均を作ります。

feature_table = pd.DataFrame({"y": series})

feature_table["lag_1"] = series.shift(1)
feature_table["ma_3_past"] = (
    series.shift(1)
    .rolling(window=3)
    .mean()
)

ここでもshift(1)が重要です。

現在値をMoving Averageへ入れると、予測対象の情報が特徴量へ混ざります。


11.5 簡単な予測として使う

「次の値は直近7日平均に近い」と仮定することもできます。

prediction = (
    series.shift(1)
    .rolling(window=7)
    .mean()
)

高度なモデルではありませんが、こうした単純な予測は後でモデル性能を比べる基準にもなります。

本格的なBaseline評価はPart 4で扱います。


11.6 Window幅を変えてみる

3日、7日、14日で比較します。

for window in (3, 7, 14):
    moving_average = series.rolling(window=window).mean()

一般にWindowを大きくすると、細かな変動は見えにくくなり、線は滑らかになります。

その一方で急な変化への反応は遅くなります。

小さいWindow
  → 変化へ早く反応
  → 細かな変動も残りやすい

大きいWindow
  → 滑らか
  → 急な変化への反応は遅い

どの幅が良いかは、データと目的によって変わります。


Lesson 9 確認問題

問:未来を予測するとき、Centered Moving Averageをそのまま特徴量として使いにくいのはなぜでしょうか。

答えと解説を見る

Centered Moving Averageは、中心時刻より後の値も平均に含めるからです。

例えばtのCentered Moving Averageが、

t-1, t, t+1

を使うなら、予測時点ではまだ分からないt+1が必要です。

過去だけで予測する場合は、Trailing Windowを使います。


12. Part 2 演習

ここまでのNotebookを一度実行したら、少し条件を変えてみます。

答えを先に見るのではなく、Notebookを複製して試すのがおすすめです。


演習1 ― Lagを変える

03_feature_engineering.ipynbで、

lag_1
lag_2
lag_7

に加えて、

lag_14

を作ってください。

そのとき、学習へ使える行数がどう変わるか確認します。

ヒントを見る
features["lag_14"] = series.shift(14)

大きなLagを追加すると、先頭側で必要な履歴が増えるため、dropna()後の行数は減ります。


演習2 ― Rolling Windowを変える

3日平均、7日平均、14日平均を同じグラフへ描いてください。

どの線が最も滑らかになるか確認します。

ヒントを見る

Windowが大きいほど、多くの値を平均するため一般に滑らかになります。

ただし、変化への追従は遅くなります。


演習3 ― Downsamplingの意味を変える

05_resampling_interpolation.ipynbで、週平均だけでなく週最大値も作ってください。

weekly_max = series.resample("7D").max()

平均と最大で、見えている情報がどのように違うか考えてみます。


演習4 ― Log Transformを戻す

sample_growth.csvへ対数変換を行ったあと、np.exp()で元のスケールへ戻してみます。

ヒントを見る
log_series = np.log(growth)
restored = np.exp(log_series)

浮動小数点の丸め誤差を除けば、ほぼ元の値へ戻ります。


13. Part 2 確認問題

問1

時系列CSVを読み込んだ直後に確認したいものを3つ挙げてください。

答えの例を見る

例えば、

  • 日時が正しく日時型として読めているか
  • 日時順に並んでいるか
  • 重複日時や抜けた日時がないか

などです。

件数、列型、基本統計量、欠測値なども確認対象になります。


問2

lag_1は何を表しますか。

答えを見る

現在時刻から1時刻前の観測値です。

日次データなら前日、10分データなら10分前になります。


問3

Rolling特徴量を予測に使うとき、情報漏洩を避けるために何を確認しますか。

答えを見る

予測対象時点や未来の値がWindowへ含まれていないことを確認します。

この教材では、shift(1)した過去系列に対してrolling()を行います。


問4

Upsamplingしただけで新しい実測値は増えますか。

答えを見る

増えません。

新しい時刻の行が増えるだけで、その時刻の観測値は存在しません。

Interpolationで埋めた値も推定値であり、実測値とは区別します。


問5

Moving AverageのWindowを大きくすると、どのような傾向になりますか。

答えを見る

一般に線は滑らかになります。

短期的な変動は弱くなりますが、急な変化への追従は遅くなります。


14. Part 2で覚えておきたいこと

Part 2は手法の数が多く見えますが、中心にある考え方はそれほど複雑ではありません。

1. まずデータを確認する

読めた

だけでは不十分です。

日時
順序
件数
重複
欠測
値の範囲

を見ます。

2. 特徴量は予測時点で使える情報から作る

LagもRollingも、未来情報を混ぜないことが基本です。

3. 可視化は加工の前後で使う

グラフは最後にきれいな図を作るためだけのものではありません。

変換前と変換後を見比べ、処理が妥当か考えるために使います。

4. Resamplingはデータの意味を考える

mean()、sum()、max()のどれを使うかは、データが何を表しているかで変わります。

5. 変換したら元へ戻すことも考える

予測結果を実務で使うなら、元の単位へ戻す処理まで含めて考えます。

6. Moving Averageは用途を分けて考える

平滑化
特徴量
予測

は同じMoving Averageでも目的が違います。


15. Part 2の全体像

ここまでをまとめると、次の流れになります。

11_part2_summary.png

Part 1では、

時系列を予測問題としてどう考えるか

を学びました。

Part 2では、

その予測問題へ入れるデータをどう作るか

を学びました。

次からは、そのデータ自体がどのような時間構造を持っているのかを調べます。


16. 次はPart 3 ― Temporal Structure

Part 3では、時系列の中にどのような構造があるのかを見ていきます。

扱う内容は次のとおりです。

12_part3.png

Part 2までは、データを「整える」作業が中心でした。

Part 3からは、

この時系列は、そもそも予測できそうな構造を持っているのか

というところへ入ります。

ここから時系列解析らしさがかなり強くなってきます。


参考資料

本記事は、次の書籍のPart 2を参考に、現在のPython環境とDocker + JupyterLabを使ったe-learning形式へ組み直しています。

  • Jason Brownlee, Introduction to Time Series Forecasting with Python, Part II: Data Preparation

    • Chapter 4: Load and Explore Time Series Data
    • Chapter 5: Basic Feature Engineering
    • Chapter 6: Data Visualization
    • Chapter 7: Resampling and Interpolation
    • Chapter 8: Power Transforms
    • Chapter 9: Moving Average Smoothing
  • Part 2 Source Zipfile


原書のコードは刊行当時のpandas APIを前提としている箇所があります。本記事では、現在の環境で実行しやすい書き方へ置き換えています。


0
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
0
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?