axjack's blog

### axjack is said to be an abbreviation for An eXistent JApanese Cool Klutz ###

コンプガチャ問題

おまけを10種類揃えるには?

  • おまけが全部で25種類の、とあるお菓子がある
  • 一個税込143円である
  • 25種類中欲しいのは10種類
  • 1種類目が当たる確率は10/25
  • 2種類目が当たる確率は9/25
  • 10種類目が当たる確率は1/25
  • 一般に、確率pのものを引き当てるために必要となる購入回数の期待値は1/pである(幾何分布)
  • よって10種類コンプリートするためには平均で


\displaystyle (10/25)^{-1} + (9/25)^{-1} + \cdots + (1/25)^{-1}

回購入すれば良い。これを計算すると、

f <- function(x,N){
p <- (1:x)/N
sum(1/p)
}

f(10,25)
[1] 73.22421

約73回購入することとなる。金額に換算すると143×73 = 10,471円となる。
1万円札と500円玉を握りしめて大人買いすれば10種類コンプリートできるかもしれない。

幾何分布の復習

  • 確率変数Yが幾何分布Geo(p)に従うとする。
  • ここでpは成功確率、q = 1-pとする。
  • 確率質量関数はP(Y=y) = pq^y
  • つまりy回連続で外れを引いてy+1回目で初成功するような確率である
  • 確率母関数はG(s)=E(s^Y)=\sum s^y p q^y = p \sum (qs)^y = p (1-qs)^{-1}である
  • 確率母関数を使うと、期待値がq/pとなる
  • この期待値は「y回外れを引いてy+1回目で初成功する」ときのYに関する期待値である
  • つまり、初成功する回"目"の期待値はq/p1を足してq/p + 1 = 1/p となる。

おまけを25種類コンプリートするには?

では、1種類コンプリート・2種類コンプリート・…・25種類コンプリートにかかる平均購入回数は?計算すると

data.frame(
種類=paste(1:25,'種類')
,平均購入回数 = vapply(1:25, f, 0, N=25)
) |> kable()

種類 平均購入回数
1 種類 25.00000
2 種類 37.50000
3 種類 45.83333
4 種類 52.08333
5 種類 57.08333
6 種類 61.25000
7 種類 64.82143
8 種類 67.94643
9 種類 70.72421
10 種類 73.22421
11 種類 75.49693
12 種類 77.58027
13 種類 79.50334
14 種類 81.28906
15 種類 82.95572
16 種類 84.51822
17 種類 85.98881
18 種類 87.37770
19 種類 88.69349
20 種類 89.94349
21 種類 91.13397
22 種類 92.27033
23 種類 93.35729
24 種類 94.39895
25 種類 95.39895


となる。

さて本当に幾何分布であっているのか?ということで、幾何分布に従う乱数を生成して確認する。

f2 <- function(nn,p){
mean( rgeom(nn,p)+1 )
}

nn <- 1000
data.frame(
種類=paste(1:25,'種類')
,幾何分布の乱数で計算した平均購入回数 =mapply(f2,nn,(1:25)/25) |> cumsum()
) |> kable()

種類 幾何分布の乱数で計算した平均購入回数
1 種類 25.2860
2 種類 37.6042
3 種類 46.1189
4 種類 52.3534
5 種類 57.3745
6 種類 61.5205
7 種類 65.1356
8 種類 68.2428
9 種類 70.9967
10 種類 73.4832
11 種類 75.7831
12 種類 77.8665
13 種類 79.7682
14 種類 81.5705
15 種類 83.2414
16 種類 84.7918
17 種類 86.2650
18 種類 87.6587
19 種類 88.9822
20 種類 90.2273
21 種類 91.4115
22 種類 92.5498
23 種類 93.6351
24 種類 94.6796
25 種類 95.6796


となる。だいたいあっている。

参考文献:
www.bandai.co.jp

統計学実践ワークブック 第1章 事象と確率 問1.3

[解くときのコツ]

  • 1段階目 → 解けるけど腑に落ちない
    • 条件付き確率を使った典型例*1ではあるが、やはり難しい。1%とか99%とか0.1%などといった微妙な数字が並んで混乱しがち。なんとなく計算はできるけど立式の見通しが立たない。気合いで解けることはある。解答を見ても分子分母がやたらと長くて萎える。
  • 2段階目 → 面積図*2?を書いてみる
    • 立式が思い付かないけど図さえ書ければ解けることに気づく。解ければいいっしょ、というスタンス。
  • 3段階目 → 全て記号で考える
    • 図を書くのが面倒になる。むしろ記号で表すことができれば、手書きでもプレーンテキストでもLaTeXでも書けてたとえツールが何もなくても口頭で(頭上で?暗唱で?)式を展開できるという利便性に気づく。

