Up

平均の差の検定

 

条件間でサンプルが独立な場合と、繰り返し条件あるいは関連のあるデータ対として得られた場合とについて、平均値の差の検定のためのプログラム例を用意してみた。

ファイルは圧縮ファイルt_test_files_csv.zipにまとめた。圧縮ファイルt_test_files_csv.zipには、Jupyter Notebook用のファイルも含めた。

 

 

独立なサンプル

 

2つの畑、AB,、からそれぞれランダムに10個のメロンを採り、重さを測ったところ、表1の結果を得たとする。

1 畑ABのメロンの重さ(g)

重さ

A

    1482     1729     1703     1442     1293

    1131     1126     1357     1582     1427

B

    1962     2028     1762     1810     1822

    1393     1711     1644     2144

 

1のデータに対して、畑ABでメロンの重さの平均値に有意差があるかどうかの検定(独立なサンプルのt−検定)を行うためのPythonスクリプトをリスト1のように用意した。

リスト1のスクリプトを実行すると、入力データファイル名の設定が求められる。

 

File Name(*.csv) =

 

入力データファイルは、CSVファイルとして図1のように作成する。

図1

 

図1のファイルは、表1のデータをExcelに入力してCSV形式のファイルData_Ind.csvとしたものである。CSVファイルの作成は、このウェブサイトで説明している。

データは、図1のように1行目に変量名を書き、その下にデータ値を書いていく。

例として、図1のファイル名Data_Ind.csvを設定する。

 

File Name(*.csv) = Data_Ind.csv

 

ファイル名を設定すると、ファイルが読み込まれて、変量名のリストが表示され、第1変量の設定が求められる。

 

File Name(*.csv) = Data_Ind.csv

['A' 'B']

Var.1 =

 

変量名は、「'」で挟んで表されているが、入力するときは「'」を外して設定する。

 

File Name(*.csv) = Data_Ind.csv

['A' 'B']

Var.1 = A

Var.2 = B

 

第1変量を設定すると、次に第2変量の設定が求められる。

第2変量を設定すると計算が始まり、ヒストグラムが表示される(図2)。

図2

 

図2のWindowを閉じると、プログラムは終了して、端末には以下の出力が表示されている。

 

 

等分散仮説を前提とする

両側検定

t = -3.84524

p-value = 0.00130

df = 17.000

95% CI = [-590.426, -172.063]

 

 

等分散仮説を前提とする

左側検定(下側検定)

t = -3.84524

p-value = 0.00065

df = 17.000

95% CI = [-inf, -208.768]

 

 

等分散仮説を前提とする

右側検定(上側検定)

t = -3.84524

p-value = 0.99935

df = 17.000

95% CI = [-553.721, inf]

 

 

