とーけい部

現在、このブログは工事中です。

統計学 統計検定 数学

ロジスティック回帰をやるときに完全分離状態っていうのに陥るときがあって、例えば以下のようなデータセット

Y <- c(1,1,1,1,0,0,0,0)
X <- c(8,7,3,1,0,-2,-1,-9)
dat <- data.frame(Y,X)
dat
> dat
  Y  X
1 1  8
2 1  7
3 1  3
4 1  1
5 0  0
6 0 -2
7 0 -1
8 0 -9

これは目的変数Yが、Xの値が0より大きければ1、0より小さければ0というような例。
具体例では、例えばXが製品の質を表している数値で、この数値が0より大きければ合格、0以下なら欠陥品として処分。みたいな感じ。

で、このような例ではXに対し0てYの生起を「確率的」に評価するのが困難になる。だって手元のデータでは「X>0なら100%の確率で合格」「X≦0なら100%で不合格」のようになってしまって、Xの値がこれくらい大きくなると、Yが1になる確率はこのくらい大きくなる、みたいな表現ができないため。

で、これを実際にRで実行するとこうなる

glm(data = dat , Y ~ X , family=binomial(link = "logit"))
> glm(data = dat , Y ~ X , family=binomial(link = "logit"))

Call:  glm(formula = Y ~ X, family = binomial(link = "logit"), data = dat)

Coefficients:
(Intercept)            X  
     -21.71        43.55  

Degrees of Freedom: 7 Total (i.e. Null);  6 Residual
Null Deviance:      11.09 
Residual Deviance: 1.402e-09    AIC: 4
 警告メッセージ: 
1:  glm.fit: アルゴリズムは収束しませんでした  
2:  glm.fit: 数値的に 0 か 1 である確率が生じました  

数値的に0か1である確率が生じましたってのは、X>0なら確率1でYが起こるっていうことかな。
まあとりあえずこんな感じでエラーが起こるわけ。

他にも、準完全分離っていう状態では、以下のようなデータ

Y <- c(1,1,1,1,0,1,0,0)
X <- c(8,7,3,1,0,0,-1,-9)
dat2 <- data.frame(Y,X)
dat2
> dat2
  Y  X
1 1  8
2 1  7
3 1  3
4 1  1
5 0  0
6 1  0
7 0 -1
8 0 -9

これは、X>0なら100%でYが1、X<0なら100%でYが0、そして境界線のX=0ではYが1になったりならなかったり。こういう状態は準完全分離と呼ばれて、やはりこれもYを確率的に評価するのが厳しくなる。

glm(data = dat2 ,Y ~ X , family = binomial(link="logit"))
> glm(data = dat2 ,Y ~ X , family = binomial(link="logit"))

Call:  glm(formula = Y ~ X, family = binomial(link = "logit"), data = dat2)

Coefficients:
(Intercept)            X  
 -3.333e-15    1.989e+01  

Degrees of Freedom: 7 Total (i.e. Null);  6 Residual
Null Deviance:      10.59 
Residual Deviance: 2.773    AIC: 6.773
 警告メッセージ: 
 glm.fit: 数値的に 0 か 1 である確率が生じました  

やはり警告が出る。まあ一応推定自体はできるけど。

でまあ、これを解決するためにFirthの方法だったりの各種補正法があるらしいんだけどそれは置いといて、以下のようなデータを見てみる。

Y <- c(1,1,1,1,0,0,0,0)
X <- c(1,1,1,1,0,0,0,0)
dat3 <- data.frame(Y,X)
dat3
> dat3
  Y X
1 1 1
2 1 1
3 1 1
4 1 1
5 0 0
6 0 0
7 0 0
8 0 0

Xがカテゴリカルで、Yもまたカテゴリカルで、かつ完全分離が起きているような状態。これはどう見ても完全分離状態だが、
Rで以下を実行すると、

glm(data = dat3 , Y ~ X , family = binomial(link="logit"))
> glm(data = dat3 , Y ~ X , family = binomial(link="logit"))

Call:  glm(formula = Y ~ X, family = binomial(link = "logit"), data = dat3)

Coefficients:
(Intercept)            X  
     -24.57        49.13  

Degrees of Freedom: 7 Total (i.e. Null);  6 Residual
Null Deviance:      11.09 
Residual Deviance: 3.429e-10    AIC: 4

警告メッセージが出てこない。……なんで???(マジで)

まあ、多分内部のアルゴリズムが上手く収束しているってことなんだろうけど、そんなことある?
警告メッセージが表示されないってことはRのglmで目的変数も説明変数も両方ともカテゴリカルであるようなロジスティック回帰をして変な推定が返ってきたとして、なんとそれに気づけないってことになる。

いやしかし、待ってほしい。以下のデータを見てみよう。

set.seed(1)
X1 <- c(rep(1,10) , rep(0,10))
X2 <- c(rep(1,15) , rep(0,5))
X3 <- c(rep(1,3) , rep(0,17))        
X4 <- c(rep(1,10) , rep(0,10))
X5 <- c(rep(1,18) , rep(0,2))
X6 <- c(rep(1,16) , rep(0,4))
#X1,X4はそこそこ出てきて、そこそこの効果
#X2は頻繁に出てきて、強めの効果
#X3はごくまれに出てきて、非常に強い効果
#X5,X6は頻繁に出てきて、弱い効果
X1 <- sample(X1 , replace = F)
X2 <- sample(X2 , replace = F)
X3 <- sample(X3 , replace = F)
X4 <- sample(X4 , replace = F)
X5 <- sample(X5 , replace = F)
X6 <- sample(X6 , replace = F)
logitP <- -2*X1 + 4*X2 + 15*X3 - 2.5*X4 + 0.2*X5 -1.2*X6
expitP <- exp(logitP)/(1+exp(logitP))
expitP
Y <- rbinom(n=20,size=1, prob=expitP)
data2 <- data.frame(Y ,X1,X2,X3,X4,X5,X6)
data2
> data2
   Y X1 X2 X3 X4 X5 X6
1  1  1  1  0  0  1  1
2  0  1  1  0  1  1  0
3  0  1  1  0  1  1  1
4  0  1  0  0  1  1  1
5  0  0  0  0  0  1  1
6  1  0  1  0  1  1  1
7  1  0  1  1  1  1  1
8  1  0  0  0  0  1  0
9  1  0  1  0  0  1  1
10 0  1  1  0  1  1  1
11 1  0  1  1  0  1  1
12 1  1  1  0  0  1  1
13 0  1  1  0  0  1  1
14 1  0  1  0  0  1  0
15 0  1  1  0  1  1  1
16 1  0  0  1  0  0  1
17 0  0  0  0  1  1  0
18 0  1  1  0  1  1  1
19 1  0  1  0  0  0  1
20 0  1  1  0  1  1  1

たとえばX3(あとX5も)に注目してみると、これは準完全分離が起きている。
これに対してロジスティック回帰を行ってもアルゴリズムが上手く推定できないと思われる。

glm(data = data2 , Y~X1+X2+X3+X4+X5+X6 , family="binomial")
> glm(data = data2 , Y~X1+X2+X3+X4+X5+X6 , family="binomial")

Call:  glm(formula = Y ~ X1 + X2 + X3 + X4 + X5 + X6, family = "binomial", 
    data = data2)

Coefficients:
(Intercept)           X1           X2           X3           X4           X5           X6  
     60.084      -81.116      101.752        2.379      -60.798      -39.962      -40.065  

Degrees of Freedom: 19 Total (i.e. Null);  13 Residual
Null Deviance:      27.73 
Residual Deviance: 3.819    AIC: 17.82
 警告メッセージ: 
 glm.fit: 数値的に 0 か 1 である確率が生じました 

あれ?警告メッセージが出てきた。
いやまあ、助かる。助かるけど、なんでさっきは警告が出てこなかったのに今度は警告が出てくるんだ???
マジで謎なんで、誰か詳しい人教えてください。

おまけ Firthの補正

せっかくなんでやっとこう。
Firthの補正は罰則項にフィッシャー情報量を利用した罰則付き最尤法になってるけど、まあ理論的なとこは各自で調べてください。

切片なしでまずやる。

#Firthの方法を用いた罰則つき最尤法を行う
install.packages("logistf")
library("logistf")
s <- logistf(data = data2 , Y ~0+X1+X2+X3+X4+X5+X6 , firth = T)
s
#切片なしなら一応上手く推定できた。
> s
logistf(formula = Y ~ 0 + X1 + X2 + X3 + X4 + X5 + X6, data = data2, 
    firth = T)
