統計的推定

この内容は山田、杉澤、村井(2008)「R」によるやさしい統計学を参考にしています。

この講義では、「母集団と標本」をとりあげます。 これは、大きな集団から一部を取り出した少数のデータの情報を用いて、もとの集団の性質を推測する推測統計の基本的な理論の学習がねらいです。 特に 標本分布の理解を目的とします。

学習項目です

母集団と標本の関係

まず重要な用語をまとめておきましょう:

  • 母集団: 対象のデータ全体               
  • 標本: 母集団から一部のデータを取り出した(抽出した)もの                
  • 標本抽出: 母集団から標本をとりだすこと
  • 母数: 母集団の性質をあらわす統計的指数(比率、平均、分散、相関係数など) </UL> 例えば、日本の中学生全体のテスト得点データを母集団とすると、名古屋市昭和区の(一部の)中学生のテスト得点データが「標本」になります。そして、平均点や分散などが母数とみなせます。

推測統計

手元にある標本から母集団の性質(母数)を推測することを推測統計といいます。 推測統計は推定検定に分けられます。

「推定」は、母数の値に対し具体的な値を求める点推定、つまり一つの値で推定の結果を表すものと、区間推定、つまりある幅を持った区間で結果を表すものに分けられます。

また「検定」は母集団について述べた異なる立場の二つの主張(仮説)のうちどれを採用するかを決定するものです。例えば、日本の中学生のテスト得点が5年前と現在とで変化したという仮説と、変化していないという仮説がある場合、どちらを採択するかをきめるのが検定です。

点推定

母集団から抽出した標本を用いて、母数の点推定を行う手順についてみていきます。 ここで、標本のデータの個数のことをサンプルサイズ、 もしくは標本の大きさと言います。

例えば、10人の17歳男性の身長データがあるとします。これは日本人の17歳男性全体という『母集団』から抽出された『標本』とみなせます。そしてこのとき標本のデータの個数が10ですから、n = 10と書きます。ここでnはサンプルサイズを表す記号です。

In [10]:
import numpy as np
Height=np.array([165.2, 175.9, 161.7, 174.2, 172.1, 163.3, 170.6, 168.4, 171.3])

この標本から、「17歳の日本人男性全体の身長」(母集団)の平均(母数の一つ)を点推定してみましょう。 それには、次のようにします。ここで mean は、平均値を求めるメソッド(関数)でした。

In [11]:
print(Height.mean())
169.1888888888889

推定の基礎

まず用語を確認しましょう:

  • 標本統計量:標本データから計算される平均や分散などの値
  • 推定値:標本データを用いて計算した母数の推定量
母集団、標本、標本統計量、母数の関係を図で表すと以下のようになります: 母集団から抽出された標本データを分析し、標本統計量を得ます、それを使って母数を推定するのです

</A> </CENTER> ここで、標本統計量からどのように母数を推定するかを表にしておきましょう:

母数 推定量 関係する関数 オプション
母平均 標本平均 np.mean
母分散 不偏分散 np.var ddof=1
母標準偏差 不偏分散の正の平方根 np.std ddof=1
母相関係数 標本相関係数 np.corrcoef 対応する要素

練習問題 前項で例に出した「身長データ」を用いて、母集団の分散と標準偏差を点推定した値を求めよ。 またそれに用いたコードをあわせて答えよ。

In [12]:
# Exercise1 計算・解答用
# 母分散と母集団の標準偏差の点推定
Height.var(ddof=1), Height.std(ddof=1)
Out[12]:
(24.046111111111124, 4.903683422806893)
In [13]:
# 比較 (標本分散, 標準偏差)
# こちらのほうが小さい値になっている
Height.var(), Height.std()
Out[13]:
(21.374320987654333, 4.623237068078419)

標本抽出に伴う誤差

標本から推定値を得る手順よりも大事なこと:

  • 実際の母数の値にどの位近い推定値が得られるか?
  • 推定の結果はどのくらい信用できるか?

  • 標本誤差: 母数の値と推定値とのズレ--- データを沢山集めれば、生じうる誤差は小さくできる
  • 標本分布: どのような推定値が得られる可能性があるか、についての手がかり

推定値の信頼性を調べる方法

推定値を計算する元になる、標本に含まれる「個々のデータの値」の決定方法について見ていきましょう。

  1. 標本抽出の方法--- 単純無作為抽出と呼ばれる方法が前提
    • 単純無作為抽出: 母集団の中のどのデータにも平等に選ばれる可能性を持っているような標本抽出の方法
    • 無作為標本: 単純無作為抽出によって得られた標本
  2. 単純無作為抽出によって得られるデータの性質としての確率変数
    • 確率変数: 実際に結果が得られるまでどのような値が得られるかが決まっていない変数
      例: サイコロを振った時の出目
      同じ手続でデータを得ても結果に再現性がない⇒ 単純無作為抽出によって得られるデータは確率変数といえる
  3. 確率変数がどのような値をとるのかを示す確率分布
    • 確率変数の実現値:抽出の結果、確率変数がとる値
    • 確率分布: 確率変数がどのような値をどのような確率でとるかということを表した分布
    • 確率分布を用いた母集団の表現としての母集団分布
      • 母集団分布:ある変数の母集団における分布
        無作為抽出の場合、標本データの確率分布は母集団分布と同じになります
    • 代表的な母集団分布である正規分布
    • Pythonを使って正規分布の母集団から標本を抽出する方法

[参考: サイコロの出目の確率分布] 理論的には、サイコロの出目の確率分布はつぎのようになります:

サイコロの出る目 1 2 3 4 5 6
確率 1/6 1/6 1/6 1/6 1/6 1/6

それに対し、シミュレーションにより、サイコロの出る目の度数分布は次のようになりました: (1) 6回サイコロを振った場合:

サイコロの目 1 2 3 4 5 6
度数 0 2 1 1 0 2
相対度数 0 2/6 1/6 1/6 0 2/6

(2) 60,000回サイコロを振った場合:

サイコロの目 1 2 3 4 5 6
度数 10,097 9,918 9,936 9,960 10,050 10,039
相対度数 1.0097 0.9918 0.9936 0.9960 1.0050 1.0039
このように、非常に多くの実現値が得られれば、度数分布は確率分布とほぼ同じになります

正規分布