問1.3の概要

ワークブックp.4を参照。

条件付き確率

定義

 P(A|B) = \frac{ P(A,B) }{  P(B) }

亜種と簡単な応用

事象が増えたバージョン

 \displaystyle P(左|右) = \frac{P(左,右)}{P(右)}

  \displaystyle  P(A,B|C ) = \frac{P(A,B,C)}{P(C)}

  \displaystyle  P(A|B,C ) = \frac{P(A,B,C)}{P(B,C)}

余事象を挿入する

 P(A|B) = \frac{ P(A,B) }{  P(B) } = \frac{ P(A,B,X) + P(A,B,X^C)} {P(B)} \\
= P(A,X|B) + P(A,X^C|B)

その他

「事象Aで条件つけた事象X、の確率」と「事象Aで条件つけた『事象Xの余事象』、の確率」の和は1
 P(X|A) + P(X^C|A) = \frac{P(X,A)}{P(A)} + \frac{P(X^C,A)}{P(A)} \\
= \frac{P(X,A) + P(X^C,A)}{P(A)} \\
= \frac{P(A)}{P(A)} = 1

3つの事象の積事象を条件付き確率で分解する
 P(A,B,C) = P(A|B,C)P(B,C) \\
= P(A|B,C)P(B|C)P(C)

まれによく見る変形
 P(A,B| C) = \frac{  P(A,B,C) } {P(C)} = \frac{P(A|B,C)P(B,C)}{P(C)} \\
= P(A|B,C)P(B|C)

解答

情報をまとめると、

記号 確率 内容
P(X) 1/100 病気である確率
P(X^C) 99/100 病気ではない確率
P(Y_1 \mid X) 99/100 病気の人が検査1で陽性となる確率
P(Y_1 \mid X^C ) 2/100 病気ではない人が検査1で陽性となる確率
P(Y_2 \mid Y_1, X) 90/100 病気であり検査1で陽性となった人、が検査2で陽性となる確率
P(Y_2 \mid Y_1, X^C ) 10/100 病気ではないが検査1で陽性となった人、が検査2で陽性となる確率

[1]

P(X|Y_1)を求めれば良い。条件付き確率より、


\displaystyle P(X|Y_1) = \frac{ P(X,Y_1) } { P(Y_1) }\\
\displaystyle = \frac{P(Y_1,X) } { P(Y_1) } \\
\displaystyle = \frac{ P(Y_1|X)P(X) } { P(Y_1) }\\
\displaystyle = \frac{ P(Y_1|X)P(X) } { P(Y_1,X) + P(Y_1,X^C) }\\
\displaystyle = \frac{ P(Y_1|X)P(X) } { P(Y_1|X)P(X) + P(Y_1|X^C)P(X^C) }

[2]

 P(X|Y_2, Y_1 )を求めれば良い。


\displaystyle P(X|Y_2, Y_1 ) = \frac{P(X,Y_2,Y_1)}{P(Y_2,Y_1)}\\
\displaystyle = \frac{P(Y_2,X,Y_1)}{P(Y_2,Y_1)}\\
\displaystyle = \frac{P(Y_2|X,Y_1)P(X,Y_1)}{P(Y_2,Y_1)}\\
\displaystyle = \frac{P(Y_2|X,Y_1)P(X|Y_1)P(Y_1)}{P(Y_2,Y_1)}\\
\displaystyle = \frac{P(Y_2|X,Y_1)P(X|Y_1)}{\frac{P(Y_2,Y_1)}{P(Y_1)}}\\
\displaystyle = \frac{P(Y_2|X,Y_1)P(X|Y_1)}{P(Y_2|Y_1)}\\
\displaystyle = \frac{P(Y_2|X,Y_1)P(X|Y_1)}{  P(Y_2,X|Y_1) + P(Y_2,X^C|Y_1 ) }  \\
\displaystyle = \frac{P(Y_2|X,Y_1)P(X|Y_1)}{  P(Y_2|X,Y_1)P(X|Y_1) + P(Y_2|X^C,Y_1)P(X^C|Y_1)  }  \\

*1:「条件付き確率 病気」もしくは「ベイズの定理 病気」で検索。

*2:「条件付き確率 面積図」で検索。

