LoginSignup
8
13

More than 5 years have passed since last update.

一元配置分散分析

Last updated at Posted at 2014-04-24

昨日は回帰分析について触れましたが、問題に応じて最適な手法を選択し適用することはデータ分析においてとても大切です。そのためには各種の分析手法について理解を深めなくてはなりません。

データを入手したとき、分布を仮定するためにいくつか分析したいことがあります。たとえばデータの変動を水準間変動と残差変動に分解し水準間で有意差があるかどうか検定する。変量間の関係から回帰式を導く。計数データを水準毎に分割する。それらが有意であるかどうか検定する。観測値の順位を用いて、母集団分布に依らないノンパラメトリック検定をする。といったものです。

分散分析

分散分析は言うなれば検定の一種で、一元配置分散分析では 1 つの要因 A の複数の水準 A_1, A_2, ... A_a に関して各水準の母平均に差があるか検定します。

次のようなデータを考えてみます。一元配置のデータです。

水準 観測値 標本平均
A_1 x_11 ... x1r \overline{x}_1
... ... ...
A_a x_a1 ... x_ar \overline{x}_a

各水準 A_i の平均は i = 1, ... , a としたとき

\overline{x}_i = \frac 1 r \sum_{j=1}^rx_{ij}

となります。また総平均は

\frac 1 {ar} \sum_{i=1}^a \sum_{j=1}^r x_{ij}

です。

各水準の観測値の個数は等しく r としても良いですが一元配置の場合は水準ごとに異なることも許されます。

ここでひとつの仮説検定が必要になります。

仮説 内容
帰無仮説 水準間の相違は無関係なランダム変動にすぎず有意性は無い
対立仮説 標本平均の相違が母平均はすべて等しいと言えないほど大きい

データの構造式を次式の通りとします。

x_{ij} = \mu + \alpha_i + \epsilon_{ij} \\
ただし \\
\sum_{i=1}^a \alpha_i = 0 \\
\epsilon_{ij} は互いに正規分布 N(0, \sigma^2) に従う

水準間平方和を S_A 、残差平方和を S_e としたとき、 S_A と S_e の確率分布を考えます。不偏分散と同様の考え方により総平方和 S_r の自由度は次式で得られます。

\phi_c = \phi_r - \phi_A = ar - a

F 間が自由度 (\phi_A ・ \phi_e) の F 分布の上側 α 点より大きいならば帰無仮説は有意水準 α で棄却されます。

import numpy as np

data = np.array([[  5.,   7.,  12.],
                 [  6.,   5.,  10.],
                 [  3.,   4.,   8.],
                 [  2.,   4.,   6.]])

s_mean = np.zeros(data.shape)

for i in range(data.shape[1]):
    s_mean[:,i] = data[:,i].mean()

print( "水準平均 " + str(s_mean) )

kouka = s_mean - np.ones(data.shape)*data.mean()

print( "水準間偏差(因子の効果) := 水準平均 - 全体平均 " + str(kouka) )

Q1 = (kouka * kouka).sum()
print( "水準間変動(効果の偏差平方和(SS)) " + str(Q1) )

f1 = data.shape[1] - 1
print( "自由度 " + str(f1) )

V1 = Q1 / f1
print ("水準間偏差(効果)の平均平方(MS)(不変分散) " + str(V1) )

error = data - s_mean
print( "水準内偏差(統計誤差) " + str(error) )

Q2 = (error * error).sum()
print( "誤差の偏差平方和(SS) " + str(Q2) )

f2 = ( data.shape[0] - 1 ) * data.shape[1]
print( "自由度(DF) " + str(f2) )

V2 = Q2 / f2
print( "水準内偏差(誤差)の平均平方(MS)(不変分散) " + str(V2) )

F = V1 / V2
print( "分散比(F値) " + str(F) )

# =>
#水準平均 [[ 4.  5.  9.]
# [ 4.  5.  9.]
# [ 4.  5.  9.]
# [ 4.  5.  9.]]
#水準間偏差(因子の効果) := 水準平均 - 全体平均 [[-2. -1.  3.]
# [-2. -1.  3.]
# [-2. -1.  3.]
# [-2. -1.  3.]]
#水準間変動(効果の偏差平方和(SS)) 56.0
#自由度 2
#水準間偏差(効果)の平均平方(MS)(不変分散) 28.0
#水準内偏差(統計誤差) [[ 1.  2.  3.]
# [ 2.  0.  1.]
# [-1. -1. -1.]
# [-2. -1. -3.]]
#誤差の偏差平方和(SS) 36.0
#自由度(DF) 9
#水準内偏差(誤差)の平均平方(MS)(不変分散) 4.0
#分散比(F値) 7.0

参考

分散分析(analysis of variance 略称 ANOVA)
http://www.agri.tohoku.ac.jp/iden/toukei7.html

Numpy で分散分析
http://mkacky.wordpress.com/2013/05/22/numpy%E3%81%A7%E5%88%86%E6%95%A3%E5%88%86%E6%9E%90/

日本統計学会公式認定 統計検定1級対応 統計学
http://www.amazon.co.jp/dp/448902150X

8
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
13