浅野・矢内(2018)に基づいて7章の統計的推計をまとめていきます。コマンドは、オーム社のHPからDLしたスクリプトを元にしています。また、他に、石村貞夫『統計解析のはなし』(東京図書、1989年)などを参考にしています。
##7.1 母集団と標本 ###イントロダクション 母集団の数値、母数(parameter)を推定することを目的とする。 母集団から標本抽出し得られたデータを基に、計算して得られるのが統計量(statistic)である。さらにその中でも母数の推定のために利用されるものが推定量(estimator)である。
不偏性(unbiasedness):推定量を平均すると、求めたい母数に一致するという性質。このような推定量は不偏推定量(unbiased estimator)と呼ばれる。
➞標本から得られる標本平均という統計量を使って母平均という母母数を推定する。
一致性(consistency):サンプルサイズを大きくするほど、求めたい母数から離れた値をとる確率が小さくなるという性質。このような推定量は一致推定量(consistent estimator)と呼ばれる。
まずは今回使う tidyverse パッケージを読み込む
library("tidyverse")
## ─ Attaching packages ───────── tidyverse 1.2.1 ─
## ✔ ggplot2 3.1.0 ✔ purrr 0.3.0
## ✔ tibble 1.4.2 ✔ dplyr 0.7.8
## ✔ tidyr 0.8.2 ✔ stringr 1.3.1
## ✔ readr 1.3.1 ✔ forcats 0.3.0
## Warning: package 'purrr' was built under R version 3.5.2
## ─ Conflicts ────────── tidyverse_conflicts() ─
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
統計的推計とは、母集団から一部の標本を抜き出し、この標本を分析することで元の母集団について知識を得ようとすることである。
ここでは、その試行として、仮の母集団データを生成し、標本調査を行う。
まず、生成する母集団データは、10万人の身長データである。この母集団の平均(母平均μ)は170cm、母集団の標準偏差(母標準偏差σ)は6とする。μ=170,σ=6
set.seed(2018 - 11 - 20) #乱数を準備
population <- rnorm(100000, mean = 170, sd = 6) #rnorm : Normal Disribution(正規分布)を作成するコマンド
mean(population) #平均値
## [1] 170.0057
sd(population) #標準偏差(Standard Deviation)
## [1] 6.000263
次に、母集団の分布をヒストグラムで図示する。(p.125, 図3)
hist_pop <- data_frame( pop = population) %>%
ggplot(aes(x = pop, y = ..density..)) + #確率密度(density)オプションを指定。
geom_histogram(binwidth = 1, color = "black") +
xlim(140, 200) + ylim(0, 0.6) +
labs(x = "height (cm)", y = "density")
print(hist_pop) #図示
上で定義した母集団から、サイズ10の標本を500個抽出する。結果を保存するために、予め10行x500列の空の行列を用意しておく。 新たに使用するのは matrix, for, sample
size10 <- matrix(data = NA, nrow = 10, ncol = 500) #matrixコマンドで、10行×500列の行列を、size10という名前で作成。
for (i in 1:500) {
size10[, i] <- sample(population, size = 10, replace = FALSE)
# for 構文で同内容の標本抽出を500回繰り返す
#sampleコマンドで、populationというデータフレームの中から、サイズ10のサンプルを、非復元抽出で標本抽出し、size10に格納する。
}
それぞれの標本での平均値を計算し、データフレームの1変数として保存する。
colMeans でsize10の平均値を計算し、means_s10 (10のサンプルサイズの平均値)という名前で、データ保存作成用のdata_frameコマンドで格納。そしてそれをdfというオブジェクト名にする。一応、データを確認。
df <- data_frame(means_s10 = colMeans(size10))
head(df, n = 10) # df 入力で全表示でも良いが、500回の標本抽出の平均値500個になるので長い。
## # A tibble: 10 x 1
## means_s10
## <dbl>
## 1 172.
## 2 167.
## 3 168.
## 4 171.
## 5 170.
## 6 172.
## 7 169.
## 8 168.
## 9 172.
## 10 172.
標本平均の標本分布をヒストグラムにする(p.126 図7.4)
hist_size10 <- ggplot(df, aes(x = means_s10, y = ..density.. )) +
geom_histogram(binwidth = 1, color = "black") +
xlim(140, 200) + ylim(0, 0.6) +
labs(x = expression(paste(" height ", bar(x), " (cm)")),
y = "density")
print(hist_size10)
## Warning: Removed 2 rows containing missing values (geom_bar).
500の標本平均内の標準誤差(バラツキ)を計算する
sd(df$means_s10)
## [1] 1.912701
標準偏差: sd(df$means_s10)
だとわかる。 ヒストグラムからも標準偏差からも、標本平均が収束していることが伺える。
さらに、サンプルサイズを増やして考えてみる。
先程と同様に、母集団からサンプルサイズ90の標本を500個抽出する。
90行x500列の空の行列を用意し、サンプルサイズ90で標本抽出を500回繰り返す。
size90 <- matrix(NA, nrow = 90, ncol = 500)
for (i in 1:500) { # 標本抽出を500回繰り返す
size90[, i] <- sample(population, size = 90, replace = FALSE)
}
それぞれの標本での平均値を計算し、データフレームの1変数として保存する
df <- mutate(df, means_s90 = colMeans(size90))
#size90 という名前の標本の平均値を出し、dfの中に、means_s90という名前で変数として新たに作成する。
同様に、標本平均の標本分布をヒストグラムにする(p.128,図7.5)
hist_size90 <- ggplot(df, aes(x = means_s90, y = ..density.. )) +
geom_histogram(binwidth = 1, color = "black") +
xlim(140, 200) + ylim(0, 0.6) +
labs(x = expression(paste("height ", bar(x), " (cm)")),
y = "density")
print(hist_size90)
## Warning: Removed 2 rows containing missing values (geom_bar).
標本サイズ90の場合の標本平均のばらつき(標準誤差)を計算する
sd(df$means_s90)
## [1] 0.627559
最後に、確認として、標本サイズ10の場合と90の場合の標本のばらつきの比を計算する
sd(df$means_s10) / sd(df$means_s90)
## [1] 3.047842
推定の精度を評価するために、推定の不確実性を明らかにする必要がある。
そこで、信頼区間(confidence interval: CI)を利用する。
信頼区間とは、「母平均μは〇〇以上☓☓以下である」というように、幅をもたせる推定であり、これを利用した推定は区間推定と呼ばれる。
標本統計量の不確実性は標本分布のばらつきとして現れる。 前提として、標本平均の標準誤差の計算式を利用する。サンプルサイズ n と母標準偏差 σ が判明すれば、標本平均の標準誤差がわかる。
しかし、母標準偏差 σ は、未知である。
そこで、まずはこの σ を推定することにする。
そのため、標本平均の標準誤差(standard error:SE)を利用する。そして、これを利用して標本平均を変形させる。そして、 \[
T=\frac{\bar{x}-μ}{SE}
\] を得る。このTは、t分布に従っていることが知られれている。さらに、式から標本平均が母平均に一致するときにT=0となる。
ここで、t分布をRで表示させてみよう。t分布は自由度と呼ばれる数値によって分布の形が変化する。
df_t <- data_frame(x = seq(-3, 3, length.out = 100)) %>%
mutate(`1` = dt(x, df = 1),
`5` = dt(x, df = 5),
`99` = dt(x, df = 99)) %>%
gather(key = "df", value = "density", `1`:`99`)
t_dist <- ggplot(df_t, aes(x = x, y = density,
color = df, linetype = df)) +
geom_line() +
labs(x = "", y = "density") +
scale_x_continuous(breaks = -3:3) +
scale_color_discrete(name = "degree of freedom") +
scale_linetype_discrete(name = "degree of freedom") +
guides(shape = guide_legend(reverse = TRUE))
print(t_dist)
標本平均の推定では、自由度がn-1のt分布を利用する。
それでは、自由度99のt分布で、データの95%が収まる範囲の上限値を求める
qt(p = 0.025, df = 99, lower.tail = FALSE)
## [1] 1.984217
# または、
qt(p = 0.975, df = 99, lower.tail = TRUE)
## [1] 1.984217
## 同様に、下限値を求める
qt(p = 0.025, df = 99, lower.tail = TRUE)
## [1] -1.984217
ここから、データの95%が収まる範囲が、-.198~1.98であることがわかる。
上で定義した母集団(身長の母平均が約170)からサンプルサイズ100の標本を1000個抽出し、それぞれの標本について信頼区間を求める。
n <- 100
res <- matrix(NA, nrow = n, ncol = 1000)
for (i in 1:1000) {
res[, i] <- sample(population, size = n, replace = FALSE)
}
それぞれの標本の平均と標準偏差を求めてデータフレームの変数にする。
その後、標準誤差 se と95%信頼区間の下限 lb、上限ub を計算する。
df_ci <- data_frame(id = 1:1000,
means = colMeans(res),
sds = apply(res, MARGIN = 2, FUN = sd)) %>%
mutate(se = sds / sqrt(n),
lb = means + qt(p = 0.025, df = 99, lower.tail = TRUE) * se,
ub = means + qt(p = 0.025, df = 99, lower.tail = FALSE) * se)
head(df_ci) # 結果の一部を見てみる
## # A tibble: 6 x 6
## id means sds se lb ub
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 170. 5.40 0.540 169. 171.
## 2 2 170. 5.59 0.559 168. 171.
## 3 3 169. 6.64 0.664 168. 171.
## 4 4 170. 5.69 0.569 169. 171.
## 5 5 169. 6.03 0.603 168. 170.
## 6 6 171. 6.42 0.642 169. 172.
信頼区間の中に真の母平均が含まれているかどうか判定する変数を作る
(pop_mean <- mean(population)) # 真の母平均をpop_meanで格納
## [1] 170.0057
df_ci <- mutate(df_ci,
success = (lb <= pop_mean & ub >= pop_mean))
## 母平均を区間内に捉えた95%信頼区間の割合を計算する
mean(df_ci$success)
## [1] 0.949
1000個の標本から50個をランダムに選び、95%信頼区間を図示する。
set.seed(2018-11-22)
ci_plt <- sample_n(df_ci, size = 50) %>%
ggplot(aes(x = reorder(id, means), y = means,
ymin = lb, ymax = ub, color = success)) +
geom_hline(yintercept = pop_mean, color = "dodgerblue") +
geom_linerange() +
geom_point() +
scale_color_discrete(name = "does this include the population mean??") +
labs(x = "", y = "95% confidence interval") +
coord_flip()
print(ci_plt)
例7.4:衆院データを使って信頼区間を求める
HR <- read_rds("data/hr-data.Rds")
## Rdsファイルの読み込みがうまくいかない場合は以下を実行
#download.file(url = "https://git.io/fxhQU",
# destfile = "data/hr-data.csv")
#HR <- read_csv("data/hr-data.csv")
## 候補者の年齢ageの50%信頼区間を求める
age_ci50 <- t.test(HR$age, conf.level = 0.5)
age_ci50$conf.int
## [1] 50.81778 50.97717
## attr(,"conf.level")
## [1] 0.5
## 候補者の年齢ageの95%信頼区間を求める
age_ci95 <- t.test(HR$age)
age_ci95$conf.int
## [1] 50.66587 51.12908
## attr(,"conf.level")
## [1] 0.95
50%信頼区間よりも、95%信頼区間のほうが長い範囲であることがわかる。