Pythonで統計学を学ぶ(6)

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

なお、滋賀医科大学の小山先生のページはとてもよくまとまっていて、お勧めです。

この講義では、「分散分析」のうち、「一元配置分散分析」をとりあげます。 前回のt検定では2つの群の平均値を比較しましたが、分散分析は3つ以上の群の平均値を比較したり、ある条件の違いによって母平均が異なるかを検定します。

学習項目です:


分散分析(ANOVA, Analysis Of Variance) とは、3つ以上の群の平均値差の検定や、条件(の組み合わせ)の違いによって母平均が異なるかどうかを検定する方法です (注意:「分散」という名前に惑わされないように)

データにおいて変数がとる値は、以下の『要因』によるものと「誤差」によるものがあるとみなせます:

  • 要因: 母平均に違いをもたらす原因     
  • 水準: ある要因の中に含まれる個々の条件

そして、 「データ全体のばらつき」は、『要因によるばらつき』と『誤差によるばらつき』の和とみなせます。分散分析は、データ全体のばらつきを「平方和」として表し、それを要因ごとに分け、誤差に比べて大きな影響を与えている要因を探し出し、推測に利用する方法です。


具体的には、ある要因の水準ごとに分けたデータ(群)について、それぞれの群の平均を求めます。そして全データに対し、その群の平均を引いた差の2乗を求めます。Pythonで書くと(「全データを表す」変数に行列データが入っているとします):


import numpy as np
import pandas as pd
# A, B, C, Dは「対応のない一元配置分散分析」の例からとった。1要因4水準
A = np.array([15,9,18,14,18])
B = np.array([13,8,8,12,7])
C = np.array([10,6,11,7,12])
D = np.array([10,7,3,5,7])

AllData = pd.DataFrame({'A':A, 'B':B, 'C':C, 'D':D})  # データフレームを作る:全データ
GroupAverage = AllData.mean()   # 水準ごとの平均のベクトル:群平均
# 水準ごとの平均のベクトルを行数だけ並べた行列を作る
GroupAverageMatrix =np.ones(AllData.shape)       # 群平均行列の形の生成
for i in range(AllData.shape[1]):                # 要素をいれていく
    GroupAverageMatrix[:,i] = AllData.mean().iloc[i]   # 水準ごとの平均

InGroup = np.array(AllData - GroupAverageMatrix)  # 各データと、その群内の平均との差

InGroupSquareSum = np.sum(InGroup**2)       #  群内平方和

Divider = InGroupSquareSum /( ( len(AllData.index) -1.0)*len(AllData.columns)) # 分母

このように「それぞれのデータと群平均との差の2乗の和」が「群の中のデータのばらつき」を表し、これが(群内平方和)と呼ばれるものです。そして、これを群内の自由度(「各群のデータ数-1」の和)で割ったものが、各データの「誤差によるばらつき」を表しているとみなすことができます。

一方、「要因によるばらつき」は、群間のばらつきで表されます。それは「全データの平均と各群の平均の差」の2乗の和を、群間の自由度(群の数-1、つまり水準数-1)で割った値と計算されます:


# 全データの和の平均</font>
OverallMean = np.sum(AllData.mean())/len(AllData.columns)   # 全体平均 
# 各群ごと「群平均-全平均」からなる行列
InterGroup =GroupAverageMatrix - np.ones(AllData.shape)*OverallMean  # 群間
InterGroupSquareSum = np.sum(InterGroup**2)  # 群間平方和 

Dividend = InterGroupSquareSum / (len(AllData.columns) - 1.0) # 分子

群間平方和を群間の自由度で割った値(「分子」の値)が『要因によるばらつき』です。これを「誤差によるばらつき」で割った値がFであり、Fの値によって要因のばらつきの影響を推定するのが分散分析です(この計算方法が「分散」という名前がついている理由です。なお、Fは統計学者Fisherに由来します)。