統計学実践ワークブック 第31章 ベイズ法 の例1

問題の概要

  • 設定
    • 普及率p
    • 20世帯中x世帯が保有している
    • pの事前分布にはベータ分布:Beta(2,20)を仮定
    • 事後分布を求めよ

回答

ベイズモデルとして考えるとパラメトリックモデルは、

X|p \sim Bin(20,p), \\
f(X = x |p) = {}_{20}C_x p^{x} (1-p)^{20-x}

であり、事前分布は、

p \sim Beta(2,20),\\
\pi(p|2,20) = \frac{  p^{2-1}(1-p)^{20-1}  }{beta(2,20)}

となる。したがって事後分布は


\displaystyle \pi(p|X) = \frac{ f(X|p)\pi(p|2,20)  }{ ∫_{p}^{} f(X|p)\pi(p|2,20)dp } \\
\displaystyle = \frac{   {}_{20}C_x p^{x} (1-p)^{20-x}   \frac{  p^{2-1}(1-p)^{20-1}  }{beta(2,20)}   }{  ∫_{p}^{}  {}_{20}C_x p^{x} (1-p)^{20-x}   \frac{  p^{2-1}(1-p)^{20-1}  }{beta(2,20)}  } \\
\displaystyle = \frac{   p^{x+1} (1-p)^{39-x} }  {  ∫_{p}^{} p^{x+1} (1-p)^{39-x} dp } \\
\displaystyle = \frac{   p^{(x+2)-1} (1-p)^{(40-x)-1}   }  {  ∫_{p}^{} p^{(x+2)-1} (1-p)^{(40-x)-1} dp } \\
\displaystyle = \frac{   \frac{p^{(x+2)-1} (1-p)^{(40-x)-1}}{beta(x+2,40-x)}   }  {  ∫_{p}^{}   \frac{p^{(x+2)-1} (1-p)^{(40-x)-1}}{beta(x+2,40-x)} dp } \\
\displaystyle = \frac{   \frac{p^{(x+2)-1} (1-p)^{(40-x)-1}}{beta(x+2,40-x)}   }  { 1 } \\
\displaystyle =  \frac{p^{(x+2)-1} (1-p)^{(40-x)-1}}{beta(x+2,40-x)}  \\

となる。よって、事後分布はベータ分布:Beta(x+2,40-2)となる。

統計学実践ワークブック 第27章 時系列解析 より、AR(1)過程

AR(1)過程についてまとめます。

共分散定常過程

時系列 \{Y_t\}が、

  • 期待値:時点によらず一定(  \mathrm{E}[ Y_t ] = \mu )
  • 分散:時点によらず一定(  \mathrm{V}[ Y_t ] = \gamma_0 )
  • 自己共分散:時点によらないが時点の差に依存する( \mathrm{Cov}[Y_t, Y_{t-h} ] = \gamma_{|h|} \ )

のとき、共分散定常過程であるという。

AR(1)過程

 \{ Y_t \}が以下で表されるものを次数1のAR過程( Auto Regressive process order 1 )といい、AR(1)と略す。

 \displaystyle Y_t = c + \phi Y_{t-1} + U_t

ただし、c,\phiは定数で U_t は ホワイトノイズ( W.N.(0,\sigma^2))である。

以下、AR(1)過程が共分散定常であるとする。

AR(1)過程の期待値

 \mathrm{E}[ Y_t ] = \mathrm{E}[    c + \phi Y_{t-1} + U_t  ] \\
=  \mathrm{E}[  c  ]  + \mathrm{E}[  \phi Y_{t-1}  ]  +  \mathrm{E} [ U_t  ]  \\
=  c  +  \phi \mathrm{E}[  Y_{t-1}  ]  +  0 \\
=  c  +  \phi \mathrm{E}[  Y_{t}  ]  +  0 \\
=  c  +  \phi \mu +  0 \\
= \mu

より、

 \displaystyle \mu = \frac{c}{1-\phi}

AR(1)過程の分散

 \mathrm{V}[  Y_t ] = \mathrm{V}[  c + \phi Y_{t-1} + U_t   ] \\
= \mathrm{V}[  c  ] + \mathrm{V}[ \phi Y_{t-1} ]  + \mathrm{V}[ U_t ] \\
= 0+ \phi ^2 \mathrm{V}[ Y_{t-1} ]  + \sigma^2 \\
= \phi ^2 \mathrm{V}[ Y_{t} ]  + \sigma^2 \\
= \phi ^2 \gamma_0 + \sigma^2 \\
=  \gamma_0

