独立なサンプルの平均値の差の検定
2つの独立なサンプルの平均値に差があるかどうかの検定のためのt値、p値、信頼区間を算出する。これらの値について、岡本安晴「データを使いこなすための統計入門」で説明している。プログラム例は、リスト1に示した。プログラムファイルなどは、圧縮ファイルfilesnhDiffMeanInd.zipにまとめたので、ダウンロード展開すれば自由に利用できる。
2つの独立なサンプルの例として図1のものを考える。
図1 Excelデータ(data.xlsx)
A市とB市からランダムにそれぞれ15人と20人を選び、血圧を測ったものである(仮想データ)。
A市の血圧データとB市の血圧データをそれぞれ配列dataAとdataBで表すとき、t値とp値はscipy.statsの関数ttest_indにより等分散の仮定の下で以下のように算出される。
results = ss.ttest_ind(dataA,
dataB)
# Student
vL, vU =
results.confidence_interval(0.95)
上のコードにより、返り値resultsにt値、p値(両側検定)と信頼区間を算出するメソッドconfidence_intervalが含まれる。
等分散の仮定が成り立たないときの値は、Welchの方法によるものとして次のコードで与えられる。
resultsw = ss.ttest_ind(dataA,dataB,
equal_var = False)
# Welch
vLw, vUw = resultsw.confidence_interval(0.95)
なお、等分散を前提としない方法として、ベイズ法によるものをこのウェブサイトで説明している。
リスト1のスクリプトを実行すると、まず、入力データファイル名の設定が求められる(図2)。
図2
入力データファイルは、図1の形式で用意する。すなわち、1行目に変数名を書く。データ値は2行目以降に設定する。1列目はデータの識別値で、数値でも文字列でもよい。また、同じ識別値を複数回使ってもよい。2列目と3列目がそれぞれサンプルが取られたグループ(図1の場合、A市とB市)の値である。
入力データファイル名として、図2では図1のデータファイル名が設定されている。
入力データファイル名を設定すると、次に出力ファイル名の設定が求められるが、このファイルには計算結果がテキストファイルとして書き出される。
出力ファイル名の設定の次には、グラフ画像の保存用ファイル名の設定が求められる。ファイル拡張子が「.png」である任意の名前でよい。
画像保存ファイル名を設定すると、データが読み込まれて計算が始まり、図3のグラフが表示される。
図3
図3のウィンドウを閉じると、スクリプトの実行終了である(図4)。
図4
実行終了後、保存されたファイルを開くことができる。
メモ帳など適当なエディタで開くことができるが、計算結果の出力ファイルをPython IDLEのエディタで開こうとすると、図5のメッセージボックスが表示されることがある。
図5
「s-jis」と設定して、「OK」ボタンをクリックすれば開くことができる(図6)。
図6
出力ファイルは以下のような内容である。
入力データファイル: data.xlsx
A市
[126, 122, 120, 132, 129, 124, 124,
125, 124, 124, 121, 121, 130, 125, 129]
B市
[126, 139, 137, 130, 139, 132, 128,
137, 134, 137, 131, 133, 136, 131, 130, 134, 141, 135, 136, 133]
t値 = -6.90702 df =
33.0 p値(両側) = 0.00000 95%CI =
[-11.500, -6.267]
Welch:
t'値 = -7.00497 df' = 31.71 p'値(両側) =
0.00000 95%CI = [-11.467,
-6.299]
A市
平均値 = 125.07 標準偏差 = 3.43
B市
平均値 = 133.95 標準偏差 = 3.81
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import scipy.stats as ss
finnm = input('入力データファイル(*.xlsx)= ')
txtoutnm = input('出力ファイル(*.txt)= ')
txtout = open(txtoutnm, 'w')
foutnm = input('画像保存ファイル(*.png)= ')
#
# Excelファイルの読み込み
# モジュール xlrd がインストール済みであること
#
xlsx_fl = pd.ExcelFile(finnm)
# ExcelファイルからExcelFile型オブジェクトを生成
data_xlsx =
pd.read_excel(xlsx_fl, header =
None) # ExcelFile型オブジェクトからDataFrame型オブジェクトを生成
data = data_xlsx.values
# Dataframe型オブジェクトからnumpyの配列オブジェクトを生成
print('\n', data)
txtout.write('\n入力データファイル: {}\n'.format(finnm))
VarNameA = data[0][1]
VarNameB = data[0][2]
dataA = []
dataB = []
for i in range(1,len(data)):
if not
pd.isnull(data[i][1]):
dataA.append(data[i][1])
if not
pd.isnull(data[i][2]):
dataB.append(data[i][2])
print('dataA =\n', dataA)
print('dataB =\n', dataB)
txtout.write('\n{0}\n'.format(VarNameA))
txtout.write('{0}\n'.format(dataA))
txtout.write('\n{0}\n'.format(VarNameB))
txtout.write('{0}\n'.format(dataB))
results = ss.ttest_ind(dataA,
dataB)
# Student
vL, vU =
results.confidence_interval(0.95)
print(f"\nt値 = {results.statistic:.5f} df = {results.df}" + \
f" p値(両側) = {results.pvalue:.5f}" +
f" 95%CI = [{vL:.3f},
{vU:.3f}]")
txtout.write(f"\n\nt値 = {results.statistic:.5f} df = {results.df}" + \
f" p値(両側) = {results.pvalue:.5f}" +
f" 95%CI = [{vL:.3f},
{vU:.3f}]\n")
resultsw = ss.ttest_ind(dataA,dataB,
equal_var = False) # Welch
vLw, vUw =
resultsw.confidence_interval(0.95)
print('\nWelch')
print(f"t'値 =
{resultsw.statistic:.5f} df'
= {resultsw.df:.2f}" + \
f" p'値(両側) = {resultsw.pvalue:.5f}" +
f" 95%CI = [{vLw:.3f},
{vUw:.3f}]\n")
txtout.write('\nWelch:\n')
txtout.write(f"t'値 =
{resultsw.statistic:.5f} df'
= {resultsw.df:.2f}" + \
f" p'値(両側) = {resultsw.pvalue:.5f}" +
f" 95%CI = [{vLw:.3f},
{vUw:.3f}]\n")
meanA = np.mean(dataA)
meanB = np.mean(dataB)
sdA = np.std(dataA)
sdB = np.std(dataB)
print(VarNameA)
print('平均値 = {0:.2f} 標準偏差 =
{1:.2f}'.format(meanA, sdA))
print(VarNameB)
print('平均値 = {0:.2f} 標準偏差 =
{1:.2f}'.format(meanB, sdB))
txtout.write('\n' + VarNameA + '\n')
txtout.write('平均値 = {0:.2f} 標準偏差 = {1:.2f}\n'.format(meanA, sdA))
txtout.write('\n' + VarNameB + '\n')
txtout.write('平均値 = {0:.2f} 標準偏差 = {1:.2f}\n'.format(meanB, sdB))
# 日本語表記の設定
#plt.rcParams['font.family'] = ['Yu
Gothic', 'Noto Sans CJK JP', 'Hiragino Maru Gothic Pro']
plt.title(('{0}: mean = {1:.2f} sd = {2:.2f}'.format(VarNameA, meanA,
sdA)) + \
'\n{0}: mean
= {1:.2f} sd =
{2:.2f}'.format(VarNameB, meanB, sdB),
fontsize = 16)
plt.hist(dataA, alpha = 0.5, label =
VarNameA)
plt.hist(dataB, alpha = 0.5, label =
VarNameB)
plt.xlabel('値', fontsize = 14)
plt.ylabel('度数', fontsize = 14)
plt.legend()
plt.tight_layout()
plt.savefig(foutnm)
plt.show()
txtout.close()
print('\n出力ファイル{}が保存されました。\n'.format(txtoutnm))
print('画像ファイル{}が保存されました。\n'.format(foutnm))