OLS推定量の標準誤差¶
ある推定量の漸近分布(asymptotic distribution、大標本において推定量が近似的に従う分布)の標準偏差を標準誤差(standard error)という。
重回帰モデル
y=β0+β1x1+⋯+βdxd+ε において、各k=0,1,…,dについて、回帰係数βkのOLS推定量β^kは、中心極限定理により十分大きなnのもとで
Z=sn(β^k−βk) が近似的に標準正規分布N(0,1)に従う。
ここでsは標本標準偏差に相当するもの。
上記の式は書き換えると
β^k=βk+ns⋅Z となる。ここで
σ=ns とおけば、β^kは平均βk、分散σ2の正規分布N(βk,σ2)に従うということになる。
別の定義では、残差をu^とするとβ^1の分散は
σ^β^12=n1[n1∑i=1n(xi−xˉ)2]2n−21∑i=1n(xi−xˉ)2u^i2 で、SE(β^1)=σ^β^12となる
誤差項εiの分散σ2が既知かつ均一分散のとき
Var[β^]=∑(Xi−Xˉ)2σ2 分散が既知かつ不均一分散のとき
Var[β^]het=[∑(Xi−Xˉ)2]2∑(Xi−Xˉ)2σi2 (『統計的因果推論の理論と実装』p.118)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
import statsmodels.formula.api as smf
beta = [10, 5]
def gen_data(n = 300, random_state=0):
np.random.seed(random_state)
x = np.random.uniform(size=n)
y = beta[0] + x * beta[1] + np.random.normal(size=n)
return x, y
estimates = []
for seed in range(1000):
x, y = gen_data(n = 100, random_state=seed)
df = pd.DataFrame(dict(x=x, y=y))
beta1 = sum((x - x.mean()) * (y - y.mean())) / sum((x - x.mean())**2)
estimates.append(beta1)
estimates = np.array(estimates)
fig, ax = plt.subplots()
ax.hist(estimates, bins=20)
ax.axvline(beta[1], color="gray", label=r"True $\beta_1$")
ax.set(title=r"Distribution of $\hat{\beta}_1$", xlabel=r"$\hat{\beta}_1$")
ax.legend()
from myst_nb import glue
glue("dist_beta_fig", fig, display=False)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
import statsmodels.formula.api as smf
from scipy.stats import norm
beta = [10, 5]
def gen_data(n = 300, random_state=0):
np.random.seed(random_state)
x = np.random.uniform(size=n)
y = beta[0] + x * beta[1] + np.random.normal(size=n)
return x, y
def se_beta(x, residuals):
n = len(x)
sqd = (x - np.mean(x)) ** 2
df = 2
nu = (1 / (n - df)) * np.sum( sqd * (residuals ** 2) )
de = ( (1 / n) * np.sum(sqd) ) ** 2
var = (1 / n) * (nu) / (de)
return np.sqrt(var)
fig, ax = plt.subplots()
estimates = []
se_list = []
for seed in range(100):
x, y = gen_data(n = 300, random_state=seed)
df = pd.DataFrame(dict(x=x, y=y))
model = smf.ols('y ~ x', data=df).fit()
beta1 = model.params["x"]
se_beta1 = se_beta(x, residuals=model.resid)
x_plot = np.linspace(4, 6, 50)
y_plot = norm.pdf(x=x_plot, loc=beta1, scale=se_beta1)
ax.plot(x_plot, y_plot, alpha=.5)
estimates.append(beta1)
se_list.append(se_beta1)
estimates = np.array(estimates)
ax.hist(estimates, bins=10)
ax.axvline(beta[1], color="gray", label=r"True $\beta_1$")
ax.set(title=r"Distribution of $\hat{\beta}_1$", xlabel=r"$\hat{\beta}_1$")
ax.legend()
from myst_nb import glue
glue("dist_beta_fig", fig, display=False)
# CI
ci = (
beta1 - 1.96 * se_beta1,
beta1 + 1.96 * se_beta1
)
fig, ax = plt.subplots()
x_plot = np.linspace(4, 6, 50)
y_plot = norm.pdf(x=x_plot, loc=beta1, scale=se_beta1)
ax.plot(x_plot, y_plot, alpha=.5)
ax.axvline(ci[0])
ax.axvline(ci[1])
# import numpy as np
# import pandas as pd
# n = 300
# beta = [10, 5]
# np.random.seed(0)
# x = np.random.uniform(size=n)
# df = pd.DataFrame({
# "x": x,
# "y": beta[0] + x * beta[1] + np.random.normal(size=n)
# })
# # df.plot.scatter(x="x", y="y")
# import statsmodels.api as sm
# import statsmodels.formula.api as smf
# from stargazer.stargazer import Stargazer
# models = [
# smf.ols('y ~ x', data=df).fit(),
# ]
# Stargazer(models)
OLS推定量のt検定¶
帰無仮説と対立仮説をそれぞれ
H0:βk=0H1:βk=0 とする。t統計量を
t=σβ^k=snβ^k と定義すると、これは標準正規分布N(0,1)に従う。∣t∣>1.96となればその確率は5%以下であるため有意水準5%で帰無仮説を棄却できる。
t検定のp値¶
帰無仮説H0:βk=0を棄却するためには有意水準をどこまで引き上げなければいけないかを考える。
N(0,1)に従うZを用いて、P(∣Z∣>∣t∣)を計算する
OLS推定量の信頼区間¶
β^kの漸近分布がN(βk,σk2)に従うとする。nが十分に大きいときは、
Zk=σkβ^k−βk はN(0,1)に従うものとみなすことができて、
P(∣Zk∣≤1.96)=P(−1.96≤σkβ^k−βk≤1.96)=0.95 と近似できる。そこから95%信頼区間は
β^k−1.96σk≤βk≤β^k+1.96σk となる
回帰の標準誤差¶
回帰の標準誤差(standard error of the regression: SER)は、回帰誤差εの標準偏差の推定量
SER=su^, su^=n−d−11i=1∑nu^i2 (u^の平均はゼロであるため、通常の分散の式における平均で引くような項が存在していない)
ここでdは推定している傾きのパラメータ数(定数項も含めればd+1)。下方バイアスが生じることがわかっているので自由度のぶんだけ修正する。