Help us understand the problem. What is going on with this article?

分布と検定

分布

乱数と一様分布

まずは、一様乱数を発生させて、その分布を図示してみましょう。

# 乱数を扱うためのライブラリをインポートする。
import random
sample_size = 10 # 乱数発生回数

# 一様乱数を dist に格納する (distribution : 分布)
dist = [random.random() for i in range(sample_size)]
# dist の中身を確認する。
dist
# 図やグラフを図示するためのライブラリをインポートする。
import matplotlib.pyplot as plt
%matplotlib inline
# ヒストグラムを描く。
plt.hist(dist)
plt.grid()
plt.show()

乱数発生回数を増やしてみる

乱数発生回数を多くするにしたがって、"理想的な" 分布の形に近づいていきます。

sample_size = 100 # 乱数発生回数

# 一様乱数を dist に格納する
dist = [random.random() for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist)
plt.grid()
plt.show()
sample_size = 1000 # 乱数発生回数

# 一様乱数を dist に格納する
dist = [random.random() for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist)
plt.grid()
plt.show()
sample_size = 10000 # 乱数発生回数

# 一様乱数を dist に格納する
dist = [random.random() for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist)
plt.grid()
plt.show()
sample_size = 100000 # 乱数発生回数

# 一様乱数を dist に格納する
dist = [random.random() for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist)
plt.grid()
plt.show()

binを増やしてみる

ゴミを分別するのに使う箱のことを bin と言います。ヒストグラムを描く時は、いくつの bin に分別するかで表示が違ってきます。binの数を多くすると、分布の細かい形が見えますが、ひとつのbinあたり分別されたデータ数は当然少なくなります。

sample_size = 100000 # 乱数発生回数

# 一様乱数を dist に格納する
dist = [random.random() for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist, bins=100) # binを多くする
plt.grid()
plt.show()

二項分布

np.random.binomial(n, p) は、確率pで奇数が出る(確率1-pで偶数が出る)ルーレットをn回プレイしたときに、奇数が出る個数を返します。このような分布を、二項分布と言います。

等確率の二項分布

奇数と偶数が等確率で出るルーレットを10回プレイし、奇数が出る回数を数えます。それを10000回繰り返します。奇数と偶数が同じ回数だけ出る確率(5回ずつ出る確率)はどのくらいでしょうか。

# 数値計算のライブラリをインポートする。
import numpy as np
sample_size = 10000 # 乱数発生回数

# 確率pで奇数が出る(確率1-pで偶数が出る)ルーレットをn回プレイしたときに、
# 奇数が出る回数の分布
dist = [np.random.binomial(n=10, p=0.5) for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist, bins=100)
plt.grid()
plt.show()

上図から分かるように、奇数と偶数が等確率で出るルーレットを10回プレイして、奇数と偶数が同じ回数だけ出る確率(5回ずつ出る確率)は、約25%(10000回中の約2500回)ほどです。案外少ない、という印象を持つかもしれませんね。

そのルーレットはイカサマか

あなたはカジノで他の客がルーレットをプレイしているのを観察していました。すると、奇数の出る回数がやけに多いので、そのルーレットはイカサマではないかという気がしてきました。イカサマでなければ、ルーレットは奇数と偶数が等確率で出るはずです。ところがこのルーレットは、100回中60回、奇数が出ました。このルーレットはイカサマでしょうか。

奇数と偶数が等確率で出るルーレットを100回プレイした時、奇数が出る回数が60回以上になる確率はどれくらいでしょうか。まずは分布を描いてみましょう。

sample_size = 10000 # 乱数発生回数

# 確率pで奇数が出る(確率1-pで偶数が出る)ルーレットをn回プレイしたときに、
# 奇数が出る回数の分布
dist = [np.random.binomial(n=100, p=0.5) for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist, bins=100)
plt.grid()
plt.show()

上と同様の計算で、今度は「ルーレットを100回プレイして奇数が60回以上出る確率」を計算してみます。

sample_size = 10000 # 乱数発生回数

# 確率pで奇数が出る(確率1-pで偶数が出る)ルーレットをn回プレイしたときに、
# 奇数が出る回数の分布
dist = [np.random.binomial(n=100, p=0.5) for i in range(sample_size)]

