対応のあるデータの平均値の差の検定
データが対との形で与えられている場合の検定、t値、p値、信頼区間を求めるプログラムをリスト1に示すように書いてみた。検定については、岡本安晴「データを使いこなすための統計入門」で説明している。
データ例として、図1に示すものを考える。健康法実行前と健康法を1カ月実行した後のそれぞれの血圧測定値20人分の仮想データである。
図1 Excelデータ(DiffData.xlsx)
健康法実行前の血圧を、実施後の血圧をで表すとき、それぞれのデータを配列、でまとめれば、t値とp値などはscipy.statsの関数ttest_relによって求めることができる。すなわち、次のコード
results =
ss.ttest_rel(X, Y)
により、戻り値results にt値などが格納されるので、以下のコードで取り出せる。
tv = results.statistic
df = results.df
pv = results.pvalue
vL, vU =
results.confidence_interval(0.95)
信頼区間の端点は、resultsに格納されているメソッドconfidence_intervalにより算出できる。
リスト1のスクリプトファイルとサンプルデータファイルは、圧縮ファイルfilesnhDiffMeanRel.zipとしてまとめた。ダウンロード解凍すれば、自由に利用できる。
リスト1のスクリプトを実行すると、まず、入力データファイル名の設定が求められる(図2)。
図2
入力データファイルは図1の形式で用意する。1行目に変数名を書く。データは2行目以降に設定する。1列目は、データの識別値を書く。図1では通し番号であるが、文字列でもよい。また、同じ識別値を複数回用いてもよい。2列目と3列目に対応のあるデータのそれぞれの値を書く。
図2では、図1のファイル名DiffData.xlsxが設定されている。入力ファイル名の設定後、計算結果の出力用テキストファイルの名前の設定が求められる(図2)。ファイル拡張子が「.txt」の任意のファイル名を設定する。出力ファイル名の設定に続いて、画像保存ファイル名の設定が求められる(図2)。ファイル拡張子が「.png」の任意のファイル名を設定する。画像は複数枚保存されるが、それぞれ設定された名前の「.png」が「_XY.png」などに変更された名前で保存される。
画像保存ファイル名を設定すると、データが読み込まれて計算が始まる。まず、それぞれの変量のヒストグラムが表示される(図3)。
図3
図3のウィンドウの右上のX印をクリックしてウィンドウを閉じると、変量の差のヒストグラムが表示される(図4)。
図4
図4のウィンドウを閉じると、スクリプトの実行終了である(図5)。
図5
保存されたファイルは、実行終了後開くことができる。
出力テキストファイルは任意のテキストエディタ(メモ帳など)で開くことができるが、Python IDLEのエディタで開こうとすると、図6のメッセージボックスが表示されることがある。
図6
「s-jis」と設定して、「OK」ボタンをクリックすれば開くことができる(図7)。
図7
出力ファイルの内容は以下のようである。
入力データファイル: DiffData.xlsx
前
後
133.00 123.00
133.00 127.00
136.00 129.00
136.00 132.00
134.00 127.00
136.00 127.00
131.00 118.00
139.00 134.00
135.00 129.00
140.00 130.00
132.00 124.00
130.00 122.00
138.00 127.00
138.00 124.00
130.00 118.00
137.00 119.00
131.00 123.00
135.00 128.00
136.00 120.00
134.00 129.00
t値 = 10.81074
df = 19 p値(両側) = 0.00000 95% CI = [7.419, 10.981]
前:
平均値=134.70 標準偏差=2.88
後:
平均値=125.50 標準偏差=4.48
差(前 - 後):
平均値=9.20 標準偏差=3.71
リスト1 対応のあるデータのt検定(MainDiffRel.py)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
#import seaborn as sb
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))
VarNameX = data[0, 1]
VarNameY = data[0, 2]
txtout.write('\n{0:>10s}{1:>10s}\n'.format(VarNameX,
VarNameY))
X = data[1:, 1]
Y = data[1:, 2]
for v in zip(X, Y):
txtout.write('{0:>10.2f}{1:>10.2f}\n'.format(v[0], v[1]))
results = ss.ttest_rel(X, Y)
tv = results.statistic
df = results.df
pv = results.pvalue
vL, vU =
results.confidence_interval(0.95)
print(f'\nt値 = {tv:.5f} df = {df} p値(両側) = {pv:.5f}' +
f' 95% CI = [{vL:.3f},
{vU:.3f}]\n')
txtout.write(f'\nt値 = {tv:.5f} df = {df} p値(両側) = {pv:.5f}' +
f' 95% CI = [{vL:.3f},
{vU:.3f}]\n')
meanX = np.mean(X)
meanY = np.mean(Y)
sdX = np.std(X)
sdY = np.std(Y)
print('\n\n{}:'.format(VarNameX))
print(' 平均値={0:.2f} 標準偏差={1:.2f}'.format(meanX, sdX))
print('\n{}:'.format(VarNameY))
print(' 平均値={0:.2f} 標準偏差={1:.2f}\n'.format(meanY, sdY))
txtout.write('\n\n{}:\n'.format(VarNameX))
txtout.write(' 平均値={0:.2f} 標準偏差={1:.2f}\n'.format(meanX, sdX))
txtout.write('\n{}:\n'.format(VarNameY))
txtout.write(' 平均値={0:.2f} 標準偏差={1:.2f}\n'.format(meanY, sdY))
DiffXY = X - Y
meanXY = np.mean(DiffXY)
sdXY = np.std(DiffXY)
print('\n\n差({0} - {1}):'.format(VarNameX, VarNameY))
print(' 平均値={0:.2f} 標準偏差={1:.2f}'.format(meanXY, sdXY))
txtout.write('\n\n差({0} - {1}):\n'.format(VarNameX, VarNameY))
txtout.write(' 平均値={0:.2f} 標準偏差={1:.2f}\n'.format(meanXY, sdXY))
SavedFiles = [txtoutnm]
plt.title(('{0}: 平均値 = {1:.2f}'.format(VarNameX,
meanX)) +
('\n{0}:
平均値 =
{1:.2f}'.format(VarNameY, meanY)), fontsize = 18)
plt.hist(X, alpha = 0.5, label =
VarNameX)
plt.hist(Y, alpha = 0.5, label =
VarNameY)
plt.ylabel('度数', fontsize = 14)
plt.legend()
plt.savefig(foutnm[:-4] + '_XY.png')
SavedFiles.append(foutnm[:-4] +
'_XY.png')
plt.show()
plt.title('差({0} - {1})の分布'.format(VarNameX, VarNameY), fontsize = 20)
plt.hist(DiffXY)
plt.ylabel('度数', fontsize = 18)
plt.savefig(foutnm[:-4] + '_Diff.png')
SavedFiles.append(foutnm[:-4] +
'_Diff.png')
plt.show()
txtout.close()
print('\n保存ファイル:')
for nm in SavedFiles:
print(' {}'.format(nm))
print()