正規分布(normal distribution, ガウス分布 Gaussian distributionともいう)は統計学で最もよく用いられる確率分布なので、ここで復習しておこう

正規分布の表現方法: N (μ,σ2) --- μは平均値、σ2は分散 (σは標準偏差)

</A> </CENTER>

</TR> </TABLE>

  • 標準正規分布: 平均0 分散1の正規分布 --- N(0,1)
  • 離散変数: 整数など、とびとびの値をとる変数(例:サイコロの出目)
  • 連続変数: 実数値をとる変数(例:正規分布に従う確率変数)
  • 確率密度 : 正規分布の図の縦軸は確率密度
       確率密度×確率変数の範囲=確率
  • 確率密度関数:確率密度を確率変数の値の関数として表したもの 
正規分布の性質:
  • μ-σからμ+σ の範囲(偏差値で言えば、40点から60点の範囲)の確率はおよそ 0.683
  • μ-2σからμ+2σ の範囲(偏差値で言えば、30点から70点の範囲)の確率はおよそ 0.954
  • μ-3σからμ+3σ の範囲(偏差値で言えば、20点から80点の範囲)の確率はおよそ 0.997

</A></TD>

</A> </TD> </TR>

正規分布 N (0,1)のグラフ 正規分布 N (1,1) のグラフを重ね書き

</TABLE>

In [42]:
from scipy import stats as st
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-4, 4, 10000)
plt.plot(x, st.norm.pdf(x,0,1), label=r'$N(%i,%i)$' % (0,1))
plt.axis([-4,4,-0.02,0.5]) 
plt.axhline(0,c='g',ls='-.')
plt.axvline(-2,c='b',ls='--')
plt.axvline(2,c='b',ls='--')
x = np.linspace(-2, 2, 10000)
plt.fill_between(x, st.norm.pdf(x,0,1))
plt.legend()
plt.show()

正規母集団から単純無作為抽出を行う

正規母集団から単純無作為抽出を行う場合、特にサンプルサイズが小さいと、 確率変数が正規分布に従っているかどうかは標本データのヒストグラムを見てもわからない(左図)。 しかし大きなサイズになれば、ほぼ正規分布に従うことわかる(右図).

In [1]:
import numpy.random as random
?random.normal
In [106]:
samplesSmall = random.normal(50, 10.0, 10)  # N(50,10^2)に従う乱数を10個生成
samplesSmall
Out[106]:
array([ 33.09788212,  58.53310324,  46.89549989,  73.32767525,
        59.72873003,  57.4554278 ,  54.04003881,  35.12864043,
        40.43082595,  56.46944824])
In [107]:
plt.hist(samplesSmall)
plt.show()
In [108]:
samplesLarge = random.normal(50, 10.0, 10000)  # N(50,10^2)に従う乱数を10000個生成
plt.hist(samplesLarge)
plt.show()

標本分布

標本分布とは、標本統計量(標本平均、標本分散など)に関する確率分布のこと

標本分布は標本における個々のデータの実現値を表した度数分布ではなく、標本統計量の確率分布
標本分布は母集団分布と標本統計量の種類、そしてサンプルサイズが決まると理論的(数学的)に導かれる。 実際のデータから作成されるわけではない

標本分布から何がわかるのか

標本分布を調べることで、推定値の性質が分かる可能性がある


標本分布を調べるときの観点:

  1. 標本分布が母数の本当の値を中心として分布しているか⇒平均
  2. 標本分布が横に大きく広がっていないか⇒標準偏差
  (1)が満たされないと推定値と母数との誤差が大きくなる
  (2) は推定値にどの程度誤差が生じるか調べるもの

標本分布を「経験的」に求める

Pythonを用いて「経験的」に標本分布を求める方法---「経験的」とは「現実に得られたデータに基づく」という意味、 理論的な標本分布を「近似的」に再現


母集団からサンプルサイズnの標本を何度も繰り返し抽出し、そのたびに標本統計量の実現値を計算して記録する


これを実行するときの問題

  • 母集団分布がどのような分布になるかが不明  
  • 母集団分布がわからないと、標本から得られる推定値の信頼性も不明
    ⇒ 母集団が正規分布であると仮定して「もし母集団分布がこのような正規分布ならば、このくらいあてになる推定値が得られる」ということを検討

推定

ふたとおりの推定:

  • 点推定: 母数の『値』を推定する
  • 区間推定: 母数の値の範囲を『信頼係数』の値によって推定する

以下では点推定について述べる(後半で区間推定について述べる)

正規母集団の母平均の推定

仮定:母集団分布は$N(50,10^2)$、 サンプルサイズ n =10

In [109]:
samples = random.normal(50, 10.0, 10)  # N(50,10^2)に従う乱数を10個生成

samples # データの確認
Out[109]:
array([ 48.19415007,  63.26636104,  57.49745353,  39.96272656,
        51.64073697,  60.36259109,  58.71608459,  63.91610309,
        65.66073452,  45.49907224])
In [110]:
np.mean(samples)   # 平均
Out[110]:
55.471601370394922

この結果、母平均の推定値は(小数点1桁として) 55.5

母平均は50なので、推定値との差は 5.5 --- この差が標本誤差(誤差)

一回きりの標本抽出で推定値がどれくらいの誤差をもつかは、いろいろ

標本分布を求める

先の操作を10,000回繰り返してみよう:

In [44]:
import numpy as np
import numpy.random as random
meanArray = np.array([ np.mean(random.normal(50, 10.0, 10)) for _ in range(10000)])

こうして得られた標本平均のヒストグラムと母集団の正規分布とを、次のコードにより重ねあわせてみると、かなり近い関係にあることが分かります:

In [69]:
from scipy import stats as st
import matplotlib.pyplot as plt
%matplotlib inline

plt.hist(meanArray,density=True, ec='k')  # 頻度ではなく割合で表示
x = np.linspace(35, 65, 10000)
plt.plot(x, st.norm.pdf(x,50,10.0**0.5), ls='--',label=r'$N(%i,%i^2)$' % (50,10))
plt.grid()
plt.legend()
plt.show()

平均$\mu$、分散$\sigma^2$の正規分布 $N(\mu, \sigma^2)$に従う母集団からサンプルサイズ$n$の標本を抽出したとき、標本平均の標本分布は、理論的に$N(\mu, \sigma^2/n)$ に従います