p = sum([1 for n in dist if n >= 60]) / sample_size
print("p値: %(p)s " %locals())

奇数と偶数が等確率で出るルーレットを100回プレイして、奇数が出る回数が「偶然」60回以上になる確率は 5% 以下になることが分かりました。つまり、100回中60回以上奇数が出るようなルーレットは、そのルーレットがイカサマだと疑ってみるのが良さそうです。

このときのpを、p値(有意確率)と呼びます。

  • 帰無仮説:そのルーレットはイカサマではない(奇数と偶数が等確率で出る)。
  • 対立仮説:そのルーレットはイカサマである。
  • p < 0.05 なので、有意水準5%で、帰無仮説を棄却できる。
  • すなわち、そのルーレットはイカサマである可能性が高い。

課題1

100回中60回以上奇数が出るようなルーレットは、そのルーレットがイカサマだと疑ってみるのが良さそうです。では、10回中6回以上奇数が出た場合、奇数が出た確率は同じ60%ですが、そのルーレットはイカサマと言えるでしょうか。p値を計算して答えてください。

# 課題1

等確率でない二項分布

全住民の5%がある感染症に罹患したと推定されている。その全住民の中から無作為に20人を抽出した場合、抽出された集団の中に罹患者は何人いるでしょうか。そのような分布も二項分布になります。分布を描いてみましょう。

sample_size = 10000 # 乱数発生回数

# 確率pで奇数が出る(確率1-pで偶数が出る)ルーレットをn回プレイしたときに、
# 奇数が出る回数の分布
dist = [np.random.binomial(n=20, p=0.05) for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist, bins=100)
plt.grid()
plt.show()

課題2

全住民の5%がある感染症に罹患したと推定されている。その全住民の中から無作為に100人を抽出したところ、抽出された集団の中に罹患者が10人以上いた。

(1) それが偶然起こる確率を概算しなさい。

(2) その結果をどう解釈すれば良いか。

# 課題2

正規分布

random.normalvariate(mu, sigma) は正規分布に従う乱数を発生させる関数です(mu は平均で、sigma は標準偏差)。

標準正規分布

平均0、標準偏差1の正規分布を「標準正規分布」と言います。標準正規分布を描いてみましょう。

sample_size = 10000 # 乱数発生回数

dist = [random.normalvariate(mu=0, sigma=1) for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist, bins=100)
plt.grid()
plt.show()

標準正規分布に従う乱数が2以上の値を出力する確率はどのくらいでしょうか。計算してみましょう。

sample_size = 10000 # 乱数発生回数

dist = [random.normalvariate(mu=0, sigma=1) for i in range(sample_size)]

p = sum([1 for n in dist if n >= 2]) / sample_size
print("p値: %(p)s " %locals())

偏差値

大学受験模試などでよく使われる「偏差値」は、平均50、標準偏差10の正規分布に従うという仮定をおいています。分布を描いてみましょう。ここで、縦軸は「学生数」をイメージしてください。

sample_size = 10000 # 乱数発生回数

# 平均50、標準偏差10の正規分布
dist = [random.normalvariate(mu=50, sigma=10) for i in range(sample_size)]

# ヒストグラムを描く。
plt.hist(dist, bins=100)
plt.grid()
plt.show()

課題3

偏差値70以上の学生は、1万人中、何人いると推定されるでしょうか。

# 課題3

検定

import numpy as np # 数値計算を行うライブラリ
import scipy as sp # 科学計算ライブラリ
from scipy import stats # 統計計算ライブラリ

カイ2乗検定

カイ2乗検定は、2つの分布が同じかどうかを検定するときに用いる手法です。

サイコロを60回ふり、各目が出た回数を数えたところ、次のようになりました。

サイコロの目
出現回数 17 10 6 7 15 5

このとき、理論値の分布(一様分布)に従うかどうかを検定してみましょう。

significance = 0.05
o = [17, 10, 6, 7, 15, 5] # 実測値
e = [10, 10, 10, 10, 10, 10] # 理論値

chi2, p = stats.chisquare(o, f_exp = e)

print('chi2 値は %(chi2)s' %locals())
print('確率は %(p)s' %locals())