Model fitted by Penalized ML
Confidence intervals and p-values by Profile Likelihood 

Coefficients:
        X1         X2         X3         X4         X5         X6 
-3.2825732  4.2851815  2.3987510 -3.0169298  0.9003723 -1.5259974 

Likelihood ratio test=13.32006 on 6 df, p=0.0382258, n=20

まあよくわらんがとりあえずエラーもなく一応最尤推定値が出てきた。(まあ厳密にいえばこれは最尤推定値ではなく罰則付き最尤推定とでも呼ぶべきものだけど)

一応、識別率をチェックしてみる。

(predict(s)>0) == data2$Y #20個中1個だけ誤判別。
> (predict(s)>0) == data2$Y #20個中1個だけ誤判別。
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
[19]  TRUE  TRUE

20個中1個だけ誤判別とのこと。

ま、切片なしなら上手くいった。しかし切片ありで推定すると……

logistf(data = data2 , Y ~X1+X2+X3+X4+X5+X6 , firth = T)
#切片ありだと警告が出る。色々調整しなきゃらしいので調整する。
> logistf(data = data2 , Y ~X1+X2+X3+X4+X5+X6 , firth = T)
logistf(formula = Y ~ X1 + X2 + X3 + X4 + X5 + X6, data = data2, 
    firth = T)
Model fitted by Penalized ML
Confidence intervals and p-values by Profile Likelihood 

Coefficients:
(Intercept)          X1          X2          X3          X4          X5          X6 
  0.2255353  -2.5385945   3.1778146   1.7764449  -2.6034431   0.6743863  -1.2892589 

Likelihood ratio test=12.38409 on 6 df, p=0.05392869, n=20

 警告メッセージ: 
1:  logistf(data = data2, Y ~ X1 + X2 + X3 + X4 + X5 + X6, firth = T) で: 
  Maximum number of iterations exceeded. Try to increase the number of iterations or alter step size by passing 'logistf.control(maxit=..., maxstep=...)' to parameter control
2:  logistf(data = data2, Y ~ X1 + X2 + X3 + X4 + X5 + X6, firth = T) で: 
  Nonconverged PL confidence limits: maximum number of iterations for variables: X6 exceeded. Try to increase the number of iterations by passing 'logistpl.control(maxit=...)' to parameter plcontrol
3:  logistf(data = data2, Y ~ X1 + X2 + X3 + X4 + X5 + X6, firth = T) で: 
  Maximum number of iterations for variables: (Intercept), X1, X2, X3, X5, X6 exceeded. P-value may be incorrect. Try to increase the number of iterations by passing 'logistf.control(maxit=...)' to parameter control