誤差の絶対値が5以下、すなわち母平均の推定値が45以上、55以下の範囲で得られた回数を調べてみましょう:

In [113]:
# 45以上55以下のものを1それ以外を0としたリストを作り、そこで0でない(つまり1)の個数を数える
np.count_nonzero([1 if 45 <= x <= 55 else 0 for x in meanArray]) 
Out[113]:
8868

全体の89%は本当の母数±5に収まっていることがわかります。理論的にはこのデータは$N(50,10^2)$に従うので、次章の知識を先取りしscipy.statsモジュールの関数cdfを用いた理論的な値と比較してみましょう:

In [2]:
from scipy.stats import norm
?norm.cdf
In [63]:
norm.cdf(55, loc=50, scale=10.0**0.5) - norm.cdf(45,loc=50,scale=10.0**0.5)
Out[63]:
0.88615370199334187

このように、 上位二桁まで一致していることが確かめられました。

平均$\mu$、分散$\sigma^2$の正規分布 $N(\mu,\sigma^2)$ に従う母集団からサンプルサイズ$n$の標本を抽出したとき、標本平均の標本分布は、理論的に$N(\mu,\sigma^2/n)$に従うことは、次のようにして実験的に確かめることができます。

In [114]:
import numpy.random as random
for k in [50,60,70,80,90,100,150,200,250,300]:    # サンプルサイズを指定
     meanArray = np.array( [np.mean(random.normal(50, 10.0, k))
                           for _ in range(10000)])  # N(50,10^2)に従うk個の乱数の平均を10,000個
     print("サンプルサイズ=%d, 平均=%f, 標本分散=%f, 標本分散*サンプルサイズ=%f"
               % (k,meanArray.mean(), meanArray.var(),meanArray.var()*k))
サンプルサイズ=50, 平均=50.001157, 標本分散=2.018868, 標本分散*サンプルサイズ=100.943413
サンプルサイズ=60, 平均=49.989521, 標本分散=1.637274, 標本分散*サンプルサイズ=98.236410
サンプルサイズ=70, 平均=50.011332, 標本分散=1.432251, 標本分散*サンプルサイズ=100.257560
サンプルサイズ=80, 平均=50.002751, 標本分散=1.255702, 標本分散*サンプルサイズ=100.456120
サンプルサイズ=90, 平均=50.011754, 標本分散=1.103067, 標本分散*サンプルサイズ=99.276044
サンプルサイズ=100, 平均=49.991631, 標本分散=1.002772, 標本分散*サンプルサイズ=100.277168
サンプルサイズ=150, 平均=49.996742, 標本分散=0.664137, 標本分散*サンプルサイズ=99.620536
サンプルサイズ=200, 平均=50.005825, 標本分散=0.500871, 標本分散*サンプルサイズ=100.174264
サンプルサイズ=250, 平均=50.000568, 標本分散=0.405689, 標本分散*サンプルサイズ=101.422301
サンプルサイズ=300, 平均=49.997763, 標本分散=0.329371, 標本分散*サンプルサイズ=98.811296

以上の結果から、サンプルサイズを変えても標本平均の平均が母平均にほぼ一致すること、また標本平均の分散は、母分散/サンプルサイズであることが確かめられました。

不偏性

ある推定量の標本分布の平均(期待値)が、推定しようとしている母数の値と一致するとき、その推定量は不偏性があるといいます。また、 不偏性がある推定量のことを不偏推定量と言います。 推定量の不偏性は「標本分布が母数の本当の値を中心として分布しているか」に対応した概念です。

標準誤差

「推定量の標本分布の標準偏差(へんさ)」を標準誤差(ごさ)と言います。 これは「標本分布の横への広がり」を表す値です。標準誤差が小さいということは、 標本分布の広がりが小さいことを表し、これは『ばらつきが少ない』ことを意味します。

例: $N(50,10^2)$の正規母集団から n=10 の標本を抽出したとき、 標本平均の標本分布は$N(50,10^2/n)$に従うので、標準誤差は(n=10なので)$\sqrt{10^2/n}=\sqrt{10}$、つまり およそ3.2となります。 ということは、標本平均から母集団の平均を推定しようとすると、おおよそ68%の確率で46.8から53.2の間の値が得られますが、運が悪いと5以上の誤差が生じることがあることがわかります。

この例から、(1)母集団の分散(母分散)が大きければ大きいほど標本の平均値は母平均から離れた値を取りやすい(標準誤差が大きくなりやすい)、(2)標本のサイズが小さいほど標準誤差が大きい、ということがわかります。 言い換えれば、標準誤差を小さくするにはサンプルサイズnを大きくするのが有効な方法であると言えます。

一般に、どのような標本統計量でも、サンプルサイズが大きいほど標準誤差は小さくなります

中心極限定理: 母集団が正規分布でなくとも、標本平均の標本分布は「サンプルサイズnが大きい時」はほぼ正規分布になる

課題3-2

標本分布を求めるの項目ではn=10の標本を10,000個作り、その標本平均を求めた。 この課題ではn=100として10,000個の標本平均を求めてみよう。そしてn=10の場合のヒストグラムとn=100の場合のヒストグラムを比較し、標準誤差が小さくなっていることを確かめてみよ。

In [68]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy.random as random
# 計算・解答用
import numpy as np
SampleAverage10 = np.array([np.mean(random.normal(50, 10.0, 10)) for _ in range(10000)])
SampleAverage100 = np.array([np.mean(random.normal(50, 10.0, 100)) for _ in range(10000)])
plt.hist(SampleAverage10, color="yellow", ec='b')     # n=10の方を黄色で表示
plt.hist(SampleAverage100, color="green", ec='k')        # n=100の方を緑色で表示
plt.title('Histogram of sample average')
plt.xlabel('x')
plt.ylabel('Frequency')
plt.show()
print("std of sample10=%f, sample100=%f"%(SampleAverage10.std(), SampleAverage100.std()))
std of sample10=3.170615, sample100=1.002135
In [66]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import numpy.random as random
import scipy.stats as st