より、

 \displaystyle \gamma_0 = \frac{\sigma^2}{1 - \phi ^ 2 }


AR(1)過程の自己共分散

時点差hの自己共分散を考えると、

 \mathrm{Cov}[ Y_{t-h}, Y_t ] = \mathrm{Cov}[ Y_{t-h},  c + \phi Y_{t-1} + U_t ] \\
= \mathrm{Cov}[Y_{t-h}, c] +  \phi  \mathrm{Cov}[Y_{t-h}, Y_{t-1} ] + \mathrm{Cov}[Y_{t-h}, U_t ] \\
= 0 +  \phi  \gamma_{h-1} + 0 \\
=  \phi  \gamma_{h-1} 
= \gamma_{h}

より、

 \displaystyle \gamma_{h} = \phi \gamma_{h-1} = \phi^2 \gamma_{h-2} = \cdots = \phi ^ h \gamma_{0}

AR(1)過程 → MA(∞)過程

c = 0としてAR(1)過程をラグオペレータを用いて記述すると、

 Y_t =  \phi Y_{t-1} + U_t  \\
= \phi L Y_t + U_t

となる。\phi L Y_t を左辺に移行し整理すると、

 Y_t = \phi L Y_t + U_t \\
\iff Y_t - \phi L Y_t = U_t \\
\iff (1 - \phi L) Y_t = U_t \\
\iff (1 - \phi L)^{-1} (1 - \phi L) Y_t = (1 - \phi L)^{-1}  U_t \\
\iff Y_t = (1 - \phi L)^{-1}  U_t \\

ここでラグオペレータの性質より

 \displaystyle (1 - \phi L) ^ {-1} = 1 + \sum_{j = 1} ^ {\infty} (\phi L )^j

を用いると、

 Y_t = (1 - \phi L)^{-1}  U_t \\
\iff Y_t = (1 + \sum_{j = 1} ^ {\infty} (\phi L )^j ) U_t \\
\iff Y_t = (1 + \phi L + \phi^2 L^2 + \cdots  ) U_t \\
\iff Y_t = U_t + \phi L U_t + \phi^2 L^2 U_t + \cdots  \\
\iff Y_t = U_t + \phi U_{t-1} + \phi^2 U_{t-2} + \cdots

となるので、これはMA(∞)過程に等しい。


AR(1)過程のスペクトラムの前に自己共分散母関数

 \displaystyle g_Y(z) = \sum_{j = - \infty}^{\infty} \gamma_j z^j

を時系列 \{Y_t\}の自己共分散母関数(autocovariance generating function)という。ただし z \in \mathbb{C}とする。
 g_Y(z)を用いると、スペクトラム(スペクトル密度関数)は、

 \displaystyle f(\lambda) = \frac{1}{2\pi} g_Y( e^{-i\lambda} ) \\
= \displaystyle \frac{1}{2 \pi} \sum_{j = -\infty}^{\infty} \gamma_j e^{-i\lambda j}

と表せる。なので、スペクトラムを計算する前に自己共分散母関数を先に求めておく。

AR(1)過程の自己共分散母関数を求めると、


 g_Y(z) = \displaystyle \sum_{j = - \infty}^{\infty} \gamma_j z^j  \\