if p < significance:
    print('有意水準 %(significance)s で、有意な差があります' %locals())
else:
    print('有意水準 %(significance)s で、有意な差がありません' %locals())
chi2 値は 12.4
確率は 0.029699459203520212
有意水準 0.05 で、有意な差があります

課題4

ある野菜をA方式で育てたものとB方式で育てたものの出荷時の等級が次の表のようになったとき,これらの育て方と製品の等級には関連があると見るべきでしょうか。

A方式 12 30 58 100
B方式 14 90 96 200
26 120 154 300
# 課題4

対応のない t 検定

# 対応のないt検定
significance = 0.05
X = [68, 75, 80, 71, 73, 79, 69, 65]
Y = [86, 83, 76, 81, 75, 82, 87, 75]

t, p = stats.ttest_ind(X, Y)

print('t 値は %(t)s' %locals())
print('確率は %(p)s' %locals())

if p < significance:
    print('有意水準 %(significance)s で、有意な差があります' %locals())
else:
    print('有意水準 %(significance)s で、有意な差がありません' %locals())
t 値は -3.214043146821967
確率は 0.006243695014300228
有意水準 0.05 で、有意な差があります

課題5

6年1組と6年2組の2つのクラスで同一の算数のテストを行い、採点結果が出ました。2つのクラスで点数に差があるかどうか検定してください。

6年1組 点数 6年2組 点数
1 70 1 85
2 75 2 80
3 70 3 95
4 85 4 70
5 90 5 80
6 70 6 75
7 80 7 80
8 75 8 90
class_one = [70, 75, 70, 85, 90, 70, 80, 75]
class_two = [85, 80, 95, 70, 80, 75, 80, 90] 
# 課題5

対応のある t 検定

# 対応のあるt検定
significance = 0.05
X = [68, 75, 80, 71, 73, 79, 69, 65]
Y = [86, 83, 76, 81, 75, 82, 87, 75]

t, p = stats.ttest_rel(X, Y)

print('t 値は %(t)s' %locals())
print('確率は %(p)s' %locals())

if p < significance:
    print('有意水準 %(significance)s で、有意な差があります' %locals())
else:
    print('有意水準 %(significance)s で、有意な差がありません' %locals())
t 値は -2.9923203754253302
確率は 0.02016001617368161
有意水準 0.05 で、有意な差があります

課題6

国語と算数の点数に差があるかどうか検定してください。

6年1組 国語 算数
1 90 95
2 75 80
3 75 80
4 75 80
5 80 75
6 65 75
7 75 80
8 80 85
kokugo =   [90, 75, 75, 75, 80, 65, 75, 80]
sansuu = [95, 80, 80, 80, 75, 75, 80, 85]
# 課題6

分散分析

# 1要因の分散分析
significance = 0.05
a = [34, 39, 50, 72, 54, 50, 58, 64, 55, 62]
b = [63, 75, 50, 54, 66, 31, 39, 45, 48, 60]
c = [49, 36, 46, 56, 52, 46, 52, 68, 49, 62]
f, p = stats.f_oneway(a, b, c)

print('f 値は %(f)s' %locals())
print('確率は %(p)s' %locals())

if p < significance:
    print('有意水準 %(significance)s で、有意な差があります' %locals())
else:
    print('有意水準 %(significance)s で、有意な差がありません' %locals())
f 値は 0.09861516667148518
確率は 0.9064161716556407
有意水準 0.05 で、有意な差がありません

課題7

下記のデータを用いて、分散分析を行ってください。

group1 = [80, 75, 80, 90, 95, 80, 80, 85, 85, 80, 90, 80, 75, 90, 85, 85, 90, 90, 85, 80]
group2 = [75, 70, 80, 85, 90, 75, 85, 80, 80, 75, 80, 75, 70, 85, 80, 75, 80, 80, 90, 80]
group3 = [80, 80, 80, 90, 95, 85, 95, 90, 85, 90, 95, 85, 98, 95, 85, 85, 90, 90, 85, 85]
# 課題7

課題8

Twitter 上で行われた以下のアンケート結果の中から1つ選び、統計的検定を行いなさい。また、その結果について統計的に考察しなさい。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away