SampleAverage5 = np.array([np.mean(random.normal(0, 1, 25)) for _ in range(10000)])
SampleAverage4 = np.array([np.mean(random.normal(0, 1, 16)) for _ in range(10000)])
SampleAverage3 = np.array([np.mean(random.normal(0, 1, 9)) for _ in range(10000)])
SampleAverage2 = np.array([np.mean(random.normal(0, 1, 4)) for _ in range(10000)])
SampleAverage1 = np.array([np.mean(random.normal(0, 1, 1)) for _ in range(10000)])
x = np.linspace(-4,4, 10000) 

plt.hist(SampleAverage1,density=True, ec='k') 
plt.plot(x,st.norm.pdf(x,0,1.0/1),label=r'$N(0,1/1^2)$')# n=1
plt.hist(SampleAverage2,density=True, ec='k')   
plt.plot(x,st.norm.pdf(x,0,1.0/2),label=r'$N(0,1/2^2)$')# n=4
plt.hist(SampleAverage3,density=True, ec='k')  
plt.plot(x,st.norm.pdf(x,0,1.0/3),label=r'$N(0,1/3^2)$')# n=9
plt.hist(SampleAverage4,density=True, ec='k')  
plt.plot(x,st.norm.pdf(x,0,1.0/4),label=r'$N(0,1/4^2)$')# n=16
plt.hist(SampleAverage5,density=True, ec='k')  
plt.plot(x,st.norm.pdf(x,0,1.0/5),label=r'$N(0,1/5^2)$')# n=25
plt.title('Histogram of sample average')
plt.xlabel('x')
plt.ylabel('Frequency')
plt.legend()
plt.show()

標本平均以外の標本分布

「平均」以外の母数のうち、分散と中央値の標本分布について述べます。

標本分散と不偏分散の標本分布</H4>

母分散の推定量としての標本分散と不偏分散の違いを実験で示しましょう。

In [117]:
import numpy as np
import numpy.random as random

SampleVars = []
UnbiasedVars = []
for i in range(10000):
    Sample = random.normal(50, 10.0,10)  # N(50, 10^2)に従う乱数10個
    SampleVars = SampleVars+[Sample.var()]  # 標本分散
    UnbiasedVars = UnbiasedVars + [Sample.var(ddof=1.0)]

SampleVars = np.array(SampleVars)
UnbiasedVars = np.array(UnbiasedVars)

print(SampleVars.mean())
print(UnbiasedVars.mean())
90.2677729196
100.297525466

平均的に母分散の推定値として不偏分散のほうが近い値であることがわかります。次にその標準偏差を求めてみましょう。

In [118]:
print(SampleVars.std())
print(UnbiasedVars.std())
42.4670221473
47.1855801637

不偏分散のほうが推定値のばらつきが大きいことがわかります。

In [119]:
plt.subplot(2,2,1)
plt.hist(SampleVars)
plt.title(u'Sample Variance')
plt.subplot(2,2,2)
plt.hist(UnbiasedVars)
plt.title(u'Unbiased Variance')
plt.show()
In [120]:
plt.subplot(2,2,1)
plt.hist(SampleVars,bins=50)
plt.title(u'Sample Variance')
plt.subplot(2,2,2)
plt.hist(UnbiasedVars,bins=50)
plt.title(u'Unbiased Variance')
plt.show()
  • 不偏分散は不偏性をもつという点では望ましい性質をもっているが、 標本分散に比べて過大な推定値が得られる可能性が高い
  • 不偏分散の平方根は母標準偏差の不偏推定量ではない

中央値の標本分布</H4>

実験: 標本中央値の標本分布を求め、標本平均と比較する(どちらが母平均の推定量としてよいか?)

In [121]:
import numpy.random as random
SampleAverage = []
SampleMedian = []
for i in range(10000):
    Sample = random.normal(50, 10.0, 10)  # N(50, 10^2)に従う乱数10個
    SampleAverage = SampleAverage+[np.mean(Sample)]  # 標本平均
    SampleMedian = SampleMedian + [np.median(Sample)]   # 中央値

SampleAverage = np.array(SampleAverage)
SampleMedian = np.array(SampleMedian)
print(SampleAverage.mean())
print(SampleMedian.mean())
50.0321506814
50.0576939024

標本中央値も標本平均も母平均とほぼ一致---母平均の推定量としての候補として優劣が付けられない

In [122]:
print(np.std(SampleAverage))
print(np.std(SampleMedian))
3.15787180632
3.6923757235

標本平均のほうが標準誤差が小さい---標本平均は母平均の不偏推定量の中で</font>標準誤差が最小

In [123]:
plt.subplot(2,2,1)
plt.hist(SampleAverage,bins=50)
plt.title(u'Sample Mean')
plt.subplot(2,2,2)
plt.hist(SampleMedian,bins=50)
plt.title(u'Sample Median')
plt.show()

関数のまとめ

注: numpyをnp, np.randomを random、 matplotlib.pyplotをplt、pandasをpd、scipy.statsをstと略記する

</A></TD>

</A> </TD>

</A> </TD></TR>

μ-σからμ+σ の範囲μ-2σからμ+2σ の範囲μ-3σからμ+3σの範囲
目的 関数名とモジュール 使い方
一様分布に従う乱数(復習) random.random(個数) random.random(10) # [0,1)の乱数を10個
正規分布に従う乱数 random.normal(平均,標準偏差,個数) random.normal(50,10,10) # N(50, 10^2)に従う乱数10個
指定の範囲の数の生成 np.linspace(最小値,最大値,個数) np.linspace(35, 65, 10000) # [35,65]の範囲の数を10000個
正規分布の密度関数 st.norm.pdf(xデータ,平均,標準偏差) plt.plot(x, st.norm.pdf(x,50,10.0**0.5)) # $N(50,\sqrt{10})$の正規分布の関数描画


演習問題

演習問題1

$N(50,10^2)$の正規母集団から$n = 20$の標本抽出を5,000回繰り返すことにより、標本平均の経験的な標本分布を求めよ。またこの経験的な標本分布から得られるグラフ(ヒストグラム)に、理論的に導かれる標本分布を重ねあわせて表示せよ。

この結果下のようなグラフが得られればよい:

In [63]:
# 計算・解答用
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import numpy.random as random
import scipy.stats as st