= \displaystyle \sum_{j = - \infty}^{-1} \gamma_j z^j    +    \sum_{j = 0}^{0} \gamma_j z^j   +  \sum_{j = 1}^{\infty} \gamma_j z^j  \\
= \displaystyle \sum_{j = 1}^{\infty} \gamma_{-j} z^{-j}    +    \gamma_0 z^0   +  \sum_{j = 1}^{\infty} \gamma_j z^j  \\
= \displaystyle \sum_{j = 1}^{\infty} \gamma_{j} z^{-j}    +    \gamma_0   +  \sum_{j = 1}^{\infty} \gamma_j z^j  \\
= \displaystyle \sum_{j = 1}^{\infty} \phi^j \gamma_0 (z^{-1})^j    +    \gamma_0   +  \sum_{j = 1}^{\infty} \phi^j \gamma_0 z^j  \\
=  \gamma_0 \left(   \displaystyle \sum_{j = 1}^{\infty} (\phi z^{-1} )^j    +    1  +  \sum_{j = 1}^{\infty} (\phi z)^j    \right)\\
=  \gamma_0 \left(   \displaystyle   (1 + \sum_{j = 1}^{\infty} (\phi z^{-1} )^j)    +    1  +  (1 + \sum_{j = 1}^{\infty} (\phi z)^j)    -2 \right)\\
=  \gamma_0 \left(   \displaystyle   (1 + \sum_{j = 1}^{\infty} (\phi z^{-1} )^j   ) + ( 1 + \sum_{j = 1}^{\infty} (\phi z)^j )   -1 \right)\\
=  \gamma_0 \left(   \displaystyle   \frac{1}{1 - \phi z^{-1}  }    +  \frac{1}{1 - \phi z }   -1 \right)\\
=  \gamma_0 \left(   \displaystyle    \frac{  (1 - \phi z^{-1}) + (1 - \phi z ) - (1 - \phi z^{-1})(1 - \phi z) } { (1 - \phi z^{-1})(1 - \phi z) }          \right)\\
=  \gamma_0 \left(   \displaystyle    \frac{  (1 - \phi z^{-1}) + (1 - \phi z ) - (1 - \phi z^{-1}  - \phi z  + \phi^2) } { (1 - \phi z^{-1})(1 - \phi z) }          \right)\\
=  \gamma_0 \left(   \displaystyle    \frac{  (1 -  \phi^2) } { (1 - \phi z^{-1})(1 - \phi z) }          \right)\\
=  \displaystyle   \frac{\sigma^2}{1-\phi^2}   \left(      \frac{  (1 -  \phi^2) } { (1 - \phi z^{-1})(1 - \phi z) }          \right)\\
=  \displaystyle    \frac{  \sigma^2  } { (1 - \phi z^{-1})(1 - \phi z) }   \\

となる。

AR(1)過程のスペクトラム

AR(1)過程の自己共分散母関数より、 g_Y(z) = \frac{  \sigma^2  } { (1 - \phi z^{-1})(1 - \phi z) } を用いて、

 \displaystyle f(\lambda) = \frac{1}{2\pi} g_Y( e^{-i\lambda} ) \\
= \displaystyle    \frac{1}{2\pi}  \frac{  \sigma^2  } { (1 - \phi (e^{-i\lambda})^{-1})(1 - \phi e^{-i\lambda}) }  \\
= \displaystyle    \frac{1}{2\pi}  \frac{  \sigma^2  } { (1 - \phi e^{i\lambda} )(1 - \phi e^{-i\lambda}) }  \\
= \displaystyle    \frac{1}{2\pi}  \frac{  \sigma^2  } { 1 -  \phi e^{i\lambda}  -   \phi e^{-i\lambda} +  \phi e^{i\lambda} \phi e^{-i\lambda}    }     \\
= \displaystyle    \frac{1}{2\pi}  \frac{  \sigma^2  } { 1 + \phi^2  -  \phi (e^{i\lambda} +  e^{-i\lambda} ) }     \\
= \displaystyle    \frac{1}{2\pi}  \frac{  \sigma^2  } { 1 + \phi^2  -  2 \phi \frac{e^{i\lambda} +  e^{-i\lambda} }{2}  }     \\
= \displaystyle    \frac{1}{2\pi}  \frac{  \sigma^2  } { 1 + \phi^2  -  2 \phi \cos(\lambda ) }     \\

となる。

参照参考

統計学実践ワークブック 第17章 回帰診断法

学習のまとめと例題のデータを使ってRで回帰診断図を出してみました。

学習のまとめ

回帰診断を使う理由

線形回帰モデルは、

  • 外れ値がある場合
  • 誤差項の
    • 独立性が満たされない場合
    • 等分散性が満たされない場合
    • 正規性の仮定が満たされない場合

について、最小二乗法による予測の結果には誤解を生じさせる可能性がある。これらを判断するために回帰診断(regression diagnostics)を行う。

どんな手法を用いて診断するのか

調べたいこと 手法
外れ値 残差プロット、てこ比、Cookの距離
独立性 残差プロット、自己相関、DW比
等分散性 残差プロット、標準化残差の絶対値の平方根プロット*1
正規性 残差プロット、正規Q-Qプロット

回帰診断図

例1の回帰診断図

  • 47都道府県の乗用車所有率に関する回帰診断図 f:id:axjack:20220416203805p:plain

解説・説明についてはワークブックを参照。図に現れる赤い線は図中の点に対するLOESS(LOWESS?)、局所回帰らしい。点たちの大まかな傾向を読み取ることができる。

問17.1の回帰診断図

  • 44都道府県の乗用車所有率に関する回帰診断図 f:id:axjack:20220416203936p:plain