等分散仮説を前提としない (Welch's t)

両側検定

t' = -3.83262

p-value = 0.00139

df = 16.520

95% CI = [-591.580, -170.909]

 

 

等分散仮説を前提としない (Welch's t)

左側検定(下側検定)

t' = -3.83262

p-value = 0.00070

df = 16.520

95% CI = [-inf, -207.910]

 

 

等分散仮説を前提としない (Welch's t)

右側検定(上側検定)

t' = -3.83262

p-value = 0.99930

df = 16.520

95% CI = [-554.579, inf]

 

 

等分散仮説を前提とする場合(標準のt検定)と、等分散仮説を前提としない場合(ウェルチのt検定)が出力されている。

ウェルチのtのp値は、このウェブサイトでのシミュレーションにおいて、等分散仮説が成り立つ場合、p値が0あるいは1の近傍において若干のずれが認められるが、全体として標準のt検定(スチューデントのt検定)のp値をよく近似していることが示されている。特に理由が無いときは、ウェルチの検定を用いる方が安全であると思われる。

 

 

 

リスト1 独立なサンプルの平均値の差の検定

 

import numpy as np

import matplotlib.pyplot as plt

import japanize_matplotlib

import pandas as pd

import scipy.stats as ss

 

fin_nm = input('File Name(*.csv) = ')

data = pd.read_csv(fin_nm)

print(data.keys().values)

A_name = input('Var.1 = ')

B_name = input('Var.2 = ')

A = data[A_name].values

A = A[np.isnan(A)==False]

B = data[B_name].values

B = B[np.isnan(B)==False]

print(f'{A_name}:  Mean = {np.mean(A):.3f},   SD = {np.std(A):.3f}')

print(f'{B_name}:  Mean = {np.mean(B):.3f},   SD = {np.std(B):.3f}')

 

for eq in [True, False]:

    for alt in['two-sided', 'less', 'greater']:

        print(); print()

        if eq == True:

            print('等分散仮説を前提とする')

        else:

            print("等分散仮説を前提としない (Welch's t)")

        if alt == 'two-sided':

            print('両側検定')

        elif alt == 'less':

            print('左側検定(下側検定)')

        else:

            print('右側検定(上側検定)')

           

        results = ss.ttest_ind(A, B, equal_var=eq, alternative=alt)

        if eq == True:

            print(f't = {results.statistic:.5f}')

        else:

            print(f"t' = {results.statistic:.5f}")

        print(f'p-value = {results.pvalue:.5f}')

        print(f'df = {results.df:.3f}')

        ci = results.confidence_interval(confidence_level=0.95)

        print(f'95% CI = [{ci.low:.3f}, {ci.high:.3f}]')

      

plt.hist([A, B],label=[f'{A_name}', f'{B_name}'])

plt.title(f'Mean({A_name}) = {np.mean(A):.2f}' +

          f'   Mean({B_name}) = {np.mean(B):.2f}', fontsize=14)

plt.ylabel('度数', fontsize=16)

plt.legend()

plt.show()

 

 

 

 

繰り返し条件のサンプル(関連のあるデータ)

 

ダイエット前後の体重として表2のデータを得たとする。

 

表2  ダイエット前後の体重[前、後](Kg

[73, 70]     [68, 61]     [71, 68]     [68, 62]     [61, 60]

[73, 70]     [80, 81]     [71, 72]     [75, 65]     [59, 52]

[89, 85]     [68, 71]     [96, 91]     [88, 83]     [79, 78]

[68, 69]     [71, 65]     [66, 64]     [72, 69]     [78, 72]

 

ダイエット前後で差があったかどうかの検定(繰り返し条件/対応のある条件のt−検定)のため、リスト2のスクリプトを用意した。

リスト2のスクリプトを実行すると、入力ファイルの設定が求められる。

 

File Name(*.csv) =

 

データファイルは、CSV形式のファイルとして用意する。図3は、表2のデータをCSV形式のファイルとしたものである。CSV形式のファイルの作成法は、このウェブサイトで説明している。

図3

 

入力データは、1行目に変量名を書き、その下にデータを書いていく。例として、図3のファイルData_Rel.csvを入力データファイルとして設定する。

 

File Name(*.csv) = Data_Rel.csv

 

データファイル名を設定すると、ファイルが読み込まれて、変量名のリストが表示され、分析の対象とする変量名の設定が求められる。

 

File Name(*.csv) = Data_Rel.csv

['' '']

Var.1 =

 

変量名のリストは、変量名が「'」で挟まれて表示されている。変量名を設置するときは、「'」をはずして設定する。

第1変量名を設定すると、第2変量名の設定が求められる。検定は、「第1変量 − 第2変量」について行われる。

 

File Name(*.csv) = Data_Rel.csv

['' '']

Var.1 =

Var.2 =

 

第2変量を設定すると、計算が始まり、差「第1変量 ― 第2変量」のヒストグラムが表示される(図4)。

図4

 

図4のWindowを閉じると、プログラムの実行の終了となる。端末には、以下の出力が表示されている。

 

 

Mean() = 73.7

Mean() = 70.4

Mean() - Mean() = 3.300

SD( - ) = 3.226

N = 20

SD/N**0.5 = 0.721

 

 

両側検定

t = 4.45826

p-value = 0.00027

df = 19.00

95% CI = [1.751, 4.849]

 

 

左側検定(下側検定)

t = 4.45826

p-value = 0.99987

df = 19.00

95% CI = [-inf, 4.580]

 

 

右側検定(上側検定)

t = 4.45826

p-value = 0.00013

df = 19.00

95% CI = [2.020, inf]

 

 

 

リスト2 繰り返し条件のt検定

 

import pandas as pd

import numpy as np

import scipy.stats as ss

import matplotlib.pyplot as plt

import japanize_matplotlib

 

fin_nm = input('File Name(*.csv) = ')

f_data = pd.read_csv(fin_nm, encoding='shift-jis')

print(f_data.keys().values)

A_name = input('Var.1 = ')

B_name = input('Var.2 = ')

a = f_data[A_name].values

b = f_data[B_name].values

 

print(f'Mean({A_name}) = {np.mean(a)}')

print(f'Mean({B_name}) = {np.mean(b)}')

print(f'Mean({A_name}) - Mean({B_name}) = {np.mean(a) - np.mean(b):.3f}')

print(f'SD({A_name} - {B_name}) = {np.std(a-b):.3f}')

print(f'N = {len(a)}')

print(f'SD/N**0.5 = {np.std(a-b)/(len(a)**0.5):.3f}')

 

for alt in ['two-sided', 'less', 'greater']:

    print(); print()

    if alt == 'two-sided':

        print('両側検定')

    elif alt == 'less':

        print('左側検定(下側検定)')

    else:

        print('右側検定(上側検定)')

    results = ss.ttest_rel(a, b, alternative=alt)

    print(f't = {results.statistic:.5f}')

    print(f'p-value = {results.pvalue:.5f}')

    print(f'df = {results.df:.2f}')

    print(f'95% CI = [{results.confidence_interval().low:.3f},' +

          f' {results.confidence_interval().high:.3f}]')

 

plt.hist(a - b)

plt.title(f'Mean({A_name} - {B_name}) = {np.mean(a) - np.mean(b):.2f}',

          fontsize=16)

plt.ylabel('度数', fontsize=14)

plt.xticks(fontsize= 12)

plt.xlabel(f'{A_name} - {B_name}', fontsize=16)

plt.show()

 

 

 

 

Up