Dividend    # 分子
⇒ 61.33333
Divider     # 分母
⇒ 8.625
F = Dividend / Divider      # F = 分子/分母
⇒ 7.111111
In [35]:
import numpy as np
# A, B, C, Dは「対応のない一元配置分散分析」の例からとった。1要因4水準
A = np.array([15,9,18,14,18])
B = np.array([13,8,8,12,7])
C = np.array([10,6,11,7,12])
D = np.array([10,7,3,5,7])
In [36]:
import pandas as pd

AllData = pd.DataFrame({'A':A, 'B':B, 'C':C, 'D':D})
AllData
Out[36]:
A B C D
0 15 13 10 10
1 9 8 6 7
2 18 8 11 3
3 14 12 7 5
4 18 7 12 7
In [3]:
AllData.mean()
Out[3]:
A    14.8
B     9.6
C     9.2
D     6.4
dtype: float64
In [4]:
GroupAverageMatrix =np.ones(AllData.shape)
for i in range(AllData.shape[1]):
    GroupAverageMatrix[:,i] = AllData.mean().iloc[i]

GroupAverageMatrix
Out[4]:
array([[ 14.8,   9.6,   9.2,   6.4],
       [ 14.8,   9.6,   9.2,   6.4],
       [ 14.8,   9.6,   9.2,   6.4],
       [ 14.8,   9.6,   9.2,   6.4],
       [ 14.8,   9.6,   9.2,   6.4]])
In [5]:
InGroup = np.array(AllData - GroupAverageMatrix)
InGroup
Out[5]:
array([[ 0.2,  3.4,  0.8,  3.6],
       [-5.8, -1.6, -3.2,  0.6],
       [ 3.2, -1.6,  1.8, -3.4],
       [-0.8,  2.4, -2.2, -1.4],
       [ 3.2, -2.6,  2.8,  0.6]])
In [6]:
InGroupSquareSum = np.sum(InGroup**2)
InGroupSquareSum
Out[6]:
138.0
In [7]:
#len(AllData.columns)
OverallMean = np.sum(AllData.mean())/len(AllData.columns)
OverallMean
Out[7]:
9.999999999999998
In [8]:
InterGroup =GroupAverageMatrix - np.ones(AllData.shape)*OverallMean
InterGroup
Out[8]:
array([[ 4.8, -0.4, -0.8, -3.6],
       [ 4.8, -0.4, -0.8, -3.6],
       [ 4.8, -0.4, -0.8, -3.6],
       [ 4.8, -0.4, -0.8, -3.6],
       [ 4.8, -0.4, -0.8, -3.6]])
In [9]:
InterGroupSquareSum = np.sum(InterGroup**2)
InterGroupSquareSum
Out[9]:
184.00000000000003
In [10]:
Dividend = InterGroupSquareSum / (len(AllData.columns) - 1.0)
Dividend
Out[10]:
61.333333333333343
In [11]:
Divider = InGroupSquareSum /( ( len(AllData.index) -1.0)*len(AllData.columns))
Divider
Out[11]:
8.625
In [12]:
F = Dividend / Divider
F
Out[12]:
7.1111111111111125

変数の値に影響を及ぼす要因が1個の場合一元配置法、要因が2個の場合二元配置法、 3個以上の場合は多元配置法という。
また要因と水準の組み合わせごとに実験が繰り返されてデータがとられる場合を繰り返しのある二元配置法などと呼ぶ。

一般に検定の結果として表示される分散分析表の構成 (PythonではFとpの値のみ):

要因 自由度(Df) 平方和(Sum Sq) 平均平方(Mean Sum Sq) F値(F value) P値 評価
要因名 水準数-1 群間平方和 群間平方平均 F値 p値 (表の下に説明)
残差(Residuals) 水準数×(1群あたりのデータ数-1) 群内平方和 群内平方平均      
合計 データ数-1            

評価の印: 星印は有意(*は0.1%、は1%、*は5%水準)、.は10%(「有意傾向」という)を表す


In [15]:
m=len(AllData.columns) - 1.0
n= ( len(AllData.index) -1.0)*len(AllData.columns)
print(m,n)
3.0 16.0
In [38]:
%matplotlib inline
from __future__ import division
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt

fig,ax = plt.subplots(1,1)
x = np.linspace(0,8, 1000)

ax.plot(x, stats.f.pdf(x, m,n), linestyle='-')

plt.xlabel('$x$')
plt.ylabel(r'$f(x)$')
plt.title(r'F-Distribution')
plt.axis([-0.2,8,-0.02,1.2]) 
plt.legend()
plt.grid()
C:\Anaconda3\lib\site-packages\scipy\stats\_continuous_distns.py:1429: RuntimeWarning: divide by zero encountered in log
  lPx = m/2 * np.log(m) + n/2 * np.log(n) + (n/2 - 1) * np.log(x)
In [35]:
stats.f.sf(7.11, m,n)
Out[35]:
0.0029898354668750795

対応のない一元配置分散分析

例題:以下の表は『教え方』ごとにみた統計学テストの成績である。この表から、4通りの教え方(A,B,C,D)によって統計学テストの母平均に差があるだろうか?

A B C D
15 13 10 10
9 8 6 7
18 8 11 3
14 12 7 5
18 7 12 7


この標本が母平均の等しい4群から抽出される可能性が高いかどうかを検討するために分散分析を行う。ここで『教え方』が要因、A, B, C, Dの4つがその水準となる.

Pythonを用いた計算方法の紹介

  1. 帰無仮説と対立仮説の設定
      ・帰無仮説 H0:4群の母平均は等しい
      ・対立仮説 H1:4群の母平均は等しくない
    注意: 4群のうち1つだけ母平均が異なるような場合でも対立仮説は成立
  2. 検定統計量の選択 --- 次のFを検定統計量とする: これは帰無仮説(すべての群の母平均が等しいとき)のもとで、F分布に従う F分布の自由度は2種類:分子と分母の自由度
    F分布の描画: st.f.pdf(x,分子の自由度,分母の自由度) 関数を使用
    ``` plt.plot(x,st.f.pdf(x, 3, 16)) ```
  3. 有意水準$\alpha$の決定: ここでは有意水準は5%、つまり$\alpha=0.05$とする
    F分布のグラフから明らかなように、F分布は正値を取る⇒ 分散分析は常に片側検定
  4. 検定統計量の実現値を求める: st.f_oneway関数
In [37]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as st
x=np.linspace(0,8,1000)
plt.plot(x,st.f.pdf(x,3,16))
plt.xlabel('x')
plt.ylabel('st.f.pdf(x,3,16)')
plt.grid()
/opt/anaconda3/lib/python3.6/site-packages/scipy/stats/_continuous_distns.py:1591: RuntimeWarning: divide by zero encountered in log
  lPx = m/2 * np.log(m) + n/2 * np.log(n) + (n/2 - 1) * np.log(x)
In [ ]:
help(st.f_oneway)

Pythonを用いた計算:

In [39]:
import numpy as np
# 4つの指導法に違いがあるか?
A = np.array([15,9,18,14,18])
B = np.array([13,8,8,12,7])
C = np.array([10,6,11,7,12])
D = np.array([10,7,3,5,7])
In [40]:
f, p = st.f_oneway(A,B,C,D)
print("F=%f, p-value = %f"%(f,p))
F=7.111111, p-value = 0.002988

F値は7.11、p値が0.003であるから、帰無仮説が棄却される。検定の結果、つまりA,B,C,Dの間に有意な平均値差が見られたことが導ける。

注意: 実際には分散分析を適用するには、データが独立で、それぞれ正規分布に従うものであり、分散はみな等しい(分散の等質性)という条件がある。分散の等質性の検定にはBartlett検定を用いる。

In [41]:
st.bartlett(A,B,C,D) # Bartlett検定
Out[41]:
BartlettResult(statistic=0.704094908747911, pvalue=0.8722403650937011)

多重比較(Tukeyの方法)

一元配置分散分析の結果「帰無仮説が棄却」されても、これだけでは「群の母平均が等しくない」ことしかわからない。


具体的に「どの群とどの群の間に差があるか」を知りたいことが多い。それには多重比較を行う。ここではTukey(テューキー)の方法を紹介する。