data = np.array([np.mean([random.normal(50,10,20)]) for i in range(5000)])
In [64]:
plt.hist(data,color='y',density=True,bins=20, ec='k')
x = np.linspace(40, 60, 1000)  # x = np.arange(35,65,0.01)でもよい
plt.plot(x, st.norm.pdf(x,50,(100/20)**0.5), ls='--',label=r'$N(50,\frac{10^2}{20})$')
plt.xlabel('mean of samples')
plt.ylabel('Density')
plt.title('Histogram of means of samples')
plt.legend()
plt.plot()
Out[64]:
[]

演習問題2

理論的な標本分布について、サンプルサイズを$n=1, 4, 9, 16, 25$と変化させた時に、標本分布の形状がどのように代わるかを調べてみよ。ただし、母集団分布は標準正規分布$N(0, 1^2)$とする。


これによって次のような図が得られれば良い。

In [70]:
# 計算・解答用
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as st
In [72]:
x =  np.linspace(-3,3,1000)

for n in range(1,6):
    plt.plot(x,st.norm.pdf(x,0,(1/n)),label=r"$n=%i^2$"%(n)) 
plt.xlabel('x')
plt.ylabel('norm(x,0,np.sqrt(1/n))')
plt.legend()
plt.show()
In [33]:
?plt.plot

演習問題3

最小値0、最大値100の一様分布から$n=20$の標本抽出を5,000回繰り返すことにより、標本平均の経験的な標本分布を求めよ。中心極限定理からこれは正規分布に近づくはずである。そこでこのヒストグラムに、標本平均データの平均と標準偏差による正規分布のグラフを重ねせて表示せよ。
この結果、次のようなグラフが得られればよい:

In [61]:
# 計算・解答用
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import numpy.random as random
import scipy.stats as st

data = np.array([np.mean(random.random(20)*100) for i in range(5000)])
In [62]:
plt.hist(data,color='y',density=True,bins=20,ec='k')
x = np.linspace(25, 75, 1000)  # x = np.arange(35,65,0.01)でもよい
plt.plot(x, st.norm.pdf(x,50,(10000/(12*20))**0.5), ls='--',label=r'$N(50,\frac{100^2}{12*20})$')
plt.ylabel('Density')
plt.xlabel('Mean of samples')
plt.title('Histogram of means of samples')
plt.legend()
plt.plot()
Out[62]:
[]

区間推定

この項は次の書籍を参考にしている: 馬場孝之(2014)『統計学キャンパスゼミ』マセマ

  • 予備知識:
    • 信頼係数とは、母数の推定において、ある区間のなかに母数が入っている確率が1に十分近い値$1-\alpha$になるようにしたときの値。またこの$\alpha$は(本来は『検定」の用語である)有意水準に対応する
    • 逆に$\alpha$を有意水準とすると、$1-\alpha$は信頼係数。$\alpha$として1%や5%を用いることが慣習的
    • 区間推定とは、推定する母数$\theta$に対し、$P(\theta_1 \leq \theta \leq \theta_2) = 1-\alpha$を満たす信頼区間$\theta_1$と$\theta_2$の値を求めるもの

以下は、正規分布$N(\mu, \sigma^2)$に従う母集団から無作為抽出した標本$X_1, X_2, \ldots, X_n$に対する推定についてのみ述べる。$\bar{X}=\frac{1}{n}\sum_{i=1}^n X_i$とする。

  • 中心極限定理(復習)
    • 互いに独立な$n$個の確率変数$X_1, X_2, \ldots,X_n$が平均$\mu$, 分散$\sigma^2$の同一の確率分布に従うとき、 $\bar{X}=\frac{1}{n} (X_1+X_2+\cdots+X_n)$(つまり$\bar{X}$はその平均)は$n\rightarrow \infty$のとき 正規分布$N(\mu, \sigma^2/n)$に従う
    • そして$\bar{X}$を標準化した確率変数$Z=\frac{\bar{X}-\mu}{\sigma/\sqrt{n}}$は、$n \rightarrow \infty$のとき標準正規分布$N(0,1)$に従う
  • 正規分布$N(\mu, \sigma^2)$:復習
    • 平均値$\mu=0$、分散$\sigma^2=1$の正規分布を標準正規分布と呼ぶ。これは、正規分布に従う確率変数$X$を標準化: $Z=\frac{X-\mu}{\sigma}$ した変数が従う分布である。
    • 互いに独立な$n$個の確率変数$X_1, X_2, \ldots,X_n$がすべて同一の正規分布$N(\mu,\sigma^2)$に従うとき、 $\bar{X}=\frac{1}{n} (X_1+X_2+\cdots+X_n)$(つまり$\bar{X}$はその平均)は正規分布$N(\mu, \sigma^2/n)$に従う。 (注:中心極限定理と違い、$n \rightarrow \infty$が不要であることに注意)
In [25]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
# Gaussian : N(0,1)
def Gaussian (x):
    return (np.exp(-x**2/2)) / np.sqrt(2*np.pi) 

#  [-6.0, 6.0] の区間で等差数列を作成
x = np.linspace(-6.0, 6.0, 10000)

# f(x)の結果を得る: [Gaussian(-6.0),...,Gaussian(6.0)]
y = [Gaussian(i) for i in x]

# グラフに表示
plt.plot(x,y)
plt.axis([-6,6,-0.02,0.45])  # 描画範囲を指定する x:[-6.0,6.0], y:[-0.02, 0.45]
plt.title("standard normal distribution: N(0,1)")
plt.grid()
  • ここで取り上げる区間推定は、母集団が正規分布$N(\mu,\sigma^2)$に従うもので、そこから無作為に抽出した標本$X_1, X_2, \ldots, X_n$の母数を区間推定するもの。
    • 推定する母数が平均値か分散か、また$\sigma^2$が既知か未知か、で条件が異なる

$\sigma^2$が既知のときの母平均$\mu$の推定

  • 母集団が正規分布$N(\mu,\sigma^2)$に従い($\mu$は未知、$\sigma^2$は既知)、そこから無作為に抽出した標本$X_1, X_2, \ldots, X_n$から$\mu$を推定する
  • $\bar{X}=\frac{1}{n}\sum_{i=1}^n X_i$とするーーー正規分布の性質から$\bar{X}$は$N(\mu, \frac{\sigma^2}{n})$に従う
  • 新たな確率変数$Z=\frac{\bar{X}-\mu}{\sqrt{\sigma^2/n}}$を定義すると$Z$は$N(0,1)$に従う($Z \sim N(0,1)$とも書ける)
  • これを用いて、標準正規分布のpercent point関数(Pythonではscipy.stats.norm.ppf関数)ppf(x)を用いると、 $$P(-{\rm ppf}(\frac{\alpha}{2}) \leq Z \leq {\rm ppf}(\frac{\alpha}{2})) = 1-\alpha$$

