カテゴリー: DataAnalytics

Pythonによる対応ありone-way ANOVA(一元配置分散分析)と多重比較

目標

対応ありone-way ANOVA(一元配置分散分析)と多重比較のプログラムをPythonで書く。対応無しのone-way ANOVAについては、 Unpaired One-way ANOVA And Multiple Comparisons In Python“を参照してください。

ANOVAとは

ANOVA(analysis of variance)は、サンプル内のグループの平均値の差について、要因間で優位な差があるかどうかを確かめる統計的仮設検定の方法です。
内容の詳細については割愛します。下記サイトなどをご覧ください。

one-way ANOVA(一元配置分散分析)とは、3つ以上のサンプルの平均を比較する分散分析テストです。 帰無仮説は、全てのグループのサンプルが同じ平均の母集団から取られたというものです。

対応のある分散分析とは、同じ被験者に対して繰り返し条件を変えて実験したような場合のデータを扱うことを意味します。

実装

以下は、対応のあるone-way ANOVAの実装例です。

ライブラリのインポート

ANOVAの検定をおこなうために以下のライブラリをインポートします。

import statsmodels.api as sm
from statsmodels.formula.api import ols
import pandas as pd
import numpy as np
import statsmodels.stats.anova as anova

データの用意

以下のようなデータを使用します。id_nは被験者であり、条件はA、B、Cの3つです。

id_1id_2id_3id_4id_5id_6id_7
condition A85908869789887
condition B55826764785449
condition C46955980527370

test_data.csvという名前で以下のようなファイルを作成します。

85, 90, 88, 69, 78, 98, 87
55, 82, 67, 64, 78, 54, 49
46, 95, 59, 80, 52, 73, 70

データの読み込みと格納

open(‘file_name’, ) as f: でファイルを読み込みます。fを区切って各数値をitemsに格納していきます。各行について、itemsを取得したら、csv_lines[0], csv_lines[1], csv_lines[2]に格納します。

csv_line = []
with open('test_data.csv', ) as f:
    for i in f:
        items = i.split(',')
        for j in range(len(items)):
            if 'n' in items[j]:
                items[j] = float(items[j][:-1])
            else:
                items[j] =float(items[j])
        print(items)
        csv_line.append(items)

各行のデータにgroupA, groupB, groupCと名付けました。(csv_lineに入れずに直接groupA, groupB, groupCに入れることもできますが、自分が分かりやすくするためこのようにしました)

ラベルを付けて、各グループのデータをセットし、pd.DataFrameを作成。

groupA = csv_line [0]
groupB = csv_line [1]
groupC = csv_line [2]
tdata = pd.DataFrame({'A':groupA, 'B':groupB, 'C':groupC})
tdata.index = range(1,10)
tdata 

tdataは以下のようになります。

もしも、平均や分散などデータの統計的値を見たい場合は、DataFrame.describe()を実行.

tdata.describe()

ANOVAの実行

得点、条件、被験者のデータからpd.DataFrameを作成する。

  • subjects: ‘id1’, ‘id2’, ‘id3’, ‘id4’, ‘id5’, ‘id6’, ‘id7’, ‘id1’, ‘id2’, ‘id3’, ‘id4’, ‘id5’, ‘id6’, ‘id7’, ‘id1’, ‘id2’, ‘id3’, ‘id4’, ‘id5’, ‘id6’, ‘id7’
  • points: groupA + groupB + groupC = 85, 90, 88, 69, 78, 98, 87, 55, 82, 67, 64, 78, 54, 49, 46, 95, 59, 80, 52, 73, 70.
  • conditions: ‘A’, ‘A’, ‘A’, ‘A’, ‘A’, ‘A’, ‘A’, ‘B’, ‘B’, ‘B’, ‘B’, ‘B’, ‘B’, ‘B’, ‘C’, ‘C’, ‘C’, ‘C’, ‘C’, ‘C’, ‘C’
subjects=['id1','id2','id3','id4','id5','id6','id7']
points = np.array(group0 +group1 + group2)
conditions = np.repeat(['A','B','C'],len(groupA))
subjects = np.array(subjects+subjects+subjects)
df = pd.DataFrame({'Point':points,'Conditions':conditions,'Subjects':subjects})

anova.AnovaRM(df, ‘Point’, ‘Subjects’, [‘Conditions’])でANOVAを実行。

aov=anova.AnovaRM(df, 'Point','Subjects',['Conditions'])
result=aov.fit()

print(result)

>>                 Anova
========================================
           F Value Num DF  Den DF Pr > F
----------------------------------------
Conditions  5.4182 2.0000 12.0000 0.0211
========================================

p値が小さいほど、帰無仮説が棄却されるようになる。統計的に優位な場合、つまりp値が0.05未満(通常≤0.05)の場合は、多重比較を実行します。 このp値は、対応のある分散分析と対応のない分散分析で異なります。

Tukeyの多重比較

テューキーの範囲検定(tuky’s HSD, honestly significant difference test)を行うには、pairwise_tukeyhsd(endog, groups, alpha=0.05)を使用します。引数endogは従属変数のデータの配列(A[0] A[1]… A[6] B[1] … B[6] C[1] … C[6])です。引数groupsは、従属変数に対応する名前(A、A…A、B…B、C…C)のリストです。alphaは有意水準です。

def tukey_hsd(group_names , *args ):
    endog = np.hstack(args)
    groups_list = []
    for i in range(len(args)):
        for j in range(len(args[i])):
            groups_list.append(group_names[i])
    groups = np.array(groups_list)
    res = pairwise_tukeyhsd(endog, groups)
    print (res.pvalues) #print only p-value
    print(res) #print result

結果の出力

次の場合は、Group AとGroup Bの平均に有意差があるという結果になります。

print(tukey_hsd(['A', 'B', 'C'], tdata['A'], tdata['B'],tdata['C']))
>> [0.02259466 0.06511251 0.85313142]
 Multiple Comparison of Means - Tukey HSD, FWER=0.05 
=====================================================
group1 group2 meandiff p-adj   lower    upper  reject
-----------------------------------------------------
     A      B -20.8571 0.0226 -38.9533 -2.7609   True
     A      C -17.1429 0.0651 -35.2391  0.9533  False
     B      C   3.7143 0.8531 -14.3819 21.8105  False
-----------------------------------------------------
None