仮定: 各群のデータ数(サンプルサイズ)nが等しく、各群の母分散も等しい(分散の等質性)
検定統計量q:


Pythonでは次のようにstatsmodels.stats.multicompモジュールの pairwise_tukeyhsd (Tukey's Honest Significant Difference)関数を用いれば、いろいろな指導方法による平均値差の多重比較が可能となる

In [ ]:
from statsmodels.stats.multicomp import pairwise_tukeyhsd
help(pairwise_tukeyhsd)
In [42]:
from statsmodels.stats.multicomp import pairwise_tukeyhsd
import numpy as np
# 4つの指導法に違いがあるか?
A = np.array([15,9,18,14,18])
B = np.array([13,8,8,12,7])
C = np.array([10,6,11,7,12])
D = np.array([10,7,3,5,7])

data_arr = np.hstack( (A,B,C,D) ) # すべてのデータを結合
# array([15,  9, 18, 14, 18, 13,  8,  8, 12,  7, 10,  6, 11,  7, 12, 10,  7,  3,  5,  7])
ind_arr = np.repeat(list('ABCD'),len(A))   # 名称をリスト
# array(['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C', 'D', 'D', 'D', 'D', 'D'])

print(pairwise_tukeyhsd(data_arr,ind_arr))   # 結果を出力する
Multiple Comparison of Means - Tukey HSD,FWER=0.05
==============================================
group1 group2 meandiff  lower    upper  reject
----------------------------------------------
  A      B      -5.2   -10.5145  0.1145 False 
  A      C      -5.6   -10.9145 -0.2855  True 
  A      D      -8.4   -13.7145 -3.0855  True 
  B      C      -0.4   -5.7145   4.9145 False 
  B      D      -3.2   -8.5145   2.1145 False 
  C      D      -2.8   -8.1145   2.5145 False 
----------------------------------------------

出力された表においてはp値が0.05以下のものに、reject列で True と記入がある。これに該当するのはAとCの間,およびAとDの間であり、これらには5%水準で有意差があることがわかった。

In [42]:
# 参考: 関数にしてみた
def tukey_hsd( lst, ind, n ):
    from statsmodels.stats.multicomp import pairwise_tukeyhsd
    import numpy as np
    data_arr = np.hstack( lst )
    ind_arr = np.repeat(ind, n)
    print(pairwise_tukeyhsd(data_arr,ind_arr))

tukey_hsd( (A,B,C,D), list('ABCD') , 5) # 第1引数:データをタプルで, 第2引数:名称のリスト, 第3引数: データの個数
Multiple Comparison of Means - Tukey HSD,FWER=0.05
==============================================
group1 group2 meandiff  lower    upper  reject
----------------------------------------------
  A      B      -5.2   -10.5145  0.1145 False 
  A      C      -5.6   -10.9145 -0.2855  True 
  A      D      -8.4   -13.7145 -3.0855  True 
  B      C      -0.4   -5.7145   4.9145 False 
  B      D      -3.2   -8.5145   2.1145 False 
  C      D      -2.8   -8.1145   2.5145 False 
----------------------------------------------
In [43]:
# 別バージョン:個数がそれぞれ違う場合. 次を参考にした: http://qiita.com/keroplant/items/bb03375c55ca4b2f5943
A = [100, 96, 80, 92, 101, 99, 89, 93]
B = [83, 77, 86, 71, 70, 98, 80, 75, 74]
C = [90, 91, 92, 89, 88, 90, 91]

def tukey_hsd( ind, *args ):
    from statsmodels.stats.multicomp import pairwise_tukeyhsd
    import numpy as np
    data_arr = np.hstack( args )
    ind_arr = np.array([])
    for x in range(len(args)):
      ind_arr = np.append(ind_arr, np.repeat(ind[x], len(args[x])))
    print(pairwise_tukeyhsd(data_arr,ind_arr))

tukey_hsd(list('ABC') , A,B,C) # 第1引数:名称のリスト, 第2引数以降: データ
Multiple Comparison of Means - Tukey HSD,FWER=0.05
==============================================
group1 group2 meandiff  lower    upper  reject
----------------------------------------------
  A      B    -14.4167 -22.7227 -6.1106  True 
  A      C    -3.6071  -12.454   5.2397 False 
  B      C    10.8095   2.1951   19.424  True 
----------------------------------------------

対応のある一元配置分散分析

一元配置分散分析(対応あり)では、同じ被験者が複数の条件を経験する(被験者内計画のデータ)というような対応があるデータを対象とする


[参考: 対応のあるなしの違い]

データに『対応がある(反復、繰り返しのある、ともいう)』ということは、それだけ情報が多い(データだから、それを用いた検定が可能になります。前章で「対応のあるt検定」について述べ、そこで取り上げた例題では結論は変わらなかったものの、対応のある検定の方がp値が小さい、ということを見ました。ここで取り上げる例題でも同じようなことがわかります。以下ではデータに「対応がない」ものとして検定した結果を載せます。

import numpy as np
import scipy.stats as st
Algebra = np.array([7,8,9,5,6])
Calculus = np.array([5,4,7,1,3])
Statistics = np.array([8,6,7,2,5])  # 好き嫌い度
print( st.f_oneway(Algebra, Calculus, Statistics) )
⇒ F_onewayResult(statistic=2.6406250000000004, pvalue=0.11210798800331405)

『対応のない』データとしての検定は、F値が2.64で、p値は0.112なので、有意水準0.05よりも大きいため、 帰無仮説は棄却されない。

この結果と、本文で述べる「対応がある」場合の結果とを比べてみてください。

In [43]:
import numpy as np
import scipy.stats as st
Algebra = np.array([7,8,9,5,6])
Calculus = np.array([5,4,7,1,3])
Statistics = np.array([8,6,7,2,5])  # 好き嫌い度
print( st.f_oneway(Algebra, Calculus, Statistics) )
F_onewayResult(statistic=2.6406250000000004, pvalue=0.11210798800331405)

例題: 以下の表は5名の学生に、線形代数、微分積分、確率統計に対する好意度の評定データである。 これら3つの科目に対する好意度に差があるだろうか?(念のため:これは1要因3水準)

学生 線形代数 微分積分 確率統計
田中 7 5 8
8 4 6
大引 9 7 7
吉川 5 1 2
荻野 6 3 5

Pythonを用いた計算方法の紹介

  1. 帰無仮説と対立仮説の設定
       
    • 帰無仮説 H0:3科目の好意度の母平均は等しい  
    • 対立仮説 H1:3科目の好意度の母平均は等しくない
  2. 検定統計量の選択 --- 次のFを検定統計量とする:
    これは帰無仮説(すべての群の母平均が等しいとき)のもとで、F分布に従う
  3. 有意水準$\alpha$の決定: ここでは有意水準は5%、つまり$\alpha=0.05$とする
    F分布のグラフから明らかなように、F分布は正値を取る⇒ 分散分析は常に片側検定
  4. 検定統計量の実現値を求める: Pythonでは、ややマイナーな pyvttbl モジュールを用いる ``` Algebra=[7,8,9,5,6] ; Calculus = [5,4,7,1,3] ; Statistics=[8,6,7,2,5] Students=list(range(5)) # ['Tanaka','Kisi','Obiki','Yosikawa','Ogino'] Favorness = np.array(Algebra+Calculus+Statistics) # 好意度をまとめrる Condition = np.repeat(['algebra','calculus','statistics'],len(Algebra)) # Favornessに合わせた科目のリスト Subjects = np.array(Students+Students+Students) # Favornessに合わせた人のリスト df = pt.DataFrame({'Favorness':Favorness,'Condition':Condition,'Subjects':Subjects}) # データフレームを作る aov=df.anova('Favorness',sub='Subjects',wfactors=['Condition']) # 対応のある1要因分散分析 print(aov) ``` この結果いろいろな表示がでるが、注目点だけ示す: ``` Favorness ~ Condition # Favorness(好意度)をCondition(条件、この場合は科目)から分析する TESTS OF WITHIN SUBJECTS EFFECTS # 「人」の対応ありのもとでの検定 # 以下はいろいろな検定方法で試されている。Sig の項がp値であり、0.002と小さい値であり5%基準で有意な差があることが示されている。 Measure: Favorness Source Type III eps df MS F Sig. et2_G Obs. SE 95% CI lambda Obs. SS Power =========================================================================================================================================== Condition Sphericity Assumed 22.533 - 2 11.267 14.696 0.002 0.440 5 0.461 0.903 18.370 0.890 # 科目ごとの平均と標準偏差。これでみると線形代数(algebra)と微分積分(calculus)の間に差があるようにみえる TABLES OF ESTIMATED MARGINAL MEANS Estimated Marginal Means for Condition Condition Mean Std. Error 95% Lower Bound 95% Upper Bound =================================================================== algebra 7 0.707 5.614 8.386 calculus 4 1 2.040 5.960 statistics 5.600 1.030 3.582 7.618 ```
  5. 帰無仮説の棄却か採択かの決定: 結果の出力のSig列において、p値が 0.002 と得られているので、5%の有意水準で、 科目間に有意な差があることが認められた。

[参考: 『人』がなぜ必要?] まず『人』を含めない場合は先に見たように p値は 0.112となり、科目の効果だけでは好意度の平均に有意な差が認められません。 そもそもこのデータにおいて『対応がある』としたのは、同じ人に対しそれぞれの科目の好意度のデータを集めたので、『対応関係がある』からです。 言い換えれば、「好意度」データを説明する要因として『科目』と『人』があり、『人』を考慮することでデータに「対応がある」と認められたのです。 </div>

In [69]:
# データの準備:DataFrameを作る
import statsmodels.api as sm
from statsmodels.formula.api import ols
import pandas as pd

Algebra=[7,8,9,5,6] ; Calculus = [5,4,7,1,3] ; Statistics=[8,6,7,2,5]
Students=list(range(5))    # ['Tanaka','Kisi','Obiki','Yosikawa','Ogino']
Favorness = np.array(Algebra+Calculus+Statistics)
Condition = np.repeat(['algebra','calculus','statistics'],len(Algebra))
Subjects = np.array(Students+Students+Students)
df = pd.DataFrame({'Favorness':Favorness,'Condition':Condition,'Subjects':Subjects})
In [70]:
df[:5]
Out[70]:
Favorness Condition Subjects
0 7 algebra 0
1 8 algebra 1
2 9 algebra 2
3 5 algebra 3
4 6 algebra 4
In [74]:
# statsmodels.statsのanova.AnovaRMを用いる、インスタンスを作ってfit()する
import statsmodels.stats.anova as anova
aov=anova.AnovaRM(df, 'Favorness','Subjects',['Condition'])
result=aov.fit()
In [75]:
print(result)
# 有意水準は5%、つまり0.005とする
                Anova
======================================
          Num DF Den DF F Value Pr > F
--------------------------------------
Condition 2.0000 8.0000 14.6957 0.0021
======================================

In [77]:
# 5%で有意差があるので、多重比較する
tukey_hsd(list('ABC') , A,B,C) 
Multiple Comparison of Means - Tukey HSD,FWER=0.05
==============================================
group1 group2 meandiff  lower    upper  reject
----------------------------------------------
  A      B      -5.2   -10.3246 -0.0754  True 
  A      C      -5.6   -10.7246 -0.4754  True 
  B      C      -0.4   -5.5246   4.7246 False 
----------------------------------------------


参考:3群以上を比較するとき、2群間の検定(t検定)を使ってはいけない理由

分散分析なら1遍に済むのに、T検定の場合3通りやらなければならないから、 というのが理由ではもちろんありません。

いま、A,B, Cという3つの群があったとします。そこで、2群間の検定を A-B間、B-C間、C-AC間で有意水準5%で行ったとします。

ここで、「この組み合わせの少なくとも1つは有意差がある」 となる確率を計算すると(実際にその間に有意差があるなしに拘らず)、  1-(1-0.05)*(1-0.05)*(1-0.05) = 0.14 となります。つまり、 有意水準 5% (=0.05)で検定したつもりが、 この方法では実質的に 14 %で検定している、つまり 検定力が低下してしまう、というのが理由です。

関数のまとめ

注: scipy.statsをst、statsmodels.stats.anovaをanovaと略記する

目的 関数名とモジュール 使い方
一元配置分散分析(対応なし) st.f_oneway(配列$_1$,$\ldots$,配列$_n$) st.f_oneway(Algebra,Caluculus,Statistics) ⇒ F値とp値
一元配置分散分析(対応あり) anova.AnovaRM(データフレーム,依存変数名,人名, その他の属性のリスト]).fit() anova.AnovaRM(df, 'Favorness','Subjects',['Condition'])).fit()
テューキーの多重分析 from statsmodels.stats.multicomp import pairwise_tukeyhsd
(続き) pairwise_tukeyhsd(データをタプルで, 名称のリスト)もしくは自作関数tukey_hsd pairwise_tukeyhsd(data_arr,ind_arr)
分散の等質性の検定 st.bartlett(データ$_1$,$\ldots$) st.bartlett(A,B,C)