データの取得

さて図の出典を見ると、

  • 都道府県・市区町村のすがた(社会・人口統計体系) 2017年度
  • 都道府県別・車種別自動車保有台数(軽自動車含む) 令和元年8月末現在

と書かれている。ググればわかるのだが、データを探すのも加工するのも大変面倒である。細かい注意点を備忘録がてら記載しておく。

  • 「車種別自動車保有台数(軽自動車含む)」については、最新の月末データもしくは各年度の年度末のデータにしかオンラインではアクセスできないっぽいので、ワークブックと完全同一のデータを用いることはおそらく不可能と思われる。先駆者の記事『統計検定準1級対応統計学実践ワークブック』をR, Pythonで解く~第17章回帰診断法~ - Qiitaでは令和二年2月現在のデータを用いたと記載あり。
  • 各変数の単位について言及すると、
    • 乗用車台数の単位は[台]を用いる
    • 人口は[人]単位であって、[万人]単位ではない
      • データ元では[万人]単位だったりするので、変換を忘れずに
    • 可住地面積は[ヘクタール]単位であって、[平方キロメートル]単位ではない
      • データ元では[平方キロメートル]単位だったりするので、変換を忘れずに
  • 先駆者の記事では『フォーマットが複雑なので手作業で準備した』と書いてある通り、フォーマットが複雑(といっても、集計値をExcelにベタ貼りした人間にはやさしく機械が読み取るにはちょっと面倒なレベル)。Excel的な表計算ソフトがあるならそちらを使って手作業で加工するのが断然良い。
    • ただし、データラングリング・前処理の練習としては全てRで加工する・全てPythonで加工するのも良いと思う
  • 車種別自動車保有台数(軽自動車含む)は都道府県単位での集計値ではなく、地方運輸局x支局 + 沖縄 という単位での集計値となっている
    • 北海道と沖縄の取り扱いに注意。いわゆるcase式やdecode式を用いて都道府県の列を派生させる必要がある

今回利用したデータを自分が二次加工して作ったデータ、をgistに載っけておきます。

gist.github.com

ソースコード

  • 前提:各データはURLへアクセスの上、Excelファイルをローカルに落とすこと
library(tidyverse)
library(readxl)

# 都道府県・市区町村のすがた(社会・人口統計体系)
# データセット情報
# 社会・人口統計体系 / 統計でみる都道府県のすがた2019 / 社会生活統計指標
# https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00200502&tstat=000001124677&cycle=0&tclass1=000001124955&stat_infid=000031788971&tclass2val=0
# データを見ると2017年度のデータが入っているのでこれを利用する
path1 <- "/Users/axjack/Downloads/a201.xls"
dat1 <- read_xls(path1)
dat1 |> 
  slice(13:59) |> 
  select(`...8`, `...9`, `1`, `13`) |> 
  rename(
    PrefNumber = `...8`
    , PrefName = `...9`
    , Pop = `1`
    , p.density = `13`
  ) |> 
  mutate(Pop = as.numeric(Pop) * 10000 ) |> # 万人を人に変換
  mutate(p.density = as.numeric(p.density) * 0.01 ) |>  #平方キロメートルをヘクタールに変換
  mutate(PrefName = str_remove_all(PrefName,"[都府県]$")) -> dat11


# 都道府県別・車種別自動車保有台数
# 平成31年(2019年)
# https://www.airia.or.jp/publish/statistics/number.html
path2 <- "/Users/axjack/Downloads/r5c6pv000000mdpm.xlsx"
dat2 <- read_xlsx(path2)
dat2 |> select(1:3) |> slice(-(1:3)) -> dat21
names(dat21) <- paste0('col',1:3)
dat21 |> 
  mutate(col1 = str_remove_all(col1,'\\s')) |> 
  mutate(col2 = str_remove_all(col2,'\\s')) |> 
  replace_na(list(col1 = '',col2 = '')) |> 
  filter(col2 != '計') |> filter(col1 != '合計') |> 
  mutate(PrefName = case_when(
    col2 %in% c('札幌','函館','旭川','室蘭','釧路','帯広','北見') ~ '北海道',
    col1 == '沖縄' ~ '沖縄',
    TRUE ~ col2
  )) |> 
  mutate(col3 = as.numeric(col3)) |> 
  group_by(PrefName) |> summarise(NumCar = sum(col3) ) -> dat22


