library(tidyverse)
5回の試行で3回成功(成功確率 \(p\)),2回失敗(失敗確率 \(1-p\))した場合の尤度関数と対数尤度関数.
\[ L(p) = \Pr(\mbox{failure})^2 \times \Pr(\mbox{success})^3 = (1-p)^2 p^3, \quad \log L(p) = 2 \log (1-p) + 3 \log (p) \]
一階の条件(\(L(\hat{p})' = 0\) または \(\log L(\hat{p})' = 0\))より \(\hat{p} = 0.6\) が得られる.
\[ \frac{d L(p)}{d p} = \frac{d}{d p} (1-p)^2 p^3 = -2(1-p)p^3 + (1-p)^2 \times 3p^2 = (1-p)p^2[-2p + 3(1-p)] = 0 \]
l_func <- function (p) (1-p)^2 * p^3 # 尤度関数
ll_func <- function (p) 2 * log(1-p) +3 * log(p) # 対数尤度関数
plot(l_func, xlim = c(0, 1)); abline(v = .6, lty = 2, col = 2)
plot(ll_func, xlim = c(0, 1)); abline(v = .6, lty = 2, col = 2)
標本 \(\{-3, -2, 0.5, 0.5, 1.5\}\) に基づいて母平均 \(\mu\) と母分散 \(\sigma^2\) を推定.
この標本が正規母集団からサンプリングされていると仮定すると,対数尤度関数は次のように書ける.
\[ f = \frac{1}{\sqrt{2 \pi \sigma^2}} \exp \left[- \frac{(y_i - \mu)^2}{2 \sigma^2} \right] , \quad \log f = - \frac{1}{2} \log 2 \pi - \frac{1}{2} \log \sigma^2 - \frac{(y_i - \mu)^2}{2 \sigma^2} \]
\[ \log L = - \frac{n}{2} \log 2 \pi - \frac{n}{2} \log \sigma^2 - \frac{1}{2 \sigma^2} \sum_i (y_i - \mu)^2 \]
よって,最尤推定量は次のように解析的に求められる.
\[ \hat{\mu} = \frac{1}{n} \sum_i y_i , \quad \hat{\sigma}^2 = \frac{1}{n} \sum_i (y_i - \bar{y})^2 \]
y <- c(-3, -2, 0.5, 0.5, 1.5) # 標本
mean(y) # 標本平均(mu の最尤推定量と同じ)
## [1] -0.5
var(y) # 標本分散
## [1] 3.625
sum((y - mean(y))^2) / length(y) # 分散(sigma^2 の最尤推定量と同じ)
## [1] 2.9
対数尤度関数を定義する. 最初の引数がパラメタベクトルになっている(後述の最適化のため).
ll_func_n <- function (param, y, n) { # 対数尤度関数
mu <- param[1]
sigma2 <- param[2]
-n/2*log(2*pi) - n/2*log(sigma2) - 1/(2*sigma2)*sum((y-mu)^2)
}
\(\sigma^2 = 1\) に固定した場合の \(\mu\) と対数尤度の関係をプロットする.
mu_list <- seq(-2, 2, length = 100)
ll_mu_list <- sapply(X = mu_list,
FUN = function(x) ll_func_n(param = c(x, 1), y = y, n = length(y)))
plot(x = mu_list, y = ll_mu_list, xlim = c(-2, 2), type = "l")
3Dで描画する.(outer
関数を使って z
を計算するつもりだったが,なぜか outer
関数にかませる尤度関数中で sum((y-mu)^2)
が評価できないので
for
文をネストして計算する.)
grid_mu <- seq(-2, 2, length = 20) # 探索する範囲を grid で表す
grid_sigma2 <- seq(1, 10, length = 20)
z <- matrix(0, nrow = length(grid_mu), ncol = length(grid_sigma2))
for (i in 1:length(grid_mu)) { # 探索 grid に対応する対数尤度を計算
for (j in 1:length(grid_sigma2)) {
z[i, j] <- ll_func_n(param = c(grid_mu[i], grid_sigma2[j]), y = y, n = length(y))
}
}
which_max_ml <- which(z == max(z), arr.ind = T) # 尤度を最大化する grid の index
grid_mu[which_max_ml[1]]; grid_sigma2[which_max_ml[2]] # ML推定量 (gridが粗いので精度は低い)
## [1] -0.5263158
## [1] 2.894737
persp(grid_mu, grid_sigma2, z, theta = 50, phi = 20) -> pmat_persp
points(trans3d(x = grid_mu[which_max_ml[1]], y = grid_sigma2[which_max_ml[2]],
z = z[which_max_ml], pmat = pmat_persp), col = 2, pch = 19)
汎用の最適化関数 optim
を使って最尤推定する.
$par
が最適化されたパラメタの値(最尤推定値).
$value
は最大化された対数尤度.
$convergence
は 0 ならば収束したことを意味する.
optim
はデフォルトでは与えられた関数を最小化するため,最大化するためには目的関数を
-1 倍した値を最小化するように設定する(引数
control = list(fnscale = -1)
).
optim(par = c(0, 1), fn = ll_func_n, y = y, n = length(y), control = list(fnscale = -1))
## $par
## [1] -0.5000029 2.8995297
##
## $value
## [1] -9.75647
##
## $counts
## function gradient
## 65 NA
##
## $convergence
## [1] 0
##
## $message
## NULL
誤差項が正規分布に従うと仮定した場合の回帰モデルの対数尤度関数.
\[ y_i = \beta_0 + \beta_1 x_{i1} + \beta_2 x_{i2} + u_i, \quad u_i \sim N(0, \sigma^2) \]
\[ \log L (\beta) = - \frac{n}{2} \log (2 \pi \sigma^2) - \frac{1}{2 \sigma^2} \sum_i (y_i - x_i' \beta)^2 \]
ここで \(x_{i}' \beta = \beta_0 + \beta_1 x_{i1} + \beta_2 x_{i2}\) である.
引数 param
は k+1 個のパラメタベクトル. k
は定数項を含めた説明変数の数. 1 つ目から k 個目までが回帰係数で,k+1
個目は \(\sigma^2\).
ml_gauss <- function (y_gauss, x_gauss) {
LL_gauss <- function (param) { # 対数尤度関数
- (n / 2) * log(2 * pi * param[k+1]) -
sum((y_gauss - x_gauss %*% param[1:k])^2) / (2 * param[k+1])
}
n <- nrow(x_gauss) # サンプルサイズ
k <- ncol(x_gauss) # 説明変数の数(定数項を含む)
optim(par = rep(1, k+1), fn = LL_gauss, control = list(fnscale = -1)) # 尤度最大化
}
y_swiss <- swiss$Fertility # y
x_swiss <- cbind(1, swiss$Agriculture, swiss$Examination) # X
ml_gauss(y_gauss = y_swiss, x_gauss = x_swiss)
## $par
## [1] 94.66923521 -0.09443892 -1.19762789 86.69205312
##
## $value
## [1] -171.5454
##
## $counts
## function gradient
## 357 NA
##
## $convergence
## [1] 0
##
## $message
## NULL
答え合わせ.
lm(Fertility ~ Agriculture + Examination, swiss)
##
## Call:
## lm(formula = Fertility ~ Agriculture + Examination, data = swiss)
##
## Coefficients:
## (Intercept) Agriculture Examination
## 94.610 -0.094 -1.195
Titanic データの読み込み.
titanic <- read.csv("https://raw.githubusercontent.com/kurodaecon/bs/main/data/titanic3_csv.csv")
生存したかどうかを表す Survived
変数を,性別,年齢,客室等級変数に回帰.
\[ \mbox{Survived} = \beta_0 + \beta_1 \mbox{Male} + \beta_2 \mbox{Age} + \beta_3 \mbox{2nd-class} + \beta_4 \mbox{3rd-class} \]
summary(lm(survived ~ sex + age + factor(pclass), data = titanic))
##
## Call:
## lm(formula = survived ~ sex + age + factor(pclass), data = titanic)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.09442 -0.24408 -0.08375 0.23289 0.99397
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.1049549 0.0438211 25.215 < 2e-16 ***
## sexmale -0.4914132 0.0255520 -19.232 < 2e-16 ***
## age -0.0052695 0.0009316 -5.656 2.00e-08 ***
## factor(pclass)2 -0.2113738 0.0348568 -6.064 1.85e-09 ***
## factor(pclass)3 -0.3703874 0.0325039 -11.395 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.3913 on 1041 degrees of freedom
## ( 263 個の観測値が欠損のため削除されました )
## Multiple R-squared: 0.3691, Adjusted R-squared: 0.3667
## F-statistic: 152.3 on 4 and 1041 DF, p-value: < 2.2e-16
解釈
\[ p = \Pr (y = 1) = \Phi (\beta_0 + \beta_1 x) \]
glm
関数で推定.
probit_titanic <- glm(formula = survived ~ sex + age + factor(pclass), data = titanic,
family = binomial(link = "probit"))
summary(probit_titanic)
##
## Call:
## glm(formula = survived ~ sex + age + factor(pclass), family = binomial(link = "probit"),
## data = titanic)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 2.055101 0.181290 11.336 < 2e-16 ***
## sexmale -1.485640 0.093813 -15.836 < 2e-16 ***
## age -0.019426 0.003606 -5.387 7.16e-08 ***
## factor(pclass)2 -0.760170 0.129921 -5.851 4.89e-09 ***
## factor(pclass)3 -1.303160 0.126633 -10.291 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1414.62 on 1045 degrees of freedom
## Residual deviance: 984.55 on 1041 degrees of freedom
## ( 263 個の観測値が欠損のため削除されました )
## AIC: 994.55
##
## Number of Fisher Scoring iterations: 5
対数尤度関数を汎用の最適化関数 optim
で最大化することで推定する.
選択確率は以下で与えられる.
\[ \Pr (Y=1) = \Phi (\beta_0 + \beta_1 X) = \frac{1}{2 \pi} \int_{-\infty}^{\beta_0 + \beta_1 X} \exp \left( - \frac{t^2}{2} \right) dt \]
よって,尤度関数は以下のようになる.
\[ L (\beta_0, \beta_1) = \prod_i \left[ \{ \Pr (Y_i = 1) \}^{Y_i} \times \{ \Pr (Y_i = 0) \}^{1 - Y_i} \right] = \prod_i \left[ \{ \Phi (\beta_0 + \beta_1 x) \}^{Y_i} \times \{ 1 - \Phi (\beta_0 + \beta_1 x) \}^{1 - Y_i} \right] \]
対数を取ると対数尤度関数が得られる.
\[ \log L (\beta_0, \beta_1) = \sum_i \left[ Y_i \times \log \{ \Phi (\beta_0 + \beta_1 x) \} + (1 - Y_i) \times \log \{ 1 - \Phi (\beta_0 + \beta_1 x) \} \right] \]
これを,\((\beta_0, \beta_1)\) を引数とする関数として定義すればよい.
標準正規分布の分布関数は pnorm
で与えられる.
ml_probit <- function (y_probit, x_probit) {
LL_probit <- function (param) {
pnorm_xbeta <- pnorm(q = x_probit %*% param, mean = 0, sd = 1)
sum(y_probit %*% log(pnorm_xbeta) + (1-y_probit) %*% log(1 - pnorm_xbeta))
}
optim(par = rep(0, ncol(x_probit)), fn = LL_probit, control = list(fnscale = -1))
}
上と同じ説明変数を使って推定する.
まずは,計算のために character/factor 型に対応する数値を計算しておく.
titanic_numeric <- titanic %>%
filter(!is.na(age)) %>%
mutate(male = 1*(sex == "male"),
pclass2 = 1*(pclass == 2),
pclass3 = 1*(pclass == 3))
titanic_x <- titanic_numeric %>%
dplyr::select(male, age, pclass2, pclass3) %>%
as.matrix
ml_probit(y_probit = titanic_numeric$survived, x_probit = cbind(1, titanic_x))
## $par
## [1] 2.05418759 -1.48531017 -0.01941115 -0.76010160 -1.30246558
##
## $value
## [1] -492.2765
##
## $counts
## function gradient
## 468 NA
##
## $convergence
## [1] 0
##
## $message
## NULL
説明変数の平均値 \(\bar{x}\) を用いる方法.
\[ ME_{x} = \phi (\hat{\beta_0} + \hat{\beta_1} \bar{x}) \hat{\beta_1} \]
xb_mean <- probit_titanic$coef %*% c(1, mean(titanic_numeric$male), mean(titanic$age, na.rm = TRUE),
mean(titanic$pclass == 2), mean(titanic$pclass == 3))
as.numeric(dnorm(x = xb_mean)) * probit_titanic$coef
## (Intercept) sexmale age factor(pclass)2 factor(pclass)3
## 0.77727888 -0.56189779 -0.00734726 -0.28751081 -0.49288013
Individual ごとの限界効果の平均値を計算する方法.
\[ ME_{x} = \frac{1}{n} \sum_i ME_{i, x} = \frac{1}{n} \sum_i \phi (\hat{\beta_0} + \hat{\beta}_1 x_i) \hat{\beta}_1 \]
xb <- as.matrix(cbind(1, titanic_numeric[, c("male", "age", "pclass2", "pclass3")])) %*% probit_titanic$coef
c(male = mean(dnorm(x = xb) * probit_titanic$coef[2], na.rm = TRUE),
age = mean(dnorm(x = xb) * probit_titanic$coef[3], na.rm = TRUE),
class2 = mean(dnorm(x = xb) * probit_titanic$coef[4], na.rm = TRUE),
class3 = mean(dnorm(x = xb) * probit_titanic$coef[5], na.rm = TRUE))
## male age class2 class3
## -0.392874167 -0.005137142 -0.201025116 -0.344617610
mfx
パッケージを使う場合.
# install.packages("mfx")
library(mfx)
probitmfx(formula = survived ~ sex + age + factor(pclass), data = titanic)
## Call:
## probitmfx(formula = survived ~ sex + age + factor(pclass), data = titanic)
##
## Marginal Effects:
## dF/dx Std. Err. z P>|z|
## sexmale -0.5408979 0.0287920 -18.7864 < 2.2e-16 ***
## age -0.0074648 0.0013850 -5.3898 7.052e-08 ***
## factor(pclass)2 -0.2672290 0.0404958 -6.5989 4.141e-11 ***
## factor(pclass)3 -0.4666238 0.0395420 -11.8007 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## dF/dx is for discrete change for the following variables:
##
## [1] "sexmale" "factor(pclass)2" "factor(pclass)3"
\[ p = \Pr (y = 1) = \Lambda (\beta_0 + \beta_1 x) \]
glm
関数で推定.
logit_titanic <- glm(formula = survived ~ sex + age + factor(pclass), data = titanic,
family = binomial(link = "logit"))
summary(logit_titanic)
##
## Call:
## glm(formula = survived ~ sex + age + factor(pclass), family = binomial(link = "logit"),
## data = titanic)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 3.522075 0.326702 10.781 < 2e-16 ***
## sexmale -2.497845 0.166037 -15.044 < 2e-16 ***
## age -0.034393 0.006331 -5.433 5.56e-08 ***
## factor(pclass)2 -1.280571 0.225538 -5.678 1.36e-08 ***
## factor(pclass)3 -2.289661 0.225802 -10.140 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1414.62 on 1045 degrees of freedom
## Residual deviance: 982.45 on 1041 degrees of freedom
## ( 263 個の観測値が欠損のため削除されました )
## AIC: 992.45
##
## Number of Fisher Scoring iterations: 4
余裕がある履修者向けの宿題:プロビットと同様に対数尤度関数を書いて
optim
で最適化計算する.
logitmfx(formula = survived ~ sex + age + factor(pclass), data = titanic)
## Call:
## logitmfx(formula = survived ~ sex + age + factor(pclass), data = titanic)
##
## Marginal Effects:
## dF/dx Std. Err. z P>|z|
## sexmale -0.5514348 0.0293172 -18.8092 < 2.2e-16 ***
## age -0.0080960 0.0014881 -5.4405 5.312e-08 ***
## factor(pclass)2 -0.2673472 0.0404682 -6.6064 3.939e-11 ***
## factor(pclass)3 -0.4901785 0.0400797 -12.2301 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## dF/dx is for discrete change for the following variables:
##
## [1] "sexmale" "factor(pclass)2" "factor(pclass)3"
余裕がある履修者向けの宿題:プロビットと同様に(mfx::logitmfx
関数を使わずに)計算する.
演習では扱わないが,興味がある履修者は 自動車保有の離散選択問題:Conditional logit を試してみよう.
3つ以上の選択肢から1つを選ぶ問題も上記を一般化して定式化・推定できることが分かるだろう.
.