演習問題6

演習問題6-1

ある大学の4学部から8名ずつの学生を無作為抽出して得られた結果が以下である。学部間でテストの母平均に差があるかどうか、 有意水準5%で分散分析を行え。

In [ ]:
import numpy as np
Hougakubu = np.array([75, 61, 68, 58, 66, 55, 65, 63])
Bungakubu = np.array([62, 60, 66, 63, 55, 53, 59, 63])
Rigakubu = np.array([65, 60, 78, 52, 59, 66, 73, 64])
Kougakubu = np.array([52, 59, 44, 67, 47, 53, 58, 49])

演習問題6-2

shidouhou.csvはCSV形式のファイルであり、20人の学生に対し、名前、性別、数学と統計の好き嫌い、心理学テスト、統計テスト1、統計テスト2のそれぞれの成績、そして指導方法の種別のデータが収められている。 このデータを読み込み、統計テスト1の成績が男女の違いで差があるかどうか、また統計の好き嫌いで差があるかどうかをそれぞれ検定せよ。

[参考: csvファイルを読み込む (再掲)</a>] 区切り記号がコンマのcsvファイルを読み込み、その内容をデータフレームとして取り込むには、pandasモジュールのread_csv関数を用いる。

もっとも中にはちゃんと読み込めないこともあるので、値を確認すること。そして読み込めない場合は、区切り記号を適切なものにセットしたりすることも考えよう。