であるから信頼区間$(1-\alpha)$を満たすには $$-{\rm ppf}(\frac{\alpha}{2}) \leq \frac{\bar{X}-\mu}{\sqrt{\sigma^2/n}} \leq {\rm ppf}(\frac{\alpha}{2})$$ これから、$\bar{X} - {\rm ppf}(\frac{\alpha}{2})\sqrt{\frac{\sigma^2}{n}} \leq \mu \leq \bar{X} +{\rm ppf}(\frac{\alpha}{2})\sqrt{\frac{\sigma^2}{n}}$

  • 参考: ppf(0.025)=-1.96, ppf(1-0.025)=1.96
In [49]:
from scipy import stats as st
import matplotlib.pyplot as plt
import numpy as np

lower=st.norm.ppf(0.025)
upper=st.norm.ppf(1-0.025)
x = np.linspace(-4, 4, 10000)
plt.plot(x, st.norm.pdf(x,0,1), label=r'$N(%i,%i)$' % (0,1))
plt.axis([-4,4,-0.02,0.5]) 
plt.axhline(0,c='g',ls='-.')
plt.axvline(lower,c='b',ls='--')
plt.axvline(upper,c='b',ls='--')
x = np.linspace(lower, upper, 10000)
plt.fill_between(x, st.norm.pdf(x,0,1),color="green")
plt.legend()
plt.title("95% confidence interval")
Out[49]:
Text(0.5, 1.0, '95% confidence interval')
In [3]:
# 標準正規分布のppf関数の0.025(2.5%)と0.975(97.5%)点
import scipy.stats as st
print("ppf(0.025)={:5.3f}, ppf(0.975)={:5.3f}".format(st.norm.ppf(0.025),st.norm.ppf(1-0.025)))
ppf(0.025)=-1.960, ppf(0.975)=1.960

練習問題2-1

$N(\mu, 16)$に従う母集団から9個の標本$X_1,X_2,\cdots,X_9$を無作為抽出したところ、その標本平均は$\bar{X}=10.0$であった。これから、母平均$\mu$の95%信頼区間を求める。

In [1]:
from scipy import stats as st
import matplotlib.pyplot as plt
import numpy as np
# 有意水準
alpha=0.05
# 標本平均のサイズ
n=9
# 標本平均
xBar=10.0
# 母分散
var=16
# ppf(alpha/2) * (var/n)**0.5
print(st.norm.ppf(0.025)*(var/n)**0.5)
print(st.norm.ppf(0.975)*(var/n)**0.5)
-2.6132853127200724
2.613285312720072
In [2]:
# 以上から
print("{:6.3f}<=μ<={:6.3f}".format(xBar+st.norm.ppf(0.025)*(var/n)**0.5, xBar+st.norm.ppf(0.975)*(var/n)**0.5))
 7.387<=μ<=12.613

問題: 上と同じ状況において、母平均μの99%信頼区間を求めよ。

In [3]:
# 計算
print("{:6.3f}<=μ<={:6.3f}".format(xBar+st.norm.ppf(0.005)*(var/n)**0.5, xBar+st.norm.ppf(0.995)*(var/n)**0.5))
 6.566<=μ<=13.434

練習問題2-2

$N(\mu, 25)$に従う母集団から16個の標本$X_1,X_2,\cdots,X_{16}$を無作為抽出したところ、その標本平均は$\bar{X}=63.0$であった。これから、母平均$\mu$の95%信頼区間を求めよ。

In [4]:
# 計算
# 有意水準
alpha=0.05
# 標本平均のサイズ
n=16
# 標本平均
xBar=63.0
# 母分散
var=25
# 以上から
print("{:6.3f}<=μ<={:6.3f}".format(xBar+st.norm.ppf(0.025)*(var/n)**0.5, xBar+st.norm.ppf(0.975)*(var/n)**0.5))
60.550<=μ<=65.450

確率分布の復習

  • $\chi^2$分布

    互いに独立な$n$個の確率変数$X_1, X_2, \ldots,X_n$が標準正規分布$N(0,1)$に従うとき、その2乗和$Z=X_1^2+\cdots+X_n^2$は、自由度$n$の$\chi^2$分布に従う

  • $t$分布

    2つの独立な確率変数$X$と$Y$があり、$X$は標準正規分布$N(0,1)$に、$Y$は自由度$n$の$\chi^2$分布に従うとき、$Z=\frac{X}{\sqrt{Y/n}}$とすると、$Z$は自由度$n$の$t$分布に従う

$\sigma^2$が未知のときの母平均$\mu$の推定

  • 母集団が正規分布$N(\mu,\sigma^2)$に従い($\mu$も$\sigma^2$も未知)、そこから無作為に抽出した標本$X_1, X_2, \ldots, X_n$から$\mu$を推定する
  • $\bar{X}=\frac{1}{n}\sum_{i=1}^n X_i$とするーーー正規分布の性質から$\bar{X}$は$N(\mu, \frac{\sigma^2}{n})$に従うが、$\sigma^2$は未知!
  • 標本の不偏分散$S^2$を母分散$\sigma^2$の代わりに用いる。確率変数$Z=\frac{\bar{X}-\mu}{\sqrt{S^2/n}}$を定義すると $Z$は 自由度$n-1$のt分布に従う