# 結合
dat22 |> left_join(dat11) |> mutate(c.ratio = NumCar/Pop ) |> 
  select(PrefNumber, PrefName, Pop, NumCar, p.density, c.ratio) |>
  arrange(PrefNumber) -> dat

#write_csv(dat,"tjw_ch17_dat.csv")
#dat <- read_csv("https://gist.githubusercontent.com/axjack/84505a444f76436229f456fe915e44ff/raw/a8f41565a2986f7eedb9c1c9ead70ace388b7492/tjw_ch17_dat.csv")


# 重回帰分析
## 47都道府県の場合
dat.lm <- lm(c.ratio ~ sqrt(p.density), dat)
summary(dat.lm)

par(mfrow = c(2,2))
plot(dat.lm)


# 44都道府県の場合
## 東京・大阪・神奈川を抜く
dat |> filter( !(PrefName %in% c('東京','大阪','神奈川')) ) -> dat.44
dat.44.lm <- lm(c.ratio ~ sqrt(p.density), dat.44)
summary(dat.44.lm)

par(mfrow = c(2,2))
plot(dat.44.lm)

こちらも参考に

*1:  \sqrt{ \mid \mathrm{Standardized \ residuals} \mid }

統計学実践ワークブック 第16章 重回帰分析 問16.2を通じて・重回帰分析のスクラッチ実装

重回帰分析は重要と聞くので、念入りに勉強した記録です。

問16.2

問題[1]の要約

モデル2: Ozone = \beta_0 + \beta_1Solar.R + \beta_2Wind + \beta_3Temp + \beta_4Month + \beta_5Day +  \varepsilon に対して重回帰分析を実施し、変数Dayに対する回帰係数の

  • 最小二乗推定量
  • t統計量

を求め、有意性を論じよ。

解答

実際に重回帰分析を実行すると、

# Coefficients:
#   Estimate Std. Error t value Pr(>|t|)    
#Day           0.27388    0.22967   1.192  0.23576    

を得る。

従って、

  • 変数Dayに対する回帰係数はEstimate列から0.27388
  • t統計量はt value列から1.192
    • 問題文ではEstimateとStd.Errorしか提示されていないが、t value = Estimate÷Std.Error より 0.27388÷0.22967=1.192494を得る
  • p-値はPr(>|t|)列から0.23576である
    • 問題文ではp-値は提示されていないので付表2. t分布のパーセント点から判断してみると、
    • 自由度120で両側10%点が1.658、自由度120で両側20%点が1.289なのでp-値は20%よりも大きいことが推測できる
    • このことから、両側10%でも20%でも有意ではないと言える

問題文のデータセットを使ってRで重回帰分析してみる

airqualityのデータはRに元から入っているデータセットなので重回帰分析してみる。

データ取得

airqualityをsummaryで見るとNAを含む行がいるのでomitする。

summary(airquality)

# NAのある行は除外する
air <- na.omit(airquality)

構造確認

ワークブックに従い、Ozoneを目的変数・それ以外を説明変数とする。

str(air)
> str(air)
'data.frame':   111 obs. of  6 variables:
 $ Ozone  : int  41 36 12 18 23 19 8 16 11 14 ...
 $ Solar.R: int  190 118 149 313 299 99 19 256 290 274 ...
 $ Wind   : num  7.4 8 12.6 11.5 8.6 13.8 20.1 9.7 9.2 10.9 ...
 $ Temp   : int  67 72 74 62 65 59 61 69 66 68 ...
 $ Month  : int  5 5 5 5 5 5 5 5 5 5 ...
 $ Day    : int  1 2 3 4 7 8 9 12 13 14 ...
 - attr(*, "na.action")= 'omit' Named int [1:42] 5 6 10 11 25 26 27 32 33 34 ...
  ..- attr(*, "names")= chr [1:42] "5" "6" "10" "11" ...

重回帰分析の実行

lm関数にて重回帰分析を実行する。

model <- lm(Ozone ~., air)
summary(model)
> summary(model)

Call:
lm(formula = Ozone ~ ., data = air)

Residuals:
    Min      1Q  Median      3Q     Max 
-37.014 -12.284  -3.302   8.454  95.348 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -64.11632   23.48249  -2.730  0.00742 ** 
Solar.R       0.05027    0.02342   2.147  0.03411 *  
Wind         -3.31844    0.64451  -5.149 1.23e-06 ***
Temp          1.89579    0.27389   6.922 3.66e-10 ***
Month        -3.03996    1.51346  -2.009  0.04714 *  
Day           0.27388    0.22967   1.192  0.23576    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 20.86 on 105 degrees of freedom
Multiple R-squared:  0.6249,    Adjusted R-squared:  0.6071 
F-statistic: 34.99 on 5 and 105 DF,  p-value: < 2.2e-16