In [ ]:
#
import pandas as pd

演習問題6-3

下は小学校1年生から6年生まで、各学年から5人ずつ無作為抽出し、50メートル走のタイムを計測したデータである。学年による違いがあるか、検討せよ(出典: 長畑(2009)『Rで学ぶ統計学』共立出版)

In [ ]:
import numpy as np
Grade1 = np.array([11.3, 12.4, 15.5, 13.6, 12.4])
Grade2 = np.array([12.3, 13.4, 11.5, 11.6, 10.8])
Grade3 = np.array([9.2, 10.4, 8.6, 9.8, 10.7])
Grade4 = np.array([9.5, 8.4, 9.8, 10.4, 7.8])
Grade5 = np.array([8.4, 7.5, 8.6, 7.9, 8.3])
Grade6 = np.array([7.8, 8.5, 7.6, 7.2, 7.5])

演習問題6-4

下は3種類の1500ccの乗用車を繰り返し4回走行させ、その1リットルあたりの走行距離(燃費)を計測したものである。 車種による違いがあるか、分散分析せよ。(出典: 長畑(2009)『Rで学ぶ統計学』共立出版)

In [ ]:
import numpy as np
A = np.array([8.0, 9.0,  7.0,   6.0])
B  = np.array([12.0, 11.0, 13.0, 12.0])
C  = np.array([ 9.0, 10.0,  9.0,  8.0])