【統計学入門(東京大学出版会)】第12章 練習問題 解答
東京大学出版会から出版されている統計学入門(基礎統計学Ⅰ)について第12章の練習問題の解答を書いていく。
本章以外の解答
本章以外の練習問題の解答は別の記事で公開している。
必要に応じて参照されたい。
12.1
標本平均を 、母平均を 、標本分散を 、標本数を とすると、
は、自由度 のスチューデントのt分布に従うことを利用する。
帰無仮説を 、対立仮説を とすると、
を満たすときに、有意水準5%で母平均が100gと考えてよいと判断できる。
これをPythonのプログラムによって確認する。
import numpy as np from math import sqrt from scipy.stats import t x = np.array([101.1, 103.2, 102.1, 99.2, 100.5, 101.3, 99.7, 100.5, 98.9, 101.4]) n = x.size x_bar = x.mean() s2 = np.sum((x - x_bar)**2) / (n - 1) mu = 100 criteria = (x_bar - mu) / sqrt(s2 / n) rejection = t.ppf(q=1-0.025, df=n-1) print("Rejection: t < {} or {} < t, Criteria: {}, {}".format(-rejection, rejection, criteria, "Rejected" if abs(criteria) > rejection else "Accepted"))
上記のプログラムを実行すると、
Rejection: t < -2.2621571627409915 or 2.2621571627409915 < t, Criteria: 1.8909240092503048, Accepted
が得られ、母平均100gは有意水準5%で棄却されない。
12.2
i)
標本間の母分散が同じであるから、2標本の標本分散を とすると、
は、自由度が のスチューデントのt分布に従う。
なお、男の給与の標本平均を 、標本数を 、母平均を とし、女の給与の標本平均を 、標本数を 、母平均を とする。 なお標本間の母分散が同じであるから、2標本の標本分散 は、
となる。
帰無仮説を 、対立仮説を とすると、
を満たすときに、有意水準5%で男女の賃金格差が存在しないと考えてよいと判断できる。
これをPythonのプログラムによって確認する。
import numpy as np from math import sqrt from scipy.stats import t x = np.array([15.4, 18.3, 16.5, 17.4, 18.9, 17.2, 15.0, 15.7, 17.9, 16.5]) y = np.array([14.2, 15.9, 16.0, 14.0, 17.0, 13.8, 15.2, 14.5, 15.0, 14.4]) m = x.size n = y.size x_bar = x.mean() y_bar = y.mean() s = sqrt((np.sum((x - x_bar)**2) + np.sum((y - y_bar)**2)) / (m + n - 2)) criteria = (x_bar - y_bar) / (s * sqrt(1 / m + 1 / n)) rejection = t.ppf(q=1-0.025, df=m+n-2) print("Rejection: t < {} or {} < t, Criteria: {}, {}".format(-rejection, rejection, criteria, "Rejected" if abs(criteria) > rejection else "Accepted"))
上記のプログラムを実行すると、
Rejection: t < -2.10092204024096 or 2.10092204024096 < t, Criteria: 3.606503775109937, Rejected
が得られ、男女の賃金格差が存在しないことは有意水準5%で棄却される。すなわち、男女の賃金格差が存在する。
ii)
男の給与の標本平均を 、標本分散を 、標本数を 、母平均を とし、女の給与の標本平均を 、標本分散を 、標本数を 、母平均を とする。
標本間の分散が等しくない場合、
は、スチューデントのt分布に従う(ウェルチの検定)。
なお自由度 は、
となる。
帰無仮説を 、対立仮説を とすると、
を満たすときに、有意水準5%で男女の賃金格差が存在しないと考えてよいと判断できる。
これをPythonのプログラムによって確認する。
import numpy as np from math import sqrt from scipy.stats import t from decimal import Decimal, ROUND_HALF_UP x = np.array([15.4, 18.3, 16.5, 17.4, 18.9, 17.2, 15.0, 15.7, 17.9, 16.5]) y = np.array([14.2, 15.9, 16.0, 14.0, 17.0, 13.8, 15.2, 14.5, 15.0, 14.4]) m = x.size n = y.size x_bar = x.mean() y_bar = y.mean() s12 = (np.sum((x - x_bar)**2)) / (m - 1) s22 = (np.sum((y - y_bar)**2)) / (n - 1) nu = (s12 / m + s22 / n)**2 / ((s12 / m)**2 / (m-1) + (s22 / n)**2 / (n-1)) nu = int(Decimal(str(nu)).quantize(Decimal('0'), rounding=ROUND_HALF_UP)) criteria = (x_bar - y_bar) / sqrt(s12 / m + s22 / n) rejection = t.ppf(q=1-0.025, df=nu) print(f"nu: {nu}") print("Rejection: t < {} or {} < t, Criteria: {}, {}".format(-rejection, rejection, criteria, "Rejected" if abs(criteria) > rejection else "Accepted"))
上記のプログラムを実行すると、
nu: 17 Rejection: t < -2.1098155778331806 or 2.1098155778331806 < t, Criteria: 3.606503775109937, Rejected
が得られ、男女の賃金格差が存在しないことは有意水準5%で棄却される。すなわち、男女の賃金格差が存在する。
iii)
男の給与の標本分散を 、標本数を 、母分散を とし、女の給与の標本分散を 、標本数を 、母分散を とする。
このとき、
は、自由度が のF分布に従う。
帰無仮説を 、対立仮説を とすると、
を満たすときに、有意水準1%で男女の賃金の母分散が等しいと判断できる。
これをPythonのプログラムによって確認する。
import numpy as np from scipy.stats import f x = np.array([15.4, 18.3, 16.5, 17.4, 18.9, 17.2, 15.0, 15.7, 17.9, 16.5]) y = np.array([14.2, 15.9, 16.0, 14.0, 17.0, 13.8, 15.2, 14.5, 15.0, 14.4]) m = x.size n = y.size s12 = (np.sum((x - x_bar)**2)) / (m - 1) s22 = (np.sum((y - y_bar)**2)) / (n - 1) criteria = s12 / s22 rejection = f.ppf(q=1-0.005, dfn=m-1, dfd=n-1) print("Rejection: F > {}, Criteria: {}, {}".format(rejection, criteria, "Rejected" if criteria > rejection else "Accepted"))
上記のプログラムを実行すると、
Rejection: F > 6.541089626853058, Criteria: 1.5635220125786158, Accepted
が得られ、男女の賃金の母分散が等しいことは有意水準1%で棄却されない。
12.3
治療法が有効か否かを判断するためには、治療後に血圧測定値が下がっていることを確認すればよい。 したがって、治療前後の血圧測定値の差の平均を としたときに、帰無仮定 、対立仮定 として検定する。
このために、
が自由度 のスチューデントのt分布に従うことを利用する。 ここで、標本平均を 、標本分散を 、標本数を とした。
を満たすときに帰無仮定が棄却され、有意水準1%で治療前後の血圧測定値の差があり、治療の効果があると判断できる。
これをPythonのプログラムによって確認する。
import numpy as np from math import sqrt from scipy.stats import t x = np.array([2, -5, -4, -8, 3, 0, 3, -6, -2, 1, 0, -4]) n = x.size x_bar = x.mean() s2 = np.sum((x - x_bar)**2) / (n - 1) mu = 0 criteria = (x_bar - mu) / sqrt(s2 / n) rejection = t.ppf(q=1-0.01, df=n-1) print("Rejection: t < {}, Criteria: {}, {}".format(-rejection, criteria, "Rejected" if criteria < -rejection else "Accepted"))
上記のプログラムを実行すると、
Rejection: t < -2.7180791835355564, Criteria: -1.560009076442849, Accepted
が得られ、帰無仮定は棄却されない。 このため、有意水準1%で治療前後の血圧測定値の差がないと判断でき、治療の効果がないと言える。
12.4
仮定された理論上での確率分布の適合度の検定であるから、適合度の 検定を用いる。 すなわち、観測度数を 、理論確率を とする。
なお表より は、
数字 | |
---|---|
1 | 10 |
2 | 7 |
3 | 8 |
4 | 11 |
5 | 6 |
6 | 8 |
である。
が自由度 の 分布に従うことを利用すると、
を満たすときに、有意水準5%でさいころが正しく作られていないと判断できる。
これをPythonのプログラムによって確認する。
import numpy as np from scipy.stats import chi2 f = np.array([10, 7, 8, 11, 6, 8]) n = np.sum(f) p = 1 / 6 criteria = np.sum((f - n * p) ** 2 / (n * p)) rejection = chi2.ppf(q=1-0.05, df=f.size-1) print("Rejection: chi2 > {}, Criteria: {}, {}".format(rejection, criteria, "Rejected" if criteria > rejection else "Accepted"))
上記のプログラムを実行すると、
Rejection: chi2 > 11.070497693516351, Criteria: 2.0800000000000005, Accepted
が得られ、有意水準5%でさいころが正しく作られていると言える。
12.5
i)
仮定された理論上での確率分布の適合度の検定であるから、適合度の 検定を用いる。 すなわち、観測度数を 、理論確率を とする。
が自由度 の 分布に従うことを利用すると、
を満たすときに、有意水準5%で0~9の値が等確率で出現するという仮説は棄却される。
これをPythonのプログラムによって確認する。
import numpy as np from scipy.stats import chi2 import random random.seed(1) idx = random.randint(0, 1000 - 100) pi_str = """ 3. 1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179 3105118548 0744623799 6274956735 1885752724 8912279381 8301194912 9833673362 4406566430 8602139494 6395224737 1907021798 6094370277 0539217176 2931767523 8467481846 7669405132 0005681271 4526356082 7785771342 7577896091 7363717872 1468440901 2249534301 4654958537 1050792279 6892589235 4201995611 2129021960 8640344181 5981362977 4771309960 5187072113 4999999837 2978049951 0597317328 1609631859 5024459455 3469083026 4252230825 3344685035 2619311881 7101000313 7838752886 5875332083 8142061717 7669147303 5982534904 2875546873 1159562863 8823537875 9375195778 1857780532 1712268066 1300192787 6611195909 2164201989 """ pi_str = pi_str.replace(" ", "").replace("\n", "").replace(".", "")[idx:idx+100] napier_str = """ 2. 7182818284 5904523536 0287471352 6624977572 4709369995 9574966967 6277240766 3035354759 4571382178 5251664274 2746639193 2003059921 8174135966 2904357290 0334295260 5956307381 3232862794 3490763233 8298807531 9525101901 1573834187 9307021540 8914993488 4167509244 7614606680 8226480016 8477411853 7423454424 3710753907 7744992069 5517027618 3860626133 1384583000 7520449338 2656029760 6737113200 7093287091 2744374704 7230696977 2093101416 9283681902 5515108657 4637721112 5238978442 5056953696 7707854499 6996794686 4454905987 9316368892 3009879312 7736178215 4249992295 7635148220 8269895193 6680331825 2886939849 6465105820 9392398294 8879332036 2509443117 3012381970 6841614039 7019837679 3206832823 7646480429 5311802328 7825098194 5581530175 6717361332 0698112509 9618188159 3041690351 5988885193 4580727386 6738589422 8792284998 9208680582 5749279610 4841984443 6346324496 8487560233 6248270419 7862320900 2160990235 3043699418 4914631409 3431738143 6405462531 5209618369 0888707016 7683964243 7814059271 4563549061 3031072085 1038375051 0115747704 1718986106 8739696552 1267154688 9570350354 """ napier_str = napier_str.replace(" ", "").replace("\n", "").replace(".", "")[idx:idx+100] pi_f = [] for i in range(10): pi_f.append(pi_str.count(str(i))) pi_f = np.array(pi_f) napier_f = [] for i in range(10): napier_f.append(napier_str.count(str(i))) napier_f = np.array(napier_f) n = 100 p = 1 / 10 rejection = chi2.ppf(q=1-0.05, df=10-1) pi_criteria = np.sum((pi_f - n * p)**2 / (n * p)) napier_criteria = np.sum((napier_f - n * p)**2 / (n * p)) print("Rejection: chi2 > {}".format(rejection)) print("pi: {}, {}".format(pi_criteria, "Reject" if pi_criteria > rejection else "Accept")) print("napier: {}, {}".format(napier_criteria, "Reject" if napier_criteria > rejection else "Accept"))
上記のプログラムを実行すると、
Rejection: chi2 > 16.918977604620448 pi: 5.4, Accept napier: 6.4, Accept
が得られ、有意水準5%で0~9の値が等確率で出現するという仮説は棄却されない。 すなわち、円周率 、自然数の底 の小数点以下1000桁から選んだ100桁は0から9の値が等確率で出現していると言える。
ii)
桁数を1001とすることを除いて、i)と同様のことを行う。
import numpy as np from scipy.stats import chi2 pi_str = """ 3. 1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179 3105118548 0744623799 6274956735 1885752724 8912279381 8301194912 9833673362 4406566430 8602139494 6395224737 1907021798 6094370277 0539217176 2931767523 8467481846 7669405132 0005681271 4526356082 7785771342 7577896091 7363717872 1468440901 2249534301 4654958537 1050792279 6892589235 4201995611 2129021960 8640344181 5981362977 4771309960 5187072113 4999999837 2978049951 0597317328 1609631859 5024459455 3469083026 4252230825 3344685035 2619311881 7101000313 7838752886 5875332083 8142061717 7669147303 5982534904 2875546873 1159562863 8823537875 9375195778 1857780532 1712268066 1300192787 6611195909 2164201989 """ pi_str = pi_str.replace(" ", "").replace("\n", "").replace(".", "") napier_str = """ 2. 7182818284 5904523536 0287471352 6624977572 4709369995 9574966967 6277240766 3035354759 4571382178 5251664274 2746639193 2003059921 8174135966 2904357290 0334295260 5956307381 3232862794 3490763233 8298807531 9525101901 1573834187 9307021540 8914993488 4167509244 7614606680 8226480016 8477411853 7423454424 3710753907 7744992069 5517027618 3860626133 1384583000 7520449338 2656029760 6737113200 7093287091 2744374704 7230696977 2093101416 9283681902 5515108657 4637721112 5238978442 5056953696 7707854499 6996794686 4454905987 9316368892 3009879312 7736178215 4249992295 7635148220 8269895193 6680331825 2886939849 6465105820 9392398294 8879332036 2509443117 3012381970 6841614039 7019837679 3206832823 7646480429 5311802328 7825098194 5581530175 6717361332 0698112509 9618188159 3041690351 5988885193 4580727386 6738589422 8792284998 9208680582 5749279610 4841984443 6346324496 8487560233 6248270419 7862320900 2160990235 3043699418 4914631409 3431738143 6405462531 5209618369 0888707016 7683964243 7814059271 4563549061 3031072085 1038375051 0115747704 1718986106 8739696552 1267154688 9570350354 """ napier_str = napier_str.replace(" ", "").replace("\n", "").replace(".", "") pi_f = [] for i in range(10): pi_f.append(pi_str.count(str(i))) pi_f = np.array(pi_f) napier_f = [] for i in range(10): napier_f.append(napier_str.count(str(i))) napier_f = np.array(napier_f) n = 1001 p = 1 / 10 rejection = chi2.ppf(q=1-0.05, df=9) pi_criteria = np.sum((pi_f - n * p)**2 / (n * p)) napier_criteria = np.sum((napier_f - n * p)**2 / (n * p)) print("Rejection: chi2 > {}".format(rejection)) print("pi: {}, {}".format(pi_criteria, "Reject" if pi_criteria > rejection else "Accept")) print("napier: {}, {}".format(napier_criteria, "Reject" if napier_criteria > rejection else "Accept"))
上記プログラムを実行すると、
Rejection: chi2 > 16.918977604620448 pi: 4.7842157842157835, Accept napier: 4.804195804195803, Accept
が得られ、有意水準5%で0~9の値が等確率で出現するという仮説は棄却されない。 すなわち、円周率 、自然数の底 の最初から1001桁は0から9の値が等確率で出現していると言える。
12.6
喫煙習慣の有無と死亡率の独立性を検定するため、 検定を行う。 喫煙習慣の度数を とし、死亡率の度数を とすると、
となるが、この に対して、
のとき と は関連していることになり、独立でなくなる。 なお、自由度は である。
この判定をPythonのプログラムによって行う。
import numpy as np from scipy.stats import chi2 f = np.array([[950, 117], [348, 54]]) n = np.sum(f) criteria = 0 for i in range(len(f)): for j in range(len(f[0])): fij = f[i, j] fi = np.sum(f, axis=1)[i] fj = np.sum(f, axis=0)[j] criteria += (n * fij - fi * fj)**2 / (n * fi * fj) rejection = chi2.ppf(q=1-0.05, df=1) print("Rejection: chi2 > {}, Criteria: {}, {}".format(rejection, criteria, "Related" if criteria > rejection else "Not related"))
上記のプログラムを実行すると、
Rejection: chi2 > 3.841458820694124, Criteria: 1.728463379862236, Not related
が得られ、有意水準5%で と が関連していない(独立である)ことがわかる。 したがって、喫煙習慣と死亡率には関連がないと言える。
12.7
12.6と同様である。
肥沃度の有無と所有関係が独立か否かを検定するため、 検定を行う。 所有関係の度数を とし、肥沃度の度数を とすると、
となるが、この に対して、
のとき と は関連していることになり、独立でなくなる。 なお、自由度は である。
この判定をPythonのプログラムによって行う。
import numpy as np from scipy.stats import chi2 f = np.array([[36, 31, 58], [67, 60, 87], [49, 49, 80]]) n = np.sum(f) criteria = 0 for i in range(len(f)): for j in range(len(f[0])): fij = f[i, j] fi = np.sum(f, axis=1)[i] fj = np.sum(f, axis=0)[j] criteria += (n * fij - fi * fj)**2 / (n * fi * fj) rejection = chi2.ppf(q=1-0.05, df=4) print("Rejection: chi2 > {}, Criteria: {}, {}".format(rejection, criteria, "Related" if criteria > rejection else "Not related"))
上記のプログラムを実行すると、
Rejection: chi2 > 9.487729036781154, Criteria: 1.5431365561546417, Not related
が得られ、有意水準5%で と が関連していない(独立である)ことがわかる。 したがって、肥沃度の有無と所有関係には関連がないと言える。
12.8
i)
Aの度数を とし、Bの度数を とすると、独立性の 検定の基準は、
で表すことができる。
したがって、
とすると、
が得られる。
ii)
Pythonのプログラムによって求める。
n = 30 x = 9 y = 12 z = 4 u = 5 before_correction = n * (x * u - y * z)**2 / ((x + z) * (y + u) * (x + y) * (z + u)) after_correction = n * (x * u - y * z + n / 2)**2 / ((x + z) * (y + u) * (x + y) * (z + u)) print("Before correction: {}, After correction: {}".format(before_correction, after_correction))
上記のプログラムを実行すると、
Before correction: 0.006464124111182934, After correction: 0.10342598577892695
が得られる。
12.9
が標準正規分布に従うから、
を満たすとき、有意水準5%で男女に知能検査の合格率の差がないと言える。
これをPythonのプログラムによって求める。
from math import sqrt from scipy.stats import norm n1 = 102 n2 = 101 p1 = 18 / n1 p2 = 8 / n2 p = 26 / (n1+n2) criteria = (p1 - p2) / sqrt((1/n1 + 1/n2) * p * (1 - p)) rejection = norm.ppf(q=1-0.025, loc=0, scale=1) print("Rejection: |z| > |{}|, Criteria: {}, {}".format(rejection, criteria, "Equal" if abs(criteria) < abs(rejection) else "Not equal"))
上記のプログラムを実行すると、
Rejection: |z| > |1.959963984540054|, Criteria: 2.073393155507257, Not equal
が得られ、男女に知能検査の合格率の差があると言える。
12.10
z変換、
より、 が標準正規分布に従うことから、
これをPythonプログラムで確認する。
from math import sqrt, log from scipy.stats import norm r = 0.6387815655787518 z = log((1+r) / (1-r)) / 2 n = 47 rejection = norm.ppf(q=1-0.025, loc=0, scale=1) no_str = ["i)", "ii)"] for i, rho in enumerate([0, 0.5]): eta = log((1+rho) / (1-rho)) / 2 criteria = sqrt(n - 3) * (z - eta) print("{} Rejection: |z| > |{}|, Criteria: {}, {}".format(no_str[i], rejection, criteria, "Accept" if abs(criteria) < abs(rejection) else "Reject"))
上記のプログラムを実行すると、
i) Rejection: |z| > |1.959963984540054|, Criteria: 5.015484383021951, Reject ii) Rejection: |z| > |1.959963984540054|, Criteria: 1.3717996314362153, Accept
となり、i)の は棄却され、ii) の は棄却されない。