```{r}
library(conflicted) # 名前の衝突の警告を出してもらう
conflicts_prefer(
dplyr::filter(),
dplyr::select(),
)
library(tidyverse) # tidyverseの基本パッケージ群の読み込み
library(ggfortify) # 分析結果の視覚化にggplotを利用するためのパッケージ
library(GGally) # ggplotで散布図などを作成するためのパッケージ
library(gt) # 表を作成するためのパッケージ
#' macOSのための日本語表示の設定
if(Sys.info()["sysname"] == "Darwin") { # macOSか調べる
theme_update(text = element_text(family = "HiraMaruProN-W4"))
label_family <- "HiraMaruProN-W4"
} else {label_family <- NULL}
```
統計データ解析
第1講 サンプルコード
Quartoの使い方
Quarto とは
Quarto は Pandoc を利用した出版システムで,文章とプログラムをまとめて記述した上で,レポートやスライドあるいはWebページのような文書の作成を行うことができる. 同様な働きをするものとしては RStudio では R Markdown という形式が用意されているが,R 以外の言語 (Python や Julia) も利用できるという意味では R Markdown の発展形と捉えることもできる. R のプログラムを主として扱う形式である R Script でもプログラム中にコメントを残すことはできるが,コメントが多いとコードそのものが読み難いといった問題がある.
Quarto の構造
Quarto は,文書全体の体裁を整えるための YAMLヘッダー,プログラムを記述するチャンク(chunk),テキスト(markdown文)の3つの領域から構成される.
YAMLヘッダーは文書の先頭に置き,---
と ---
の間に必要な事項を記述する. この文書のYAMLヘッダーは以下のように書かれている.
---
title: "統計データ解析"
subtitle: "第1講 サンプルコード"
date: "2024-10-02"
format:
1 html:
toc: true
2 html-math-method: katex
self-contained: true
grid:
3 margin-width: 350px
execute:
4 echo: fenced
5reference-location: margin
citation-location: margin
tbl-cap-location: margin
fig-cap-location: margin
6warning: false
editor: visual
---
- 1
- HTML形式の文書を作成することを宣言する.
- 2
- TeXのレンダリングにKaTeXを利用する.
- 3
- 右側に大き目のマージンを指定する.
- 4
- チャンク内の情報を全て表示するように指定する.
- 5
- 脚注,文献,表や図の説明をマージンに表示する.
- 6
- 作成した文書中に警告を表示しない.
チャンクは ```{r}
(R言語の場合) と ```
の間にコードを記述する. 例えば,後の解析で共通に用いるパッケージ 1 を読み込むには以下のように記述する.
1 以下ではこの他に ggrepel
broom
MASS
などパッケージに含まれる関数の一部を利用するが,これらは個別に指定して利用する.
Rのコードはパッケージ knitr
2 を利用して処理される. また,文書全体を通して1つのプロセスが処理し,チャンク間で情報は共有されるため,前のチャンクでの計算結果を後のチャンクでも使うことができる.
2 knitr のオプションと Quarto の関係は Code Cells: Knitr に詳しく記載されている.
テキストは一般的な markdown 文法で解釈される. 数式はTeXの基本的な記述を理解するので,簡単な数式をそのまま記述することができる. テキスト中の数式は $ 数式 $
で,独立した数式は $$ 数式 $$
で記述する.
正規分布は \mathbb{R}=(-\infty,\infty) 上の確率分布で,平均 \mu 分散 \sigma^{2} である分布の密度関数は \phi(x) = \frac{1}{\sqrt{2\pi\sigma^{2}}}e^{-\frac{(x-\mu)^{2}}{2\sigma^{2}}} となる.
RStudio での利用
Quarto ファイルを開くと左上のペインに表示される. エディタの左上の Source/Visual
で表示を切り替えることができる. また Render
の右の設定で,文書の出力先 Window/Viewer Pane
,チャンクの実行結果の出力先 inline/console
を選択することができる.
単回帰分析
例として MASS::Animals
を用いる3. 拡張したデータフレーム形式である tibble
に変換して bb_data
で参照する.
3 オリジナルのデータは MASS::Animals
あるいは data(Animals, package = "MASS")
とすれば Animals
で参照することができる.
```{r}
bb_data <- MASS::Animals |> rownames_to_column() |> as_tibble()
```
このデータは28種類の動物の平均的な体重と脳の重さを調べたもの4で,データの内容を表にすると以下のようになる.
4 データの詳細は help(Animals, package = "MASS")
で確認することができる.
```{r}
#| label: tbl-bb
#| tbl-cap: 28種類の陸生動物の平均的な体重と脳の重さ.
bb_data |> gt()
```
body | brain | |
---|---|---|
Mountain beaver | 1.350 | 8.1 |
Cow | 465.000 | 423.0 |
Grey wolf | 36.330 | 119.5 |
Goat | 27.660 | 115.0 |
Guinea pig | 1.040 | 5.5 |
Dipliodocus | 11700.000 | 50.0 |
Asian elephant | 2547.000 | 4603.0 |
Donkey | 187.100 | 419.0 |
Horse | 521.000 | 655.0 |
Potar monkey | 10.000 | 115.0 |
Cat | 3.300 | 25.6 |
Giraffe | 529.000 | 680.0 |
Gorilla | 207.000 | 406.0 |
Human | 62.000 | 1320.0 |
African elephant | 6654.000 | 5712.0 |
Triceratops | 9400.000 | 70.0 |
Rhesus monkey | 6.800 | 179.0 |
Kangaroo | 35.000 | 56.0 |
Golden hamster | 0.120 | 1.0 |
Mouse | 0.023 | 0.4 |
Rabbit | 2.500 | 12.1 |
Sheep | 55.500 | 175.0 |
Jaguar | 100.000 | 157.0 |
Chimpanzee | 52.160 | 440.0 |
Rat | 0.280 | 1.9 |
Brachiosaurus | 87000.000 | 154.5 |
Mole | 0.122 | 3.0 |
Pig | 192.000 | 180.0 |
横軸に体重,縦軸に脳の重さを対数変換して描画したものが以下の図になる.
```{r}
#| label: fig-bb-loglog
#| fig-cap: 体重と脳の重さの両対数グラフ.
#| fig-width: 7
#| fig-height: 7
bb_p <- bb_data |>
ggplot(aes(body, brain)) +
geom_point(colour = alpha("royalblue", 0.75)) +
ggrepel::geom_text_repel(aes(label = rowname), # 各点の名前を追加
size = 3) +
scale_x_log10() + scale_y_log10() + # log-log plot を指定
labs(title = "Brain and Body Weights",
x = "body [kg]", y="brain [g]")
print(bb_p) # グラフを表示
```
両対数変換したデータにおいてはほぼ線形の関係が成り立っていることが見て取れるので,その関係式(回帰式)を推定して図示すると以下のようになる.
```{r}
#| label: fig-bb-lm
#| fig-cap: 回帰式とその信頼区間.
#| fig-width: 7
#| fig-height: 7
bb_p <- bb_p + # 回帰式を追加
geom_smooth(method = "lm",
colour = "dodgerblue",
fill = "dodgerblue")
print(bb_p) # グラフを表示
```
実際の分析においては, 回帰式の妥当性や外れ値などを考察する必要があり, そのための統計的な方法を学ぶ.
重回帰分析
例として配布データ wine.csv
を readr::read_csv()
用いて読み込み,以下 bw_data
で参照する.
```{r}
bw_data <- read_csv(file="data/wine.csv")
```
このデータはボルドー地区の何年かにわたるワインの価格と気候の関係を調べたもの5で,データは以下のとおりである.各列は生産年(VINT),対数変換した価格(LPRICE2),冬の降雨量(WRAIN),育成期平均気温(DEGREES),収穫期降雨量(HRAIN),評価までの経過年数(TIME_SV)を意味する.
```{r}
#| label: tbl-wine
#| tbl-cap: ボルドーワインの価格と気候の関係.
bw_data |> gt()
```
VINT | LPRICE2 | WRAIN | DEGREES | HRAIN | TIME_SV |
---|---|---|---|---|---|
1952 | -0.99868 | 600 | 17.1167 | 160 | 31 |
1953 | -0.45440 | 690 | 16.7333 | 80 | 30 |
1954 | NA | 430 | 15.3833 | 180 | 29 |
1955 | -0.80796 | 502 | 17.1500 | 130 | 28 |
1956 | NA | 440 | 15.6500 | 140 | 27 |
1957 | -1.50926 | 420 | 16.1333 | 110 | 26 |
1958 | -1.71655 | 582 | 16.4167 | 187 | 25 |
1959 | -0.41800 | 485 | 17.4833 | 187 | 24 |
1960 | -1.97491 | 763 | 16.4167 | 290 | 23 |
1961 | 0.00000 | 830 | 17.3333 | 38 | 22 |
1962 | -1.10572 | 697 | 16.3000 | 52 | 21 |
1963 | -1.78098 | 608 | 15.7167 | 155 | 20 |
1964 | -1.18435 | 402 | 17.2667 | 96 | 19 |
1965 | -2.24194 | 602 | 15.3667 | 267 | 18 |
1966 | -0.74943 | 819 | 16.5333 | 86 | 17 |
1967 | -1.65388 | 714 | 16.2333 | 118 | 16 |
1968 | -2.25018 | 610 | 16.2000 | 292 | 15 |
1969 | -2.14784 | 575 | 16.5500 | 244 | 14 |
1970 | -0.90544 | 622 | 16.6667 | 89 | 13 |
1971 | -1.30031 | 551 | 16.7667 | 112 | 12 |
1972 | -2.28879 | 536 | 14.9833 | 158 | 11 |
1973 | -1.85700 | 376 | 17.0667 | 123 | 10 |
1974 | -2.19958 | 574 | 16.3000 | 184 | 9 |
1975 | -1.20168 | 572 | 16.9500 | 171 | 8 |
1976 | -1.37264 | 418 | 17.6500 | 247 | 7 |
1977 | -2.23503 | 821 | 15.5833 | 87 | 6 |
1978 | -1.30769 | 763 | 15.8167 | 51 | 5 |
1979 | -1.53960 | 717 | 16.1667 | 122 | 4 |
1980 | -1.99582 | 578 | 16.0000 | 74 | 3 |
1981 | NA | 535 | 16.9667 | 111 | 2 |
1982 | NA | 712 | 17.4000 | 162 | 1 |
1983 | NA | 845 | 17.3833 | 119 | 0 |
1984 | NA | 591 | 16.5000 | 119 | -1 |
1985 | NA | 744 | 16.8000 | 38 | -2 |
1986 | NA | 563 | 16.2833 | 171 | -3 |
1987 | NA | 452 | 16.9833 | 115 | -4 |
1988 | NA | 808 | 17.1000 | 59 | -5 |
1989 | NA | 443 | NA | 82 | -6 |
変数の間の関係を散布図として描画すると以下のようになる.
```{r}
#| label: fig-wine-pairs
#| fig-cap: ボルドーワインの価格と気候の関係.
#| fig-width: 7
#| fig-height: 7
bw_data |>
ggpairs(columns = 2:6,
lower = list(continuous = wrap("smooth_loess", colour = "blue"))) +
theme(axis.title.x = element_text(size = 8), # 文字の大きさを調整
axis.title.y = element_text(size = 8))
```
ワインの価格を冬の降雨量(WRAIN),育成期平均気温(DEGREES),収穫期降雨量(HRAIN),年数(TIME_SV)で説明する回帰式は以下のように推定される.
```{r}
bw_fit <- lm(LPRICE2 ~ . - VINT, # VINTを除く全て
data = bw_data)
#' 推定結果を表にまとめるためのパッケージ gtsummary を利用
library(gtsummary)
library(broom.helpers) # gtsummary のいくつかの関数で利用(インストールされていれば不要)
bw_fit |>
tbl_regression(estimate_fun = label_style_sigfig(digits = 4)) |>
add_glance_source_note(include = c(r.squared, adj.r.squared))
```
Characteristic |
Beta |
95% CI |
p-value |
---|---|---|---|
WRAIN | 0.0012 | 0.0002, 0.0022 | 0.024 |
DEGREES | 0.6164 | 0.4190, 0.8138 | <0.001 |
HRAIN | -0.0039 | -0.0055, -0.0022 | <0.001 |
TIME_SV | 0.0238 | 0.0090, 0.0387 | 0.003 |
R² = 0.828; Adjusted R² = 0.796 |
|||
1 CI = Confidence Interval |
重回帰による予測値と実際の価格を比較すると以下のようになる. 良好な予測が行われていることが視覚的に確認できる.
```{r}
#| label: fig-bw-prediction
#| fig-cap: 重回帰による予測値と実際の価格
#| fig-width: 7
#| fig-height: 7
bw_fit |>
broom::augment() |>
ggplot(aes(x = LPRICE2, y = .fitted, label = VINT)) +
geom_text(na.rm = TRUE) + # text で表示
geom_abline(slope = 1, colour = "red") +
labs(title = "Bordeaux Wine Price",
x = "Price (log)", y = "Prediction")
```
主成分分析
県別の生活環境に関するデータ jpamenity.csv
6を用いる. 補助的な情報なども含めて整理したデータフレームを ja_data
とする.
6 配布したデータ jpamenity.csv
には,政府統計の総合窓口から取得した以下の25項目が,各県ごとにまとめられている. 昼夜間人口比率(%),年少人口割合[15歳未満人口](%),老年人口割合[65歳以上人口](%),人口増減率(%),粗出生率(人口千人当たり),粗死亡率(人口千人当たり),婚姻率(人口千人当たり),離婚率(人口千人当たり),高等学校数(15〜17歳人口10万人当たり)(校),高等学校数(可住地面積100k㎡当たり)(校),高等学校卒業者の進学率(%),労働力人口比率[男](%),労働力人口比率[女](%),完全失業率[男](%),完全失業率[女](%),交通事故発生件数(人口10万人当たり)(件),刑法犯認知件数(人口千人当たり)(件),食料費割合[二人以上の世帯](%),住居費割合[二人以上の世帯](%),教育費割合[二人以上の世帯](%),平均貯蓄率[勤労者世帯](%),趣味・娯楽の平均時間[有業者・男](時間.分),趣味・娯楽の平均時間[無業者・男](時間.分),趣味・娯楽の平均時間[有業者・女](時間.分),趣味・娯楽の平均時間[無業者・女](時間.分). また jpamenityitem.csv
には簡略化した項目名が記載されている.
```{r}
## 元のデータに県名と地方名を付加してデータフレームを作成する
ja_data <- bind_cols(
read_csv(file = "data/prefecture.csv",
col_select = c(2,4)) |>
set_names("県名", "地方名"), # 列の名称を"県名"と"地方名"に変更
read_csv(file = "data/jpamenity.csv",
col_select = !1:2) |> slice(-1) |>
set_names(names(read_csv(file = "data/jpamenityitem.csv")))) # 簡略化した項目名に変更
```
データの一部を表形式で表示すると以下のようになる.
```{r}
#| label: tab-ja-data
ja_data |>
select(1:10) |> slice(1:15) |> # 大きな表なので一部を選択する(列:select,行:slice)
gt()
```
県名 | 地方名 | 昼夜人口比 | 年少人口比 | 老年人口比 | 人口増減率 | 粗出生率 | 粗死亡率 | 婚姻率 | 離婚率 |
---|---|---|---|---|---|---|---|---|---|
北海道 | 北海道 | 100.0 | 11.7 | 26.0 | -0.47 | 7.09 | 10.63 | 4.86 | 2.12 |
青森県 | 東北 | 100.0 | 12.1 | 27.0 | -0.95 | 6.79 | 12.81 | 4.33 | 1.78 |
岩手県 | 東北 | 99.7 | 12.4 | 27.9 | -0.84 | 7.12 | 12.33 | 4.32 | 1.52 |
宮城県 | 東北 | 100.2 | 13.0 | 22.9 | -0.09 | 8.05 | 9.51 | 5.30 | 1.70 |
秋田県 | 東北 | 99.9 | 11.1 | 30.7 | -1.12 | 6.16 | 13.98 | 3.78 | 1.41 |
山形県 | 東北 | 99.8 | 12.6 | 28.3 | -0.78 | 7.13 | 12.81 | 4.24 | 1.46 |
福島県 | 東北 | 99.6 | 12.9 | 26.1 | -1.41 | 7.02 | 11.94 | 4.73 | 1.64 |
茨城県 | 関東 | 97.2 | 13.2 | 23.8 | -0.51 | 7.78 | 10.20 | 4.92 | 1.79 |
栃木県 | 関東 | 99.1 | 13.2 | 23.2 | -0.40 | 8.02 | 10.43 | 5.13 | 1.85 |
群馬県 | 関東 | 99.9 | 13.4 | 24.9 | -0.45 | 7.49 | 10.63 | 4.64 | 1.77 |
埼玉県 | 関東 | 88.6 | 13.0 | 22.0 | 0.07 | 7.90 | 8.20 | 5.10 | 1.86 |
千葉県 | 関東 | 89.5 | 12.8 | 23.2 | -0.31 | 7.89 | 8.59 | 5.19 | 1.86 |
東京都 | 関東 | 118.4 | 11.3 | 21.3 | 0.26 | 8.12 | 8.25 | 6.75 | 1.91 |
神奈川県 | 関東 | 91.2 | 13.0 | 21.5 | 0.10 | 8.32 | 7.94 | 5.68 | 1.85 |
新潟県 | 中部 | 100.0 | 12.5 | 27.2 | -0.64 | 7.45 | 11.97 | 4.35 | 1.37 |
関連の強い項目ごとに3つのグループに分け, それぞれのグループで散布図を作成する.
```{r}
#| label: fig-ja-pairs1
#| fig-cap: 県別の生活環境(人口動態に関連する項目)
#| fig-width: 7
#| fig-height: 7
ja_data |>
GGally::ggscatmat(columns = 3:10, color = "地方名", alpha = .5) +
theme(text = element_text(size = 8))
```
```{r}
#| label: fig-ja-pairs2
#| fig-cap: 県別の生活環境(教育・労働などに関連する項目)
#| fig-width: 7
#| fig-height: 7
ja_data |>
GGally::ggscatmat(columns = 11:19, color = "地方名", alpha = .5) +
theme(text = element_text(size = 8))
```
```{r}
#| label: fig-ja-pairs3
#| fig-cap: 県別の生活環境(貯蓄・余暇などに関連する項目)
#| fig-width: 7
#| fig-height: 7
ja_data |>
GGally::ggscatmat(columns = 20:27, color = "地方名", alpha = .5) +
theme(text = element_text(size = 8))
```
25次元のデータを主成分分析を用いて2次元に縮約し, 各県の特性をバイプロットで図示すると以下のようになる.
```{r}
#| label: fig-ja-biplot
#| fig-cap: 県別の生活環境の主成分分析
#| fig-width: 7
#| fig-height: 7
ja_fit <- ja_data |>
column_to_rownames(var = "県名") |>
select(where(is.double)) |>
prcomp(scale. = TRUE) # 主成分分析の実行
autoplot(ja_fit, # バイプロット
data = ja_data,
shape = FALSE, label = TRUE, loadings = TRUE, loadings.label = TRUE,
label.family = label_family, loadings.label.family = label_family,
label.size = 3, loadings.label.size = 3.5)
```
判別分析
例として MASS::biopsy
7 を用いる. 不要な項目を削除し整理したものを bio_data
とする.
7 データの詳細は help(biopsy, package = "MASS")
で確認することができる.
```{r}
bio_data <- MASS::biopsy |>
as_tibble() |>
na.omit() |> # NA を除く
select(-ID) # IDを除く
```
このデータは乳癌の良性・悪性と9種類の生検との関係を700弱の患者について調べたものである. 生検同士の関係と良性・悪性を散布図に図示すると以下のようになる.
```{r}
#| label: fig-bio-pairs
#| fig-cap: 9種類の生検の散布図.
#| fig-width: 7
#| fig-height: 7
bio_data |>
GGally::ggpairs(diag = list(mapping = aes(colour = class)),
lower = list(mapping = aes(colour = class)))
```
以下の図は,9種類の生検の相互の関係を主成分分析を用いて2次元に縮約し,良性・悪性との関係を視覚的に捉えたものである.
```{r}
#| label: fig-bio-pca
#| fig-cap: 主成分分析を用いて2次元に縮約した生検と良性・悪性の関係.
#| fig-width: 7
#| fig-height: 7
autoplot(bio_data |> select(where(is.numeric)) |> prcomp(), # 主成分分析
data = bio_data,
colour = "class") +
theme(legend.position=c(.9,.85))
```
線形判別分析では,回帰分析と同様に説明変数(この場合は9種類の生検の値)の重み付けた値(判別関数値)によりクラスの判別を行う. このデータにより作成された判別関数値のクラスごとの分布を表示すると以下のようになる. クラスごとに大きく異なる分布となっていることがわかる.
```{r}
#| label: fig-bio-discriminant
#| fig-cap: 線形判別関数による判別関数値の分布.
#| fig-width: 7
#| fig-height: 7
library(MASS) # パッケージ MASS に含まれる判別分析のための関数を利用
bio_fit <- lda(class ~ ., data = bio_data)
bio_data |>
mutate(x = predict(bio_fit)$x) |>
ggplot(aes(x = x)) +
geom_histogram(aes(fill = class), show.legend = FALSE) +
facet_grid(class ~ .)
```
クラスタ分析
データ例として omusubi.csv
8 を用いる. 補助的な情報を付加して om_data
とする.
8 このデータは おむすびの日アンケート で公開されていたものの(2009年版)であるが,現在は公開されていないようである.
```{r}
om_data <- bind_cols(
read_csv(file = "data/omusubi.csv"),
read_csv(file = "data/prefecture.csv")) # 県名・地方名の情報を付加
```
県別の人気比率を図示すると以下のようになる.
```{r}
#| label: fig-om-barplot
#| fig-cap: おむすびの具の県別人気アンケート (2009年度実施).
#| fig-width: 7
#| fig-height: 7
om_data |>
select(ume:etc,jp) |>
set_names(c("梅","鮭","昆布","鰹","明太子","鱈子","ツナ","その他","県名")) |>
pivot_longer(-県名) |>
mutate(県名 = fct_rev(as_factor(県名)),
name = as_factor(name)) |>
ggplot(aes(y = 県名, x = value)) +
geom_bar(aes(fill = name),
stat = "identity",
position = position_stack(reverse=TRUE)) +
labs(x = "人気比率", fill = "具材") +
theme(axis.text.y = element_text(size = 9))
```
比率は確率分布と見ることができるので,県同士の人気比率の距離を分布間の距離の一つである Hellinger 距離 9 を用いて測り,階層的クラスタリングを行う. 結果をデンドログラムとして表示すると以下のようになる.
9 比率を表すベクトルを1/2乗してEuclid距離を計算すればHellinger距離に比例した量が得られる.
```{r}
#| label: fig-om-dendrogram
#| fig-cap: おむすびの具人気アンケート結果のもとづく階層的クラスタリング.県別の人気比率のHellinger距離を群平均法により分析した.
#| fig-width: 7
#| fig-height: 7
library(cluster) # クラスタ分析のためのパッケージ
library(ggdendro) # ggplot でデンドログラムを描くためのパッケージ
om_agnes <-
om_data |>
select(ume:etc,jp) |>
set_names(c("梅","鮭","昆布","鰹","明太子","鱈子","ツナ","その他","県名")) |>
column_to_rownames(var = "県名") |>
sqrt() |>
agnes()
om_agnes |> as.dendrogram() |>
ggdendrogram(rotate = TRUE, theme_dendro = FALSE) +
labs(x = "県名", y = "距離") +
theme(axis.text.y = element_text(size = 9))
```
時系列解析
例として datasets::AirPassengers
を用いる10.
10 datasets
のデータは起動時に読み込まれでるので,特に準備はいらない.データの詳細は help(AirPassengers)
で確認することができる.
```{r}
library(tsibble) # 時系列を扱うためのパッケージ
library(feasts) # ggplotで時系列を扱うための拡張パッケージ
library(fable) #
```
時系列のためのデータ形式になっており,Console 上ではそのまま適切に表示されるが,表形式にするには若干工夫が必要となる.
```{r}
#| label: tbl-ap
#| tbl-cap: 1949年から1960年における米国における月ごとの国際線乗客数の変遷.
ap_tsbl <- AirPassengers |> as_tsibble() # 時系列向きの形式に変換
ap_tsbl |>
mutate(Year = year(index),
Month = month(index, label = TRUE)) |>
as_tibble() |> select(!index) |> #
pivot_wider(names_from = Month) |>
gt() |>
tab_header(title = "Monthly Airline Passenger Numbers",
subtitle = "1949-1960")
```
Monthly Airline Passenger Numbers | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
1949-1960 | ||||||||||||
Year | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
1949 | 112 | 118 | 132 | 129 | 121 | 135 | 148 | 148 | 136 | 119 | 104 | 118 |
1950 | 115 | 126 | 141 | 135 | 125 | 149 | 170 | 170 | 158 | 133 | 114 | 140 |
1951 | 145 | 150 | 178 | 163 | 172 | 178 | 199 | 199 | 184 | 162 | 146 | 166 |
1952 | 171 | 180 | 193 | 181 | 183 | 218 | 230 | 242 | 209 | 191 | 172 | 194 |
1953 | 196 | 196 | 236 | 235 | 229 | 243 | 264 | 272 | 237 | 211 | 180 | 201 |
1954 | 204 | 188 | 235 | 227 | 234 | 264 | 302 | 293 | 259 | 229 | 203 | 229 |
1955 | 242 | 233 | 267 | 269 | 270 | 315 | 364 | 347 | 312 | 274 | 237 | 278 |
1956 | 284 | 277 | 317 | 313 | 318 | 374 | 413 | 405 | 355 | 306 | 271 | 306 |
1957 | 315 | 301 | 356 | 348 | 355 | 422 | 465 | 467 | 404 | 347 | 305 | 336 |
1958 | 340 | 318 | 362 | 348 | 363 | 435 | 491 | 505 | 404 | 359 | 310 | 337 |
1959 | 360 | 342 | 406 | 396 | 420 | 472 | 548 | 559 | 463 | 407 | 362 | 405 |
1960 | 417 | 391 | 419 | 461 | 472 | 535 | 622 | 606 | 508 | 461 | 390 | 432 |
横軸に時間をとり,その変遷を図示すると以下のようになる.
```{r}
#| label: fig-ap-timeseries
#| fig-cap: 米国の国際線乗客数の変遷.
#| fig-width: 7
#| fig-height: 7
ap_tsbl |>
autoplot(value) +
labs(title = "AirPassengers",
x = "Year", y = "Passengers/1000")
```
ほぼ線形のトレンドと増大する分散変動があることがわかる. 分散変動を安定化するために以下では対数変換したデータを扱う. また,時系列の予測の精度を評価するために,訓練データを試験データに分割する.
```{r}
ap_train <- ap_tsbl |> filter_index(~ "1958-12") # 訓練データ
ap_test <- ap_tsbl |> filter_index("1959-01" ~ .) # 試験データ(2年分)
```
階差を取ることによって定常化できるかどうか検討する.
```{r}
#| label: fig-ap-difference
#| fig-cap: 対数変換と階差による時系列の定常化の検証.
#| fig-width: 7
#| fig-height: 7
ap_train |>
gg_tsdisplay(difference(log(value)),
plot_type = "partial")
```
対数変換した訓練データでSARIMAモデルを推定し,試験データの予測を行う.
```{r}
#| label: fig-ap-prediction
#| fig-cap: SARIMAモデルの推定と予測.
#| fig-width: 7
#| fig-height: 7
ap_fit <- ap_train |> model(sarima = ARIMA(log(value))) # SARIMAモデルの推定(次数は自動推定)
ap_fit |>
forecast(h = nrow(ap_test)) |>
autoplot(ap_train) +
autolayer(ap_test, value, colour = "purple") +
labs(title = "Forecast from SARIMA model",
x = "Year", y = "Passengers/1000")
```