その根拠:

  • $Z=\frac{ \frac{\bar{X}-\mu}{\sqrt{\sigma^2/n}}}{\sqrt{S^2/\sigma^2}}$と書き換える
  • ここで、$X=\frac{\bar{X}-\mu}{\sqrt{\sigma^2/n}}$とおくと$Z=\frac{X}{\sqrt{S^2/\sigma^2}}$と書け、$X$は$N(0,1)$に従う
  • $Y = (n-1)\cdot\frac{S^2}{\sigma^2}$ とおくと(つまり$\frac{S^2}{\sigma^2}=\frac{Y}{n-1}$)、 $Z=\frac{X}{\sqrt{Y/(n-1)}}$の形になる
  • $S^2$は不偏分散であるから $$Y=\frac{n-1}{\sigma^2}S^2 = \frac{n-1}{\sigma^2}\cdot \frac{1}{n-1}\sum_{i=1}^n (X_i-\bar{X})^2 = \sum_{i=1}^n \left( \frac{X_i-\bar{X}}{\sigma}\right)^2$$
  • $\frac{X_i - \bar{X}}{\sigma}$は$X_i$の標準化と呼ばれるもの、これは$N(0,1)$に従う
  • したがって$Y$はこの2乗和であるから、$Y$は($\frac{X_i-\bar{X}}{\sigma}$は線形従属なので自由度が$n$より1減って) 自由度$n-1$の$\chi^2$分布に従う
  • 分散が既知の場合と同様、信頼区間$1-\alpha$とすると、 $t$分布のpercent point関数(Pythonではscipy.stats.t.ppf(x,自由度)、以下ではt.ppfと表す)を用いて $$\bar{X} - {\rm t.ppf}(\frac{\alpha}{2},n-1)\sqrt{\frac{S^2}{n}} \leq \mu \leq \bar{X} +{\rm t.ppf}(\frac{\alpha}{2},n-1)\sqrt{\frac{S^2}{n}}$$
In [5]:
# 自由度9のときの2.5%点と97.5%点
import scipy.stats as st
print("t.ppf(0.025,3)={:5.3f}, t.ppf(0.975,3)={:5.3f}".format(st.t.ppf(0.025,3),st.t.ppf(1-0.025,3)))
print("t.ppf(0.025,9)={:5.3f}, t.ppf(0.975,9)={:5.3f}".format(st.t.ppf(0.025,9),st.t.ppf(1-0.025,9)))
print("t.ppf(0.025,100)={:5.3f}, t.ppf(0.975,100)={:5.3f}".format(st.t.ppf(0.025,100),st.t.ppf(1-0.025,100)))
t.ppf(0.025,3)=-3.182, t.ppf(0.975,3)=3.182
t.ppf(0.025,9)=-2.262, t.ppf(0.975,9)=2.262
t.ppf(0.025,100)=-1.984, t.ppf(0.975,100)=1.984
In [6]:
# 作図
%matplotlib inline
from scipy import stats as st
import numpy as np
import matplotlib.pyplot as plt

fig,ax = plt.subplots(1,1)
x = np.linspace(-6, 6, 10000)
linestyles = [':', '--', '-.','-']
deg_of_freedom = [1,3,9,100]
for df, ls in zip(deg_of_freedom, linestyles):
  ax.plot(x, st.t.pdf(x, df), linestyle=ls, label=r'$df=%i$' % df)

plt.xlabel('$t$')
plt.ylabel('$f(t)$')
plt.title('t-Distribution')
plt.axis([-6,6,-0.02,0.6]) 
plt.legend()
plt.grid()

練習問題3-1

$N(\mu, \sigma^2)$に従う母集団から10個の標本を無作為抽出したところ、その値は9.8, 10.3, 11.9, 8.7, 9.5, 10.2, 10.9,8.2, 9.4, 10.5であった。これから、母平均$\mu$の95%信頼区間を求める。

In [7]:
# 自由度7のt分布のppf関数の0.025と0.975に対する値
import scipy.stats as st
import numpy as np

# 標本
Xs = np.array([9.8, 10.3, 11.9, 8.7, 9.5, 10.2, 10.9,8.2, 9.4, 10.5])
N=Xs.size
# 平均
xBar=Xs.mean()
N,xBar
Out[7]:
(10, 9.940000000000001)
In [13]:
# 自由度
ddof=N-1
# 不偏分散
var=Xs.var(ddof=1)
var
Out[13]:
1.149333333333334
In [9]:
# t.ppf(alpha/2,ddof) * (var/n)**0.5
print(st.t.ppf(0.025,ddof)*(var/N)**0.5)
print(st.t.ppf(0.975,ddof)*(var/N)**0.5)
-0.7669124274167254
0.7669124274167253
In [10]:
# 以上から
print("{:6.3f}<=μ<={:6.3f}".format(xBar+st.t.ppf(0.025,ddof)*(var/N)**0.5, xBar+st.t.ppf(0.975,ddof)*(var/N)**0.5))
 9.173<=μ<=10.707
In [8]:
%matplotlib inline
from scipy import stats as st
import numpy as np
import matplotlib.pyplot as plt

lower=st.t.ppf(0.025,ddof)
upper=st.t.ppf(0.975,ddof)
df=ddof
x = np.linspace(-6, 6, 10000)
plt.plot(x, st.t.pdf(x, df))

plt.xlabel('$t$')
plt.ylabel('$f(t)$')
plt.title('t-Distribution')
plt.axis([-6,6,-0.02,0.6]) 
plt.axvline(lower,c='yellow',ls='--')
plt.axvline(upper,c='orange',ls='--')
plt.axhline(0,c='k',ls='-')
x = np.linspace(lower, upper, 10000)
plt.fill_between(x, st.t.pdf(x,df),color="green")
plt.grid()

問題: 上と同じ状況において、母平均μの99%信頼区間を求めよ。

In [12]:
# 標本
Xs = np.array([9.8, 10.3, 11.9, 8.7, 9.5, 10.2, 10.9,8.2, 9.4, 10.5])
N=Xs.size
# 平均
xBar=Xs.mean()

# 自由度
ddof=N-1
# 不偏分散
var=Xs.var(ddof=1)

print("{:6.3f}<=μ<={:6.3f}".format(xBar+st.t.ppf(0.005,ddof)*(var/N)**0.5, xBar+st.t.ppf(0.995,ddof)*(var/N)**0.5))
 8.838<=μ<=11.042

練習問題3-2

ある一年間の新生児から8名の体重を無作為抽出した結果が以下である:(単位はkg)

2.82, 3.01, 3.24, 3.16, 3.34, 3.57, 2.98, 3.28

全国の新生児の体重を母集団とし、それが正規分布に従うと仮定したとき、母平均の95%信頼区間を推定せよ。

In [16]:
Xs=np.array([2.82, 3.01, 3.24, 3.16, 3.34, 3.57, 2.98, 3.28])

N=Xs.size
# 平均
xBar=Xs.mean()

# 自由度
ddof=N-1
# 不偏分散
var=Xs.var(ddof=1)