ワークブックと見比べると、p.136と同じ結果が出ていることがわかる。

重回帰分析をスクラッチ実装する

せっかくワークブックで線形代数をゴリゴリ用いて重回帰分析を勉強したので、lm関数を用いずにスクラッチ実装(と言えるのか・・・?とりあえず標準的な関数だけで実装)してみる。

変数の準備

データ行列などを準備する。注意点として、


\displaystyle X = 
\begin{pmatrix}

 1 & x_{11} & \cdots & x_{1d}   \\
 1 & x_{21} & \cdots & x_{2d}   \\
\vdots &  \vdots  &   \vdots    & \vdots   \\ 
 1 & x_{n1} & \cdots & x_{nd}   \\

\end{pmatrix}
= 
\begin{pmatrix}

 1 & \mathrm{x}_1 ' \\
 1 & \mathrm{x}_2 ' \\
\vdots &  \vdots  \\
 1 & \mathrm{x}_n ' \\

\end{pmatrix}



と、Xの1列目は \vec{1}であるのでcbind関数で列をくっつけることを忘れずに。

# X: データ行列, n: 行数, k: パラメータ数
X_raw <- air[, -1]
n <- nrow(X_raw)
k <- ncol(X_raw)
X <- cbind(1, as.matrix(X_raw) )

# y: 目的変数
y <- as.numeric( air[, 1] )

例の‪逆行列

 (X^{T}X)^{-1}  を求めておく。逆行列はsolve関数で求める。

# (X^{T}X)^{-1} 
XtXinv <- solve(t(X) %*% X)

各係数を求める

残差の標準誤差

残差の標準誤差は、


s = \sqrt{ \dfrac{ \| e \|^2 }{n-d-1} }  = \sqrt{ \dfrac{ \| y - X\hat{\beta} \|^2 }{n-d-1} } =  \sqrt{ \dfrac{ \| y - X(X^{T}X)^{-1}X^{T}y  \|^2 }{n-d-1} }

を用いて計算する。なお、mean関数だとn個足してnで割ってしまっているので、nを掛けて自由度n-k-1で割っている。

## 残差の標準誤差(Residual standard error)
s <-  sqrt( mean( (y - X %*% XtXinv %*% t(X) %*% y )^2 )*(n/(n-k-1)) )

値を確認すると、「esidual standard error: 20.86」と同じ値が得られていることがわかる。

> print(s)
[1] 20.85846
> sigma(model)
[1] 20.85846

回帰係数(Estimate)たち


\hat{\beta} = (X^{T}X)^{-1}X^{T}y

を素直に計算すれば良い。最後の転置(t())は見栄えのために使用している。

> print( XtXinv %*% t(X) %*% y |> t() )
                  Solar.R      Wind     Temp     Month       Day
[1,] -64.11632 0.05027432 -3.318444 1.895786 -3.039957 0.2738775

これはlm関数で求めた値と等しい。

> coef(model)
 (Intercept)      Solar.R         Wind         Temp        Month          Day 
-64.11632110   0.05027432  -3.31844386   1.89578642  -3.03995664   0.27387752 

標準誤差(Std. Error)たち

ワークブックp.130どおりだとうまくいかず(何故?)、こちらを見てX^{T}Xを用いてみたところ標準誤差たちが得られた。

> print( sqrt( s^2 * diag(XtXinv) ) )
              Solar.R       Wind       Temp      Month        Day 
23.4824887  0.0234186  0.6445095  0.2738869  1.5134568  0.2296708 
> coef(summary(model))[,2]
(Intercept)     Solar.R        Wind        Temp       Month         Day 
 23.4824887   0.0234186   0.6445095   0.2738869   1.5134568   0.2296708 

統計学実践ワークブック 第16章 重回帰分析 pp.125-127について、式を導出したり図示したり行間を埋めたりしました。

試験対策だけであったら、ぶっちゃけ重回帰分析した結果(回帰係数、t値、p値、決定係数)が読み解ければ良いと思われる。がしかし、ワークブックpp.125-127にある線形代数的な解釈・幾何学的な解釈の魅力といったらなんとやら。というわけで、行間を埋めた記録を記す。

speakerdeck.com

axjack is said to be an abbreviation for An eXistent JApanese Cool Klutz.