なんかうるさいのがいっぱい出てきた。
どうやらイテレーションを増やせ、maxstepを増やせ、とのこと。PLってのはプロファイル尤度。信頼区間がどうのこうの言われてしまった。(ちなみにプロファイル尤度っていうのはパラメータが多次元の場合に、注目しているパラメータについて固定し、それ以外の余分なパラメータについて最大化した尤度のこと。特定のパラメータの方向から尤度関数の"輪郭(profile)"を見たときに、その輪郭っていうのはその他の余り物のパラメータについて最大化した値になってることから名づけられてる。わかりやすくて良いネーミングだと思う。逸脱度統計量(deviance statistic)ってのがカイ二乗分布に漸近的に従うからこれを利用していろいろできる。ネットに上がってるスライドだとhttps://www.researchgate.net/publication/341702223_purofairuyouduxinlaiqujian_Profile_likelihood_confidence_interval_yitengyaoer_muyaotanhuahui_2019nian3yue14riとかみたらわかりやすいかもしれん。尤度比検定とか勉強したことある人なら「あ~あれね」ってなるかも)

logistf()関数には引数としてcontrol と plcontrol があるので、ここをいじってまあとりあえず適当にイテレーションを増やしてみる。

#切片ありだと警告が出る。色々調整しなきゃらしいので調整する。
cont <- logistf.control(maxit=1000,maxstep = 100)
plcont <- logistpl.control(maxit=1000)
ss <- logistf(data=data2 ,  Y ~X1+X2+X3+X4+X5+X6 , firth = T , control = cont,plcontrol = plcont)
ss
> ss
logistf(formula = Y ~ X1 + X2 + X3 + X4 + X5 + X6, data = data2, 
    control = cont, plcontrol = plcont, firth = T)
Model fitted by Penalized ML
Confidence intervals and p-values by Profile Likelihood 

Coefficients:
(Intercept)          X1          X2          X3          X4          X5          X6 
  0.2235775  -2.5389918   3.1783897   1.7748356  -2.6033374   0.6761207  -1.2892522 

Likelihood ratio test=12.3841 on 6 df, p=0.05392857, n=20

警告が消えた。ただまあ、さっきの場合の推定値とほとんど変わらない。

せっかくなので信頼区間も見てみる

ss$ci.lower
ss$ci.upper
> ss$ci.lower
(Intercept)          X1          X2          X3          X4          X5          X6 
 -8.5842939 -10.0082939  -0.2387445  -5.1621690  -8.8773211  -8.7860762  -6.6975334 
> ss$ci.upper
(Intercept)          X1          X2          X3          X4          X5          X6 
10.11215546  0.25278118 14.07936182 14.74288884 -0.05546432 10.02277278  2.32220824 

X5は有意に負の効果を持つと推定されている。ちなみに真の構造ではX5はYの生起に対して非常に弱い正の影響を及ぼす。
……逆じゃねーか!(おわり) 追記:見間違えてました。X4が有意に負の効果を持つと推定されてます!真の構造でも確かに負です!よかった~

線形モデルと回帰診断図

修正:2020/12/01 標準化残差の式が間違っていた(いやまあそういう定義もあるんだけど、R内での定義とは異なっていたことに気づかんかった)ので修正しました。申し訳ないです。

外れ値を含むデータ

以下の仮想データを見てみましょう

set.seed(1)
X <- c( rnorm(n = 10 ,mean = 0 , sd = 1) , 5 , 0.5)
Y <- 3*X + rnorm(n = 12 , mean = 0 , sd = 2)
Y[12] <- Y[12] + 20
plot(X , Y , xlim = c(-2 , 7) , ylim = c(-4 , 26) , col = ifelse(Y<10 , "black" , "red") , pch = 16 , cex =1, main = "仮想データ1")

f:id:hasegawa-yuta289:20201115024731p:plain

これは、以下のデータ

DATA <- data.frame(X,Y)
DATA
##             X          Y
## 1  -0.6264538  1.1442009
## 2   0.1836433  1.3306164
## 3  -0.8356286 -3.7493670
## 4   1.5952808  0.3564426
## 5   0.3295078  3.2383852
## 6  -0.8204684 -2.5512724
## 7   0.4874291  1.4299066
## 8   0.7383247  4.1026465
## 9   0.5757814  3.3697864
## 10 -0.3053884  0.2716375
## 11  5.0000000 16.8379547
## 12  0.5000000 23.0642726

の散布図になっています。
まあパッと見てわかるのは、このデータは線形に分布しているみたいだな~ってことですね。
しかし、明らかにデータの11番目の観察と12番目の観察は、データ全体からみると外れた値、外れ値のように見えます。

この二つのデータ点(赤点で示しました)は、果たして適切なんだろうか、
もしかしたら、データの打ち間違えか何かなんじゃないのか……というのが、今回のテーマになります。

とりあえず線形モデルを当てはめてみよう

上記の仮想データについてとりあえず線形モデルで単回帰してみましょう。
つまり、以下

\displaystyle{
\large
\begin{eqnarray}
y_i &=& \beta_0 + \beta_1 x_i + \epsilon_i \\
\epsilon_i &\overset{iid}\sim& N(0 , \sigma^2)\\
(i &=& 1,2,\cdots , 12)
\end{eqnarray}
}

というモデルを考えて、このパラメータ\displaystyle{
\beta _ 0 , \beta _ 1
}を最小二乗法で推定してみます。

このモデルでは、以下の仮定を置いていることに注意してください。

1.各観察iは、互いに独立である(言い換えれば、各誤差\displaystyle{
\epsilon _ i
}は独立である)
2.各誤差iは、期待値が0(\displaystyle{
E(\epsilon _ i) = 0
})であり、かつ分散が等しい(\displaystyle{
V(\epsilon _ i) = \sigma^ 2
})
3.各観察iは、正規分布している(言い換えれば、各誤差\displaystyle{
\epsilon _ i
}正規分布に従う)

実際の推定は、Rでlm()関数を使うだけで簡単に終わります。

LM <- lm(data = DATA , Y ~ X)
LM
## 
## Call:
## lm(formula = Y ~ X, data = DATA)
## 
## Coefficients:
## (Intercept)            X  
##       2.389        2.957

この線形モデルの切片は2.389、傾きは2.957と推定されました。

実際のデータに推定された線形モデルを図示してみましょう。

plot(DATA , xlim = c(-2 , 7) , ylim = c(-4 , 26) , col = ifelse(Y<10 , "black" , "red") , pch = 16 , cex =1 , main = "仮想データ1")
abline(LM)

f:id:hasegawa-yuta289:20201115024755p:plain

う~ん、なんかあんまり上手くフィットしてないように見えますね。
観察1~10(黒点)よりも上の方を回帰直線が通過してますね。
あれ? でも、11番目の観察(右上の赤点)にはよく当てはまっているように見えます。
回帰直線よりもだいぶ上側に位置している12番目の観察にはもう全然フィットしてませんね。

まあこの例の場合はさすがにあからさま過ぎるんで言っちゃいますが、これはデータの12番目の観察に引っ張られることで推定された回帰式が上に引っ張られてしまい、うまくデータにフィットしなくなってしまったわけです。

では、この12番目のデータ点は、果たして異常値として排除してしまって良いのでしょうか?
この判断を、散布図をパッと見て「よし、これがおかしいから外そう!」でやってるんじゃ困りますよね。
人によっては「いやいや、この点ってそんなにおかしいかな?」とか言い出しそうです。
そのような相手に対して、「よし、どう見てもおかしいから排除!」というやり方では、この12番目の観察が異常値として排除するに足るだけの十分な理由を説明できません。

そこで登場するのが回帰診断です。
回帰診断とはデータに対してフィットさせた回帰モデルが、実際どれくらい手元のデータによく当てはまっているのか、どこかおかしい点はないのかなどを調べる方法です。
(どちらかというと、データそのものが、フィットさせた回帰モデルにどれくらい当てはまっているのか、前提をきちんと満たしていそうかどうか、のチェックする方法という呼び方の方が正しいかも)

LMに対する回帰診断

まあ一口に回帰診断とか言っても色々あるんで詳しく知りたい人は別途調べてほしいんですが、今回はRにplot(LM)と打ち込むことで(LMはlm()関数の出力)表示される4枚の回帰診断図について説明していきます。

plot(LM)

f:id:hasegawa-yuta289:20201115024823p:plain

f:id:hasegawa-yuta289:20201115024834p:plain

f:id:hasegawa-yuta289:20201115024847p:plain

f:id:hasegawa-yuta289:20201115024900p:plain

なんか色々出てきました。
一つずつ見ていきましょう。

残差vs当てはめ値

f:id:hasegawa-yuta289:20201115024823p:plain

Residualsってのは残差ですね。
fittedってのは当てはめ値のことです。ちなみに当てはめ値\displaystyle{
\hat{y}
}のことを推定値と呼ぶこともありますが、yという値そのものは単に観測された値でしかない(真の値を知ることができないパラメータなどとは違って、真の値はすでにそこに"ある"ものである)ので、まあ個人的には推定値という呼び方は良くないのかなとか思います(まあyhatのことを期待値μの推定としてとらえるなら推定値って呼び方もできるんで、まあどっちでもいいが)

\displaystyle{
残差_i = 実測値_i - 当てはめ値_i\\
つまり、y_i - \hat{y}_iのこと
}
oldpar <- par(no.readonly = TRUE)
par(mfrow=c(2,1));par(oma=c(0,0,0,0));par(mar=c(4,4,1.5,1))

plot(DATA , xlim = c(-2 , 7) , ylim = c(-4 , 26) , col = ifelse(Y<10 , "black" , "red") , pch = 16 , cex =1 , main = "仮想データ1")
text(c("11" , "12") , x = c(5 , 0.5) , y = c(19 , 25))
abline(LM)
plot(LM,1)
par(oldpar)

f:id:hasegawa-yuta289:20201115025020p:plain

この図はまあ、fittedに対して残差がどのくらいか見てるわけですね。
LMにおける仮定では全ての誤差は独立同一にとある正規分布に従うとしていましたので、
この図で見て当てはめ値に対して残差が系統的に変化するようでしたら、そもそもこの1次式による線形モデルを利用すること自体をちょっとやめた方がいいんじゃないの?ということになります。

たとえば以下のような仮想データに対する例を見てみれば明らかでしょう。

set.seed(1)
X2 <- rnorm(n = 10 , mean = 0 , sd = 3)
Y2 <- X2^2 + rnorm(n=10 , mean = 0 , sd = 1)
DATA2 <- data.frame(X2 , Y2)
oldpar <- par(no.readonly = TRUE)
par(mfrow=c(2,1));par(oma=c(0,0,0,0));par(mar=c(4,4,1.5,1))
plot(DATA2 , main = "仮想データ2")
curve(add=T , x^2 , xlim = c(-3 , 6) , col = "blue")
LM2 <- lm(data = DATA2 , Y2 ~ X2)
abline(LM2)
plot(LM2 , 1)
par(oldpar)

f:id:hasegawa-yuta289:20201115025047p:plain

実際のデータ点が当てはめ値(線形式)よりも上に位置していれば、残差は正。
実際のデータ点が当てはめ値(線形式)よりも下に位置していれば、残差は負。

この仮想データでは、データが中心から離れれば離れるほど残差が正に大きくなっていく傾向が見て取れ、逆にデータが中心に近づけば近づくほど残差が負に大きくなっていく傾向がありますね。

このように、残差に傾向が存在するかしないか?を残差vs当てはめ値プロットでは確認できます。
この図で残差に何かしらの傾向が存在するならば、線形モデルの仮定である「誤差分布の独立同一性」が非常に怪しいですよね。
まあ、このような使い方をします。

正規QQプロット

QQプロットって知ってますかね?知ってるならこの項目は飛ばして良いです。

QQプロットとは、ざっくり言うと「確率変数Aの分布」と、「確率変数Bの分布」がどれくらい違うのかをチェックする方法です。

具体的には、確率変数Aの標本から求めた分位点と、Bの標本から求めた分位点とを、各々対応している分位どうしでプロットしていきます。(まあ要するに分位点の散布図がQQプロットになります)
二つの分布が等しいなら、各分位点は、(当たり前ですが)同じ値になりますよね?
なので、二つの分布が等しいならQQプロットは理論上は完全な45度線(y=x上の点)をとります。実際のデータにはばらつきがあるため、二つの分布が等しいならおおむね直線を描きます。

set.seed(1)
A <- rnorm(n=10000)
B <- rnorm(n=10000)
qqplot(A,B , cex = 0.5 , main = "QQプロット")
abline(0,1 , col="red" , lwd = 2)

f:id:hasegawa-yuta289:20201115025115p:plain

正規QQプロットとは、このQQプロットを利用して、「片方は正規分布」と仮定し、もう片方は実際のデータを利用することで、理論上の正規分布の分位点の値からどれだけずれているのかをチェックします。

ある確率変数Zがあったとします。

set.seed(1)
Z <- rt(n = 60 , df = 3 )
hist(Z , main = "Z" , xlab = "Z")

f:id:hasegawa-yuta289:20201115025139p:plain

う~ん、このZは正規分布してるんですかね?
正規QQプロットでチェックしてみます。

qqnorm(Z)
abline(0,1)

f:id:hasegawa-yuta289:20201115025205p:plain

あらあら、中心部はともかく、端っこの方は随分と直線関係から外れてしまいました。
これはZが実際には正規分布ではなくt分布(自由度3)に従っていることによります。

正規分布N(20,100)に従う確率変数Vを考えてみましょう。

set.seed(1)
V <- rnorm(n=1000 , mean = 20 , sd = 10)
qqnorm(V)

f:id:hasegawa-yuta289:20201115025222p:plain

正規QQプロットでチェックするのは標準正規分布との当てはまりなので、今回これは45度線にはなっていませんが(縦軸と横軸の縮尺に注意!)、正規分布は位置パラメータ(平均)と尺度パラメータ(分散)しかもたないので、分布の形自体は変わらないために直線形状にはなってくれます。正規分布に対してQQプロットが上手くいく理由がわかりますね。
ちなみに縦軸の単位が大きいのは、確率変数Vの分散が標準正規分布(横軸)と比べて大きいからです。

最後に、ガンマ分布Ga(2,5)に従う確率変数Dと、ガンマ分布Ga(6,8)に従う確率変数Eを考えてみましょう。
Ga分布の最初のパラメータは形状パラメータとよばれ、この値が変わると分布の形状が大きく変化してしまいます。

curve(dgamma(x , shape = 2 , scale = 5) , xlim = c(0 , 100) , col = "red" , main = "ガンマ分布")
curve(dgamma(x , shape = 6 , scale = 8) , xlim = c(0 , 100) , col = "blue" , add = T)
legend("topright" , legend = c("形状パラメータ=2","形状パラメータ=6") , col = c("red" , "blue") , lty = 1 , cex = 1.5 )

f:id:hasegawa-yuta289:20201115025242p:plain

DとEを1000個発生させて、QQプロットを見ましょう。

set.seed(1)
D <- rgamma(n = 1000 , shape = 2 , scale = 5)
E <- rgamma(n = 1000 , shape = 6 , scale = 8)
qqplot(D,E,main="QQプロット")

f:id:hasegawa-yuta289:20201115025255p:plain

これは直線関係にはなってないですよね。
QQプロットは一応どのような分布にも適用できますが、ガンマ分布のようにパラメータによってそもそも形状が変わってしまうような分布について適用しても、(形状パラメータが一致していない限り)あまり意味がなさそうですね。

ちなみに、形状パラメータを合わせてみると以下のようになります(Ga(2,4)とGa(2,8)の比較)。

set.seed(1)
D <- rgamma(n = 1000 , shape = 2 , scale = 4)
E <- rgamma(n = 1000 , shape = 2 , scale = 8)
qqplot(D,E,main="QQプロット")

f:id:hasegawa-yuta289:20201115025312p:plain

まあ~おおむね直線関係になりました。

先ほどのLMの回帰診断図のQQプロットに戻ってみましょう。

plot(LM,2)

f:id:hasegawa-yuta289:20201115025331p:plain

縦軸を見ればわかりますが、これは横軸の理論上の正規分布に対して、縦軸を残差としています。
正規分布に対する独立同一性の仮定が正しければ、残差は(おおむね)正規分布するのでこれは直線を描くはずですね。実際ほぼ直線を描いていますが、やはり観察12だけはおかしな値になっています。こいつだけ正規分布に従っていなさそう、と考えられます。

標準化残差のプロット

standardized residualっていうのは文字通り標準化残差です。

標準化っていうのは標準正規分布を考えてもらえばわかると思います。N(5,100)に従うような確率変数Xに対して、これを標準化したものは(X-5)/√100 ですが、これは標準正規分布に従いますよね。

標準化残差というのは、残差を標準化したものになります。具体的には以下の計算式によって求めた残差の変換値のことを言います。

\displaystyle{
\Large{
線形モデル\ y = X\beta + \epsilon\ に対して、\\
標準化残差_i = \frac{残差_i}{\sqrt{\hat{\sigma}^2 (1-h_{ii})}}    \\
ただし、\hat{\sigma}^2 = \frac{\sum_i( y_i - \hat{y_i})^2}{n-rankX}であり、\\
h_{ii}はi番目の観察のてこ比である
}
}

この式の\displaystyle{
\hat{\sigma}^ 2
}は、誤差\displaystyle{
\epsilon
}の分散の不偏推定量になってます。
なんで?て思った人は、まあ例えば『自然科学の統計学』の2章とか読めば載ってるんで読んでみてください。
てこ比については次の節で紹介しているので、ここではまあ雰囲気で流してください。

なお、この値のことを標準化残差ではなくスチューデント化残差と呼ぶこともあります。その場合、このスチューデント化残差はインターナルなスチューデント化残差(internally studentized residual)とよばれます。Rで標準化残差を算出するための関数rstandard(LM)は上の標準化残差、もしくはインターナルなスチューデント化残差を計算しています。ちなみに、エクスターナルなスチューデント化残差(あるいは、単にスチューデント化残差)はRの関数rstudent(LM)によって計算できます。参考:Studentized residual

正規分布というものは大体の値が3σ範囲内に入るので、この標準化残差が3を超えているような値は何かおかしいんじゃねえの~?ということが言えるわけです。
(正規分布の仮定が正しければ標準化残差は漸近的に標準正規分布に従うので)

もう一度LMの回帰診断図(標準化残差プロット)を見てみましょう。

plot(LM,3)

f:id:hasegawa-yuta289:20201115025429p:plain

理由はよくわかりませんが、標準化残差の絶対値のルートを縦軸に取ってますね。横軸は当てはめ値です。
√3=1.73205ぐらいらしいので、まあ1.5を超えているような場合には要注意でしょう。これを見るとやはり観察12はおかしな値をとっているように見えます。

てこ比プロットとクックの距離

最後の図はてこ比プロットです。もう一度見てみましょう。

plot(LM,5)

f:id:hasegawa-yuta289:20201115025453p:plain

まあ縦軸は良いですよね。これは標準化残差です。
横軸のLeverage(レバレッジ:てこ比)とは何でしょうか?

レバレッジについて説明する前に、まず思い出してほしいのですが、最小二乗推定量というのはyの線形推定量、つまりyの各々の要素を線形結合したような推定量になってました。(知らなかった人は豆知識として覚えておくとお得です)

めんどくさいので行列表現してしまいますが、以下のようになっています。

\displaystyle{
線形モデル\ y = X\beta + \epsilon に対して、\\
最小二乗推定量\hat{\beta}は、以下の正規方程式\\
X'X\beta = X'y\\
の解であるから、Xが正則とすれば、\\
\hat{\beta} = (X'X)^{-1}X'y\ より、\\
当てはめ値\ \hat{y} = X\hat{\beta}=X(X'X)^{-1}X'y\\
したがって、\hat{y}の各要素は、\\yの各々の要素の線形結合になっている。
}

ということは、yのk番目の観察の当てはめ値は、以下のように表現できますよね。

\displaystyle{
\Large
\hat{y_k} = h_{k1}y_1+h_{k2}y_2+\cdots+h_{kk}y_k+\cdots+h_{kn}y_n
}

これについて、てこ比とは以下のように定義します。

\displaystyle{
\Large
k番目の観察のてこ比とは、h_{kk}のことである
}

このてこ比(レバレッジ)が横軸の値になっているわけですね。観察11のレバレッジが0.8程度と、他と比べて格段に高いのがてこ比プロットから見て取れます。

てこ比の定義を見ればわかりますが、
てこ比が高いということは、その値がその値自身を説明する能力が高いということになります。
したがって、てこ比が高ければ高いほど、その観察の当てはめ値はデータ全体について、その観察以外の値に対してあまり影響を受けないということになります。
散布図を思い出してみましょう。

plot(DATA , xlim = c(-2 , 7) , ylim = c(-4 , 26) , col = ifelse(Y<10 , "black" , "red") , pch = 16 , cex =1 , main = "仮想データ1")
abline(LM)

f:id:hasegawa-yuta289:20201115025522p:plain

黒点(レバレッジは0~0.2程度)については回帰直線の当てはまりが良くありませんが、右上の赤点(観察11)にはよく当てはまっているように見えます。これは観察11のレバレッジが0.8程度と非常に高い値を取っているからです。

先ほどの説明の通り、レバレッジが高い観察に対しては推定されたモデルの当てはまりが良いので、残差が(標準化残差が)低くなる傾向にあります。
このことを逆手に取ると、同じ標準化残差をもっているとしても、レバレッジの値が高ければその残差が持つ意味は大きいということがわかります。てこ比が高いにも関わらずその観察の標準化残差が高ければ、その値は非常に「おかしい」値ということになります。

ところで、てこ比プロットにて赤い点線はCook's distance(クックの距離)と書いてありますが、これはなんでしょうか?

クックの距離について説明していきます。
簡単に言えば、「観察kのクックの距離」とは、「観察kを引っこ抜いたデータから推定されたあてはめ値たちと、実際の当てはめ値たちとの距離」になります。
クックの距離が高いほど、その観察がモデル推定に対して与えている影響が絶大である、ということになりますね。
まあ詳しくはね、Wikipediaとかあるんでね、読むとね、良い可能性が無きにしもあらずCook's distance

てこ比プロットを見れば、レバレッジが高いほど、小さな標準化残差に対してクックの距離が大きくなっていくことがわかります。まあ、そりゃそうだろうねという感じがします。

実際に計算してみましょう。観察12のクックの距離は0.5より低いくらいとのことなので、観察12を引っこ抜いて線形モデルを推定し、本当にそうなのかチェックしてみます。

DATA3 <- DATA[-12,]           #観察12を抹消する
LM3 <- lm(data = DATA3 , Y~X)
X12.pred.LM <- fitted(LM)  #観察12を含むデータからのあてはめ値
X12.pred.LM3 <- predict(LM3 , newdata = data.frame(X = DATA$X)) #観察12を除くデータからのあてはめ値
sigma2hat <- sum(resid(LM)^2)/(12-2)
sum((X12.pred.LM - X12.pred.LM3)^2) / (2 * sigma2hat)
## [1] 0.4117405

クックの距離は0.41ぐらいとわかりました。

ちなみに、plot(LM)では出てこない図ですが、plot(LM , 4)と打ち込めばもっとわかりやすくクックの距離を出してくれます。

plot(LM , 4)

f:id:hasegawa-yuta289:20201115025546p:plain

まあ露骨に観察12のクックの距離が大きいですね。
この値があまりに大きいと、その値がモデル推定に対して与えている影響が大き過ぎるということなので、その値が本当に分析に含めるべきまっとうなデータなのか?があやしくなります。

なお、Rでクックの距離を計算したければcooks.distance(LM)という関数があるのでそれを使えば一発です。

観察12はおかしいよね

というわけで、今までの回帰診断図を見る限り、まあ観察12はおかしい値に思えますね。逆に、外れ値っぽい観察11は、それほどおかしな値ではありませんでした。

観察12を異常値として排除し、回帰直線を引いてみましょう。

plot(DATA , xlim = c(-2 , 7) , ylim = c(-4 , 26) , col = ifelse(Y<10 , "black" , "red") , pch = 16 , cex =1 , main = "仮想データ1")
abline(LM3)

f:id:hasegawa-yuta289:20201115025558p:plain

当てはまりが直感的にも良くなりました。やったぜ。(おわり)

参考文献

買いましょう

これだけ読めばOK

多変量解析の本だけどてこ比や標準化残差について載ってる

分散の不偏推定量~の下りがわからなかったり、そもそも行列を使って表現した線形モデルについて詳しくない人はこれ読むと良いかも

そもそも行列?線形代数?なにそれわかんね~~~~って人は(高校数学わかるなら)これとかおすすめかも、ジョルダン標準形とかあんま使わないから最後まで読まんで良いかもしれん

Rを使った社会科学系の実践的なデータ分析がやってみたい・実データを通してRのコードの書き方を学びたい人はこれ読むと良いかも。日本語訳がかなり微妙なので英語得意なら原著の方が良いかも

あと僕はまだ読んだことないんだけど、回帰診断に特化した書籍だとこんなのがあったり

ベータ分布の直感的解釈

ベータ分布の解釈

いろんな分布がありますよね、例えば二項分布やポアソン分布は成功回数の散らばりを表しているし、指数分布や幾何分布やガンマ分布やら負の二項分布やらは待ち時間を表しているし、正規分布なら微小な変動の総和の振舞いを表している(中心極限定理)などなど……まあ、数学的な意味だけじゃなくて、その分布を現実に対応させた解釈を与えることができるわけです。

ベータ分布←こいつなに?????????????

なんなんですかね、こいつ。
ちょっと考えていきましょう。

\displaystyle{
\Large{
ベータ分布に従う確率変数\theta \\
\theta \sim Be(\alpha ,\beta)\\
の密度関数は、以下の通り\\
p(\theta | \alpha , \beta ) = \frac{\theta^{\,\alpha -1} (1-\theta) ^{\beta -1}}{B(\alpha , \beta)}\quad ここで \theta \in (0,1)\\
ただしB(\alpha ,\beta)はベータ関数
}
}

まあ~密度関数の形を見ると二項分布っぽい形をしてますよね。
今回は二項分布と絡めて、ベータ分布の直感的な意味を考えていきます。ベイズの定理を使います。

まず図示してみましょう。
パラメータを1~20まで動かすとこんな感じになります。

curve(sin,lty=0,from=0,to=1,ylim=c(0,6),xlab=expression(paste(theta)),ylab="確率密度",main="ベータ分布 (パラメータは2つとも同じ値)")
for( i in 1:20 ){
  curve(dbeta(x,shape1=i,shape2=i),add=T,col=rgb(i/20,0,i/20))
}
text(expression(paste("(",alpha, " , " ,beta, ") = 1~20")) , x = 0.8 , y = 5,cex=2 )
abline(v=0.5 , col="red")
text(expression(paste(theta , " = 0.5")) ,x=0.55 , y= 0.5 , cex=1.5,col="red")

f:id:hasegawa-yuta289:20201013210824p:plain

紅紫に近いほどパラメータが大きいです。
うーん、パラメータが上がってくると\displaystyle{
\theta = 0.5
}に近づいていくのはわかるけど……これは、どういうことですかね?

数式による説明

ベイズの定理によると、以下のようになります。

ちなみにここでは見やすくするために確率密度や確率関数を表す表記としてpを乱用してますが、どのpが何の(どの確率変数の)確率密度を表しているのかはその都度違うので注意してください。

\displaystyle{
\theta の事前分布が(0,1)の一様分布だとして、\\
パラメータ\thetaを成功確率に持っている二項分布\\
に従うデータyが与えられたとき、\\
\theta の事後分布は以下のようになる。  \\
\large{
\begin{eqnarray} 
p(\theta | y) &=& \frac{p(y| \theta) p(\theta)}{p(y)}\\
&\propto & p(y| \theta) p(\theta) \\
&=& nCy \,\theta^{\, y} \, (1-\theta)^{n-y} \  \cdot 1\\
&\propto& \theta^{\, y} \, (1-\theta)^{n-y} 
\end{eqnarray}
}
}

ベイズ統計なのでパラメータは確率変数で表現されています。

ちなみに\displaystyle{
\propto
}という記号は「比例」を表しています。ここではyが与えられているので、y(だけ)に関する値は定数として、この比例記号\displaystyle{
\propto
}で無視してしまいます。

なんと!この最後の式、これはベータ分布の分子そのものになってます!
ということは、\displaystyle{
 p(\theta | y)は\theta=0 \sim 1
}積分したときに1になっているはずなので、\displaystyle{
\theta
}のyを条件付けしたときの条件付き分布は、ベータ分布になっていることがわかります。

\displaystyle{
\theta の事前分布が(0,1)の一様分布だとして、\\
パラメータ\thetaを成功確率に持っている二項分布\\
に従うデータyが与えられたとき、\\
\theta の事後分布はBe(y+1,n-y+1)になる。  \\
}

ここで、yは成功回数、n-yは失敗回数ですから、結局以下のようになります。

\displaystyle{
Be(\alpha ,\beta)について、\\
\alpha-1は成功回数を、\\
\beta -1は失敗回数を、\\
それぞれ表している。\\
\theta \sim Be(\alpha ,\beta)は、成功回数\alpha-1、失敗回数\beta-1のときの、\\
成功確率として解釈できる。
}

ここで、もう一度さっき見た図を確認してみましょう。

curve(sin,lty=0,from=0,to=1,ylim=c(0,6),xlab=expression(paste(theta)),ylab="確率密度",main="ベータ分布 (パラメータは2つとも同じ値)")
for( i in 1:20 ){
  curve(dbeta(x,shape1=i,shape2=i),add=T,col=rgb(i/20,0,i/20))
}
text(expression(paste("(",alpha, " , " ,beta, ") = 1~20")) , x = 0.8 , y = 5,cex=2 )
abline(v=0.5 , col="red")
text(expression(paste(theta , " = 0.5")) ,x=0.55 , y= 0.5 , cex=1.5,col="red")

f:id:hasegawa-yuta289:20201013210824p:plain

\displaystyle{
(\alpha , \beta ) = 1 \sim 20
}となっていますが、これは「成功回数と失敗回数が同じである」というもとで、この回数を増やしていったとき、「成功確率はどのような値をとっていそうか?」ということを表しているわけですね。
例えば「成功回数1、失敗回数1」のときは、「まあ確かに成功確率が0.5かもしれないけど、でも本当に0.5かな?偶然そうなっただけなんじゃないの?」というのが分布で表現されているわけです。だから横に広い形になっているのです。
一方で、「成功回数19,失敗回数19」のときは、「38回もやっといて成功・失敗が半々なら、まあ成功確率はほとんど0.5なんでしょうね。少なくとも、0.5から大きく異なるような値である可能性は低いだろう」というのが分布で表現されています。だから横に狭い形になっているわけです。

ちなみに\displaystyle{
\alpha = 1 ,\beta = 1
}というのは「成功回数0、失敗回数0」に相当していますが、これは1回もコイントスをしていないのに、このコインの表が出る確率を考えよう……というのと同じ問題になります。当然、このコインが表になる確率について我々が知っていることは何もないわけですが、これがBe(1,1)が(0,1)の一様分布と等しいことに対応しているとも解釈できますね。
(まあ、本当に一様分布が「知ってることは何もない」無情報であることを表しているのか?みたいな疑問はあるかもしれませんが、ここでは無視します。)

以上のベータ分布の直感的な意味を考えつつ、以下のベータ分布の密度関数の形を想像してみましょうか。

\displaystyle{
Be(21,11)
}

これは成功回数が20,失敗回数が10のとき、さて成功確率はどのくらいでしょうか?というのを表しているわけですが……大体、成功確率は20/30=0.666くらいになりそうですね。試行回数が30回ですから、まあ0.666に近い値をとりそうです。
正解は以下のようになります。

curve(dbeta(x,shape1 = 21 , shape2 = 11),from=0 ,to=1 , xlab = expression(paste(theta)),ylab = "確率密度", main = "Be(21,11)")
abline(v=0.666,col="red")
text(expression(paste(theta , " = 0.666")) ,x=0.6 , y= 0.5 , cex=1.5,col="red")

f:id:hasegawa-yuta289:20201013211037p:plain

じゃあ今度は、

\displaystyle{
Be(200 , 100)
}

を考えてみましょう。これは成功回数の全体に対する比率が大体0.666でさっきと同じですが、こっちの方が試行回数が桁違いに多いのがわかります。その分だけ、分布の不確実性は下がりそうだとわかりますね。

curve(dbeta(x,shape1 = 200 , shape2 = 100),from=0 ,to=1 , xlab = expression(paste(theta)),ylab = "確率密度", main = "Be(200,100)")
abline(v=0.666,col="red")
text(expression(paste(theta , " = 0.666")) ,x=0.6 , y= 0.5 , cex=1.5,col="red")

f:id:hasegawa-yuta289:20201013212002p:plain

さっきよりも分布が横に狭くなりました。

これを考えていけば、例えばベータ分布の平均値は\displaystyle{
\frac{\alpha}{\alpha + \beta}
}になりますが、
成功回数/試行回数 \displaystyle{
\approx \frac{\alpha}{\alpha + \beta}
}として、ベータ分布の平均値を解釈できます。 (おわり)

北極3倍を食べた

この前蒙古タンメン中本に行って北極ラーメン(常設メニューの中じゃ一番辛いらしい)を食べたんだけど、正直そんなに辛くなかったのでガッカリしてたんだよね。いやまあ、もちろん美味しかったからそれは良いんだけど、カップ麺じゃなくてきちんとしたやつなわけだから、もっと辛いのかな〜……なんて。

 

で、また中本に行くことになったので今度はさらに辛いやつにしようってことで、北極ラーメンの辛さ3倍(通常の北極の3倍の唐辛子が入ってる)を頼みました。ちなみに10倍まで頼めるらしい。

f:id:hasegawa-yuta289:20201008201315j:image

辛さ等倍の北極はスープまで完飲したら翌日までお腹壊して最悪だったのでスープは飲まないように……と決めてチャレンジ。

 

一口入れたら、いやもう、結構からい。ペヤング「獄激辛」と比べれば遠く及ばないまでも、顔が熱くなる感覚っていうのかな?体の「モード」が「激辛モード」になったのを感じるくらいの辛さ。

3口めくらいまではスルスルいけたけど、まーなんかそこからしんどいんですよ。辛いもの食べて「しんどい」って感じたの久々だったね。それこそ獄激辛以来かな。アレと違って手が止まるほどではなかったけど。美味いには美味いんだけど……いや美味かったかな?美味しいのか美味しくなかったのかよく覚えてないわ。自信ないわ。辛さ+しんどさのが強くてあまり味を覚えてない。

 

食べ始めてすぐ涙が出てくる。止まらんの。なぜか左目からだけボロボロバラボロ涙が出てくる。そのあとに汗ね。途中から中本にいるのかサウナに入ってんのかわからんくらい汗が出てくる。

で、半分くらいまで食べ終わると鼻水が出てきたね。ティッシュで拭き取るんだけど、涙も止まらんし汗も出てくる。涙を拭き取るときにスープが目に入らないように注意を払わないといけないからめんどくさい。

 

まあダラダラ食べてたら麺がなくなったわけ。

普通ラーメンの麺食べ終わったら1口2口くらいはスープ飲んじゃおうかな〜どうしようかな〜みたいに考えると思うけど、もう食べてる途中に「さすがにこれスープ飲んだらマジで体調壊れるな」と思ったから当初の予定通り避けた。マジで1口も飲んでない。

ただまあ、スープの底に沈んだ具材くらいは食べんとな〜なんて思いながら、真っ赤なドンブリの奥にモヤシを見つけたのよ。全身ジャリジャリの唐辛子だらけ。モヤシはこれ拷問の最中かな?て感じ。俺いつから地獄の閻魔大王になったのかと思っちゃった。食べてもなんかもうよくわからんし。味 is どこ?

 

という感じでね、食べ終わりました。

f:id:hasegawa-yuta289:20201008202819p:image

 

「本当に食べ終わったのかよ?」て言われそうだけど本当に食べ終わりました。スープの透明度が1%もないから証明できないけど、この水面の下には一切の具材がありません。死の湖です。

 

《食べ終えて》

まぁ〜、美味しかった。美味しかったけど、これは果たして本当にラーメンが美味しかったのだろうか?という疑問が強い。辛いものはなんとなく美味しく感じるものなのでね。ぶっちゃけよくわかりませーん。お腹は壊した。スープ飲まなくてよかった。

俺にはまだ早かったな。北極等倍は美味しく食べられたけど、こっちはもうただのフードファイト。辛いもの好きな人は美味しく食べられるんだろうな。辛さで遊ぶのは今はここら辺が限界だなという感じでした。おわり

統計調査士(CBT方式)に合格しました・感想・統計検定

1990年代以降、「証拠に基づいた政策・意思決定」(evidence based policy)が世界的な潮流となっています。証拠の中心を成すのが統計データであり、なかでも公的統計は中央・地方の行政が施策を企画立案する上で、また国民・企業などが合理的に意思決定する際に欠かせぬものです。学術研究においても広く利用されています。現代において、政府等によって作成される公的統計は社会の情報インフラとして位置付けられますが、そこから目的に沿って有効な情報を引き出し、活用できなければ宝の持ち腐れといえます。統計調査士検定は、公的統計に関する基本的な知識を正確に認識し、公的統計を適切に利用する能力を評価する検定試験です。
統計調査士に合格することは、統計の役割、統計法規、公的統計が作成される仕組み等に加えて、主要な公的統計データの利活用方法に関する正確な理解を証するものです。合格することで、
(ア)取得する過程で有用な知識を体系的に整理して獲得できる、
(イ)自信と誇りを持って統計調査業務に取り組める、
(ウ) 公的統計に係る知識と能力が客観的に評価される
ため、就業において、とりわけ民間調査機関で優先的に採用されやすくなる 等の効果が期待されます。

とのことです(統計検定公式サイトより)

というわけでね、このたび統計検定の統計調査士に合格したので、感想でも書こうかなと。
せっかく合格したので統計調査士試験が超絶難関試験で取るのがもう死ぬほど大変で友達に超自慢できる資格だと嘘をついてもいいんですけど、まあせっかくなんで本当のことを言おうかな。
今回受験したのはCBT方式と言って、好きな日程・好きな試験会場で受験申込をし、当日は会場にあるコンピュータを使って回答し、その場で即時合否を確認できる方式になります。CBT方式はこの記事を書いた時点(2020/9/16)では統計検定4級~2級と統計調査士試験のみが対応しており、統計検定の準1級・1級・専門統計調査士は年に1回の紙の試験でしか受けられません。近々、専門統計調査士はCBT方式が解禁されるそうです。専門統計調査士っていうのは統計調査士の強い版みたいな資格です。多分2級よりは難しいと思います。

・内容
統計学の検定試験ではなく、統計分析の検定試験って感じでしたね。統計学の内容はあまり出てこないです。公的統計の種類を答えさせたり、どういう調査法が使われてるのかとか、まあそんな感じの内容です。データの集計結果を分析・解釈させる問題も出てきます。問題は全て5択問題です。

・レベル感
統計検定2級に合格できる人ならちょっと勉強すれば合格できると思います。とくに社会科学系の学部(卒)の人はマジ一瞬で合格できると思います。めっちゃ簡単でした。
内容は実務的なものに偏っていて統計学はあまり関係なく、また公的統計について問う問題が多いので理系卒の人は少し苦戦するかもしれません。ジニ係数GDPデフレータラスパイレス指数みたいな用語を聞いたことすらないよっていう人には割と難しく映ると思います。まあ7割取れれば合格なので、2日も勉強すれば合格圏内に入るんじゃないでしょうか(統計検定2級程度の知識があるものとする)。
僕は一応経済学部の人間なのでそこらへんの知識は普通にあったため特に苦労しませんでした。しかも統計学専攻なので尚更ですね。統計学が好きだよって人は2級程度なら勉強せずとも合格できると思うので、むしろ統計調査士試験の方が難しいと感じるんじゃないでしょうか。僕は2級よりも難しいと思いました。一般的には統計調査士試験よりも統計検定2級の方が難しい扱いになると思います(そもそも測っている能力がだいぶ違うのでこの比較はナンセンスかも)。

・勉強内容と勉強時間
過去問を読みました。勉強時間は4時間です。まあ、そのくらいのレベル感です。

・受験手順(CBTの場合)
オデッセイIDを取得→ネットで好きな会場の好きな時刻に受験申請をする→メールか何かがくるので受験料を口座振り込み→振込を確認しましたメールがくる→指定した時刻に指定した会場にてパソコンを使って受験する→受験終了後速攻で結果がでる

追記[11/09]
試験後ちょうど4週間くらいで合格証と手帳が届きました。気長に待ちましょう。

1次元ザリガニ釣りと幾何分布

ザリガニを釣ろう

最近暑いんでね、ザリガニを釣ろうかなと思います。
と言ってもただザリガニを釣るんじゃ面白くない(いや面白いけど)のでね、今回は仮想用水路に赴いて仮想ザリガニを捕獲する仮想ザリガニ釣りをやります。

ザリガニが10匹の場合を考えましょう。このザリガニの1匹の長さを1マスとして、200マスある用水路内の全てのザリガニを捕獲します。
人間様である私がわざわざザリガニを釣るために彼らを探して自分から釣りにいくのは負けた気がして嫌なので、この用水路の端っこでじっと待っていましょう。割りばしの端っこにタコ糸を巻き、糸先にはコンビニで買った「さきいか」をくっつけます。

ザリガニはこの用水路内に定常に分布し、ランダムに動き回ります。

YOSUIRO <- rep(0,200)
YOSUIRO[1:10] <- 1
set.seed(1)
YOSUIRO <- sample(YOSUIRO ,size=200,replace=FALSE)
YOSUIRO
##   [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
##  [38] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
##  [75] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
## [112] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
## [149] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0
## [186] 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0

例えばこれが一次元用水路内のザリガニの分布になってます。「1」がザリガニです。

sample(vec , size , replace)関数は、ベクトルvecの要素を、size回だけ無作為抽出し、それを並べる関数です。replaceをTRUEにするとこれは復元抽出、FALSEにすると非復元抽出です。vecに1:100、sizeを1にすれば、これは1,2,……,100の離散一様分布からの乱数として扱えます。

さっそくザリガニを釣っていきましょう。
最初は200マス中に10匹ザリガニがいますから、1回の試行で10/200=5%でザリガニがエサに食いつきます。エサに食いついたら100%でザリガニを釣れるとしましょう。

time <- 0
set.seed(1)
while(sum(YOSUIRO) != 0 ){
number <- sample(1:200,size=1)
if(YOSUIRO[number] == 1){YOSUIRO[number] <- 0}
time <- time+1
}
time
time
## [1] 676

ザリガニ釣り1回あたりの試行で1分かかるとすると、この用水路内のザリガニを根絶やしにするのに676分、全部で11時間ぐらいかかってしまいました。

仮想用水路は全国に無限個あるので、そのうち10000個の用水路内のザリガニ(10匹)を片っ端から釣ります。

time.vec <- c()
set.seed(100)
for( i in 1:10000){
YOSUIRO <- rep(0,200)
YOSUIRO[1:10] <- 1
time <- 0
while(sum(YOSUIRO) != 0 ){
number <- sample(1:200,size=1)
if(YOSUIRO[number] == 1){
  YOSUIRO[number] <- 0
  }
time <- time+1
}
time.vec[i] <- time
}
mean(time.vec)
mean(time.vec)
## [1] 583.0318

10000回繰り返してみた結果、200マスある一次元用水路内の10匹のザリガニを捕まえるのにかかる時間は、平均で583分、だいたい10時間かかるということがわかりました。

幾何分布

さて、仮想用水路200マスに潜むザリガニ10匹を釣り切るには平均して約583分かかるっぽいということがわかりましたが、これの理論上の値、つまり期待値はどのようにして求めることができるでしょうか。
これの計算には「幾何分布」Geo(p)を使うことができます。

1回あたり確率pで成功する事象を考えます。例えば均質なコインを投げたら表がでる確率はp=0.5ですが、表が出るまで投げたとき、投げた回数はどのような確率的振る舞いをするでしょうか?
表が出るかどうかはランダムですから、表が出るまで投げた回数もまたランダムに変動しますよね。つまり、確率変数なわけです。当たり前ですが投げた回数というのは自然数しかとりませんから、これは離散確率変数ですね。
1回あたり確率pで成功する事象をk回目で引き起こしたとき、これは言い換えればk-1回は失敗したことになります。失敗確率は1-pですから、(1-p)k-1 に、最後に成功する確率pをかけて、p(1-p)k-1が、成功するまで試行を繰り返すときに試行回数がk回である確率となります。この試行回数が従う分布のことを「幾何分布Geo(p)」と呼びます。

\displaystyle{
X \sim Geo(p)であるとき、\\
P(X=k)=p(1-p)^{ k - 1}
}

幾何分布に従う確率変数の期待値は1/pとなります。例えば確率0.2で成功するような事象を成功するまで繰り返すとき、繰り返し回数はだいたい5回くらいかな~というのは、まあなんとなくわかると思います。

(一応証明)

\displaystyle{
P(X=k)=(1-p)^{k-1}pより、\\
\begin{eqnarray}
E(X)&=&\sum _{k=1} ^{\infty} k(1-p)^{k-1}p \\
&=&p \lim _{n\rightarrow \infty}\frac{1}{p} \left( \frac{1-(1-p)^n}{1-(1-p)}-n(1-p)^n \right)\\
&=&p\ \cdot \ \frac{1}{p^2}=\frac{1}{p}
\end{eqnarray}
}

さて、ザリガニ釣りに戻りましょう。
今回は、先述した通り、まず10/200=5%の確率で1匹目のザリガニを釣ることができます。したがって、幾何分布の期待値が1/pであることより、1匹目のザリガニを釣るのにかかる平均回数は200/10=20回、となりますね。
1匹目を釣った後は、この1次元用水路に残るザリガニは9匹ですから、1匹目のザリガニを釣ったあと、2匹目のザリガニを釣るまでにかかる回数の期待値は200/9回となります。同様にして、3匹目のザリガニを釣るまでにかかる回数は200/8回、4匹目は200/7回、……、10匹目は200/1回となりますね。

以上より、

\displaystyle{
ザリガニ10匹を釣り終わるまでにかかる回数の期待値は、\\
200/10+200/9+\cdots +200/1
}

手計算はめんどくさいので機械を使って計算すると、この値は

Summation <- 0
for( i in 1:10){
  Summation <- Summation + 200/i
}
Summation
Summation
## [1] 585.7937

585.7937回になるとわかりました。
ザリガニ全部を釣り終わるまでにだいたい585分=9時間と45分かかるわけですね。いや~大変ですな。

コーシー分布の再生性を示す(特性関数って凄いのよ!)

コーシー分布の再生性を示そう with 特性関数

前回の記事では畳み込みを利用して気合でコーシー分布の再生性を示しました。

hasegawascond.hatenablog.com

確かにこのやり方は初等的で非常にわかりやすく、理解しやすいです。しかし一方で、(言うまでもなく)計算が死ぬほどめんどくさく、しかもただ時間がかかるだけでなく計算ミスも起きかねないという、正直あんまり勧められる方法ではないわけですね。今回は、コーシー分布の再生性を特性関数を利用して証明してみましょう。
特性関数を求めるときに留数定理など複素関数論の理論が出てきますが、これらについて全部説明するとさすがに面倒なのでそこら辺の説明は適宜端折ることにします。

特性関数とはなんぞや

特性関数の定義は以下。

\displaystyle{
確率変数Xの特性関数\ \phi(t)は、\\
\phi (t) = E\left[ exp(\,itX\,)  \right]\ と定義する 
}

特性関数は確率分布と1対1に対応しており、しかもモーメント母関数と違って全ての確率分布に存在することが証明できます。証明は多分調べたらすぐ出てきます。

コーシー分布

位置パラメータが x_0、尺度パラメータが \sigmaのコーシー分布の密度関数は以下のように定義されます。

\displaystyle{
f(x)=\frac{\sigma}{\pi}\frac{1}{\sigma^2 + (x-x_0)^2} 
}

標準コーシー分布の特性関数を求める

まず、簡単のために位置パラメータが0、尺度パラメータが1のコーシー分布について特性関数を求めてみましょう。

\displaystyle{
\begin{eqnarray}
\phi(t) &=& E(exp(itX))\\
&=& \int_{-\infty}^{\infty}exp(itx) \frac{1}{\pi} \frac{1}{1+x^2} dx\\
&=&\frac{1}{\pi}\int_{-\infty}^{\infty} \frac{exp(itx)}{1+x^2} dx
\end{eqnarray}
}

最後の積分がやや曲者なので、これを複素関数論の理論を使って計算していきましょう。
最後の積分の中身について、

\displaystyle{
f(z)=\frac{exp(itz)}{1+z^2} = \frac{exp(itz)}{(z-i)(z+i)} \quad(z \in \mathbb{C})
}

としてf(z)を定義します。

以下の経路を定義します。

\displaystyle{
C_R : -R \rightarrow R \rightarrow (半径Rの円の上半周上を走る)\rightarrow-R\\
\Gamma_R:R \rightarrow (半径Rの円の上半周上を走る)\rightarrow-R
}

図にすると以下(手書きですいません)。

f:id:hasegawa-yuta289:20200824030246j:plain

このように定義した経路について、-RからRまでの積分を以下のように計算します。

\displaystyle{
\large{
\begin{eqnarray}
\int_{-R}^{R} f(x)dx &=& \int_{C_R} f(z)dz - \int_{\Gamma_R}f(z)dz
\end{eqnarray}
}
}

こうやって求めた積分について R\rightarrow \inftyとしてやれば、特性関数が求まります。

まずt>0として求めましょう。
CRについて計算していきます。
十分大きい任意のRについて、CR内の特異点は、f(z)の1位の極z=iのみであり、ここで留数Res(f,i)は

\displaystyle{
\large
Res(f,i)=\lim_{z\rightarrow i}(z-i)f(z)=\frac{1}{2i}exp(-t)
}

であるから、留数定理より

\displaystyle{
\large{
\begin{eqnarray}
\int_{C_R} f(z)dz &=&2\pi i\  Res(f,i)\\
&=&\pi\  exp(-t) \\
&\rightarrow& \pi\ exp(-t)\quad(R\rightarrow \infty) 
\end{eqnarray}
}
}

と求まりました。

次にΓRについて求めましょう。
以下の定理を認めてしまいます。複素関数論の本なら大体載っているのかなと思いますが、例えば証明は『複素関数論』(森・杉原)の148pに載ってます。

\displaystyle{
g(z)は複素平面の上半分で原点から十分遠い領域にて正則であり、\\
|z|\rightarrow \inftyのとき0に一様収束するとする。\\
このとき、\lim_{R\rightarrow \infty}\int_{\Gamma_R}exp(ipz)g(z)dz=0\quad (p > 0)
}

この定理は、まあ直感的には以下のような解釈ができそう。

\displaystyle{
z=x+iy とする。\quad(x,y\in \mathbb{R})\\
exp(ipz)=exp(ipx+ip(iy))=exp(ipx)\times exp(-py)\\
ここで、exp(ipx)は単位円上の点であるからノルムの観点から無視してしまおう。\\
p > 0であることと、\Gamma_R上ではy > 0 であることから、\\
\Gamma _R 上にてexp(-py)は定数で抑えられ、\\
原点から十分離れたzについてほとんど0になるg(z)に潰されてしまい、\\
結局積分値は0へと収束することになる。
}

さて、この定理について、

\displaystyle{
g(z)=\frac{1}{1+z^2}
}

とすれば、t>0より、

\displaystyle{
\lim_{R \rightarrow \infty}\int_{\Gamma_R}f(z)dz=0
}

とわかる。

次にt<0の場合を考えます。
ΓRの部分で上手くいくようにするため(p>0でないと上の定理が使えないのでね)、

\displaystyle{
\begin{eqnarray}
\int_{-\infty}^{\infty} \frac{exp(itx)}{1+x^2} dx&=&\int_{-\infty}^{\infty} \frac{exp(\,i\,(-t)(-x)\,)}{1+(-x)^2} dx\\
(y=-xとする)  &=& \int_{-\infty}^{\infty} \frac{exp(\,i\,(-t)y\,)}{1+y^2} dy
\end{eqnarray}
}

として、

\displaystyle{
f(z)=\frac{exp(i(-t)z)}{1+z^2} = \frac{exp(i(-t)z)}{(z-i)(z+i)} \quad(z \in \mathbb{C})
}

と定義し直す。
CRについて、先の場合と同様にして、

\displaystyle{
\large{
\begin{eqnarray}
\int_{C_R} f(z)dz &=&2\pi i\  Res(f,i)\\
&=&\pi\  exp(t) \\
&\rightarrow& \pi\ exp(t)\quad(R\rightarrow \infty) 
\end{eqnarray}
}
}

ΓRについても同様に、

\displaystyle{
\lim_{R \rightarrow \infty}\int_{\Gamma_R}f(z)dz=0
}

以上より、

\displaystyle{
t > 0 のとき、\\
\phi(t) = exp(-t)\\
t < 0 のとき、\\
\phi(t) = exp(t)
}

これらをまとめて、

\displaystyle{
標準コーシー分布の特性関数\\
\phi(t) = exp( - |t| )
}

とわかる。
なお、t=0の場合についてこれが成立していることはすぐにわかる。

コーシー分布の特性関数を求める

\displaystyle{
\begin{eqnarray}
\phi(t) &=&\int_{- \infty }^{\infty} exp(itx)\frac{\sigma}{\pi}\frac{1}{\sigma^2 + (x- x_0)^2} dx\\
&=&\frac{\sigma}{\pi}\int_{- \infty }^{\infty}\frac{exp(itx)}{\sigma^2 + (x- x_0)^2} dx\\
\end{eqnarray}
}

最後の積分の中身について、

\displaystyle{
\begin{eqnarray}
f(z)=\frac{exp(itz)}{ ( (z-x_0)- i \sigma) ( (z-x_0)+ i \sigma) }
\end{eqnarray}
}

と定義する。
先の例と同様にして経路を以下のように設定する。

f:id:hasegawa-yuta289:20200824030312j:plain

t>0の場合について、

\displaystyle{
Res(f,x_0+i\sigma)=\frac{exp(it(x_0 + i \sigma))}{2i\sigma}
}

よって

\displaystyle{
\large{
\begin{eqnarray}
\int_{C_R} f(z)dz &=&2\pi i\  Res(f,i)\\
&=&\frac{\pi}{\sigma}\  exp(itx_0 - \sigma t) \\
&\rightarrow& \frac{\pi}{\sigma}\  exp(itx_0 - \sigma t) \quad(R\rightarrow \infty) 
\end{eqnarray}
}
}

ΓRについても標準コーシー分布の場合と同様にして、( R \rightarrow \inftyで)0と計算できる。
t<0についても、やはり標準コーシー分布の場合と同様に計算ができて、結局、

\displaystyle{
\Large{
コーシー分布の特性関数\\
\phi(t) = exp(ix_0 t - \sigma |t| )
}
}

コーシー分布の再生性

特性関数が手に入ったので、簡単に再生性を示すことができる。

\displaystyle{
\large{
\begin{eqnarray}
\phi_{\bar X}(t)&=&\left\{ \phi \left( \frac{t}{n} \right)  \right\}^n\\
&=& \left\{exp \left(ix_0 \frac{t}{n} - \sigma \left| \frac{t}{n} \right| \right) \right\}^n\\
&=& exp(ix_0 t - \sigma |t| )\\
&=& \phi(t)
\end{eqnarray}
}
}

特性関数は確率分布と対応しているので、コーシー分布からのランダムサンプルの標本平均が従う確率分布は、元のコーシー分布と全く一致していることが示せた。

このように特性関数を利用することで、畳み込みを利用するよりもずっと簡単に再生性を示すことができるのだ~!(凄い!)