print("Xbar = {:6.3f}".format(xBar))
print("{:6.3f}<=μ<={:6.3f}".format(xBar+st.t.ppf(0.025,ddof)*(var/N)**0.5, xBar+st.t.ppf(0.975,ddof)*(var/N)**0.5))
Xbar =  3.175
 2.978<=μ<= 3.372

母分散$\sigma^2$の推定($\mu$も未知)

  • 母集団が正規分布$N(\mu,\sigma^2)$に従い($\mu$も$\sigma^2$も未知)、そこから無作為に抽出した標本$X_1, X_2, \ldots, X_n$から$\sigma^2$を推定する
  • $V=\sum_{i=1}^n (\frac{X_i-\bar{X}}{\sigma})^2$とすると(前述から)$V$は自由度$n-1$の$\chi^2$分布に従う。このことから$\sigma^2$の区間推定を行う
  • $\chi^2$分布のpercent point関数(Pythonではscipy.stats.chi2.ppf(x,自由度), 以下ではchi2.ppfと表す)を用いて $$ P(chi2.{\rm ppf}(1-\frac{\alpha}{2},n-1) \leq V \leq chi2.{\rm ppf}(\frac{\alpha}{2},n-1)) = 1-\alpha$$より、 $$chi2.{\rm ppf}(1-\frac{\alpha}{2},n-1) \leq \sum_{i=1}^n (\frac{X_i-\bar{X}}{\sigma})^2 \leq chi2.{\rm ppf}(\frac{\alpha}{2},n-1)$$
  • ここで標本からの不偏分散$S^2 = \frac{1}{n-1}\sum_{i=0}^n (X_i - \bar{X}^2)$を用いると $$V=\sum_{i=1}^n (\frac{X_i-\bar{X}}{\sigma})^2=\frac{n-1}{\sigma^2} \cdot \frac{1}{n-1}\sum_{i=0}^n (X_i-\bar{X})^2 = \frac{n-1}{\sigma^2} S^2$$
  • 以上から、$\frac{(n-1)S^2}{chi2.{\rm ppf}(\frac{\alpha}{2},n-1)} \leq \sigma^2 \leq \frac{(n-1)S^2}{chi2.{\rm ppf}(1-\frac{\alpha}{2},n-1)}$

練習問題4-1

$𝑁(\mu,\sigma^2)$に従う母集団から10個の標本を無作為抽出したところ、その値は9.8, 10.3, 11.9, 8.7, 9.5, 10.2, 10.9,8.2, 9.4, 10.5であった。これから、母分散$\sigma^2$の95%信頼区間を求める。

In [17]:
# 自由度7のt分布のppf関数の0.025と0.975に対する値
import scipy.stats as st
import numpy as np

# 標本
Xs = np.array([9.8, 10.3, 11.9, 8.7, 9.5, 10.2, 10.9,8.2, 9.4, 10.5])
N=Xs.size
# 平均
xBar=Xs.mean()
N,xBar
Out[17]:
(10, 9.940000000000001)
In [18]:
# 自由度
ddof=N-1
# 不偏分散
var=Xs.var(ddof=1)
var
Out[18]:
1.149333333333334
In [19]:
# chi2.ppf(alpha/2,ddof) 
print(st.chi2.ppf(0.025,ddof))
print(st.chi2.ppf(0.975,ddof))
2.7003894999803584
19.02276779864163
In [21]:
# 以上から
print(" σ**2={:6.3f}".format(var))
print("{:6.3f}<=σ**2<={:6.3f}".format(var*ddof/st.chi2.ppf(0.975,ddof), var*ddof/st.chi2.ppf(0.025,ddof)))
 σ**2= 1.149
 0.544<=σ**2<= 3.831
In [22]:
%matplotlib inline
from scipy import stats as st
import numpy as np
import matplotlib.pyplot as plt

df=ddof
upper=st.chi2.ppf(0.025,ddof)
lower=st.chi2.ppf(0.975,ddof)
x = np.linspace(0, 20, 10000)
plt.plot(x, st.chi2.pdf(x, df))

plt.xlabel('$\chi^2$')
plt.ylabel(r'$f(\chi^2)$')
plt.title(r'$\chi^2\ \mathrm{Distribution}$')
plt.axis([-0.2,20,-0.02,0.2]) 
plt.axvline(lower,c='yellow',ls='--')
plt.axvline(upper,c='orange',ls='--')
plt.axhline(0,c='k',ls='-')
x = np.linspace(lower, upper, 10000)
plt.fill_between(x, st.chi2.pdf(x,df),color="green")
plt.grid()

問題: 上と同じ状況において、母分散の99%信頼区間を求めよ。

In [23]:
print(" σ**2={:6.3f}".format(var))
print("{:6.3f}<=σ**2<={:6.3f}".format(var*ddof/st.chi2.ppf(0.995,ddof), var*ddof/st.chi2.ppf(0.005,ddof)))
 σ**2= 1.149
 0.439<=σ**2<= 5.962

練習問題4-2

ある一年間の新生児から8名の体重を無作為抽出した結果が以下である:(単位はkg)

2.82, 3.01, 3.24, 3.16, 3.34, 3.57, 2.98, 3.28

全国の新生児の体重を母集団とし、それが正規分布に従うと仮定したとき、母分散の95%信頼区間を推定せよ。

In [26]:
Xs=np.array([2.82, 3.01, 3.24, 3.16, 3.34, 3.57, 2.98, 3.28])
N=Xs.size
# 平均
xBar=Xs.mean()
# 自由度
ddof=N-1
# 不偏分散
var=Xs.var(ddof=1)

# 以上から

print(" xBar={:6.3f}".format(xBar))
print("{:6.3f}<=μ<={:6.3f}".format(xBar+st.t.ppf(0.025,ddof)*(var/N)**0.5, xBar+st.t.ppf(0.975,ddof)*(var/N)**0.5))

print(" σ**2={:6.3f}".format(var))
print("{:6.3f}<=σ**2<={:6.3f}".format(var*ddof/st.chi2.ppf(0.975,ddof), var*ddof/st.chi2.ppf(0.025,ddof)))
 xBar= 3.175
 2.978<=μ<= 3.372
 σ**2= 0.056
 0.024<=σ**2<= 0.231
In [ ]: