Up

対応のあるデータの平均値の差の検定

 

データが対の形で与えられている場合の検定、t値、p値、信頼区間を求めるプログラムをリストに示すように書いてみた。検定については、岡本安晴データを使いこなすための統計入門で説明している。

データ例として、図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により算出できる。

リストのスクリプトファイルとサンプルデータファイルは、圧縮ファイル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()

 

 

Home