2群間の母平均の差の検定を行う(t検定)【Python】

2つのグループのデータに差があるかどうかを調べるにはどうすればよいでしょうか?それぞれのグループのデータの平均値をとってみて、単純に比較するだけでいいですか?その平均値がどの程度違えば、「たまたま平均値が違っただけ」ではなく、本当に違いがあるといえるでしょうか?

このようなことを確かめるための方法が「母平均の差の検定」で、t検定を用います。2つのグループのデータのそれぞれの母集団の平均値(母平均)が等しいかどうかを統計学的に確かめることができ、ここで差があることが確かめられればその2つのグループは異なるものだと統計的に言うことができます。

ここではPythonを用いて平均値の差の検定を行う方法を説明します。

開発環境

  • Python 3.7.9
  • scipy 1.6.0

対応のない2群の母平均の差の検定

具体的な例

まずは、具体的な例を考えてみましょう。ある企業の健診において血圧(収縮期血圧)を計測しました。この時、グループAとグループBからそれぞれランダムに15人抽出した血圧のデータが以下の通りだとします。この時、グループAとグループBの血圧の平均値に差があるといえるでしょうか?

グループAとグループBからそれぞれランダムに抽出した15人の平均は「標本平均」といいますが、今求めたいのではこの15人を抽出した元のグループA・グループB全体の平均についてです。このサンプル(標本)の抽出元の平均のことを母平均といいます。

母平均に差があるかどうかを検定する

それではグループAとグループBの母平均に差があるかどうかの検定を有意水準を5%で行ってみましょう。帰無仮説と対立仮説とは次のようになります。

  • 帰無仮説:グループAの母平均(\(\mu_A\))とグループBの母平均(\(\mu_B\))とは差がない (\(\mu_A = \mu_B\))
  • 対立仮説:グループAの母平均(\(\mu_A\))とグループBの母平均(\(\mu_B\))には差がある (\(\mu_A \neq \mu_B\))

Pythonを用いて仮説検定を行う場合はscipy.statsモジュールを用います。対応のない2群間の平均値の差についてのt検定はttest_ind関数を用いましょう。なお、ここではグループAの分散とグループBの分散が等しいかどうかは不明であるとします。

from scipy import stats

group_A = [107,117,131,121,130,116,109,131,118,107,108,131,105,110,108]
group_B = [118,116,127,140,115,137,116,140,121,139,128,127,121,131,123]

result = stats.ttest_ind(group_A, group_B, equal_var = False)
print(result)
Ttest_indResult(statistic=-2.873554179171748, pvalue=0.007698227008043952)

これよりp値が0.0076… ということが分かります。これは、仮に帰無仮説が真であるとすると今回の標本分布と同じか、より極端な標本分布が偶然得られる確率は0.0076…であるという意味になります。ここでは最初に有意水準を5%としているので、「その確率が5%以下であるならば、それは偶然ではない(=有意である)」とあらかじめ設定しています。帰無仮説が真であるときに今回の標本分布が得られる確率は0.0076…であり0.05(5%)よりも小さいことから、これは偶然ではない(=有意である)と判断でき、帰無仮説は棄却されます。つまり、グループAとグループBの母平均には差があると言えます。

ttest_ind関数について

今回使ったttest_ind関数についてみていきましょう。この関数は対応のない2群間のt検定を行うためのものです。

equal_var引数で等分散かどうかを指定でき、等分散であればスチューデントのt検定を、等分散でなければウェルチのt検定を用います。先ほどの例ではequal_var=Falseとして等分散の仮定をせずにウェルチのt検定を用いていますが、検定する2つの母集団の分散が等しければequal_var=Trueと設定してスチューデントのt検定を用いましょう。ただし、等分散性の検定を行うことについては検定の多重性の問題もあり最近ではあまり推奨されていません。このことについては次の項で詳しく説明しています。

両側検定か片側検定かはalternative引数で指定でき、デフォルトでは両側検定になっています。なお、このalternative引数はscipy 1.6.0から導入された引数です。

等分散性の仮定について ― 最近のトレンド

2群間の母平均の差の検定では、母集団の等分散性を仮定できるかどうかでスチューデントのt検定とウェルチのt検定を使い分けます。そのため、多くの統計の教科書ではF検定などを用いて等分散性の検定を行ったうえで、スチューデントのt検定かウェルチのt検定を選択するように書いていると思います。等分散性の検定については以下の記事をご覧ください。

しかし、「等分散性の検定」→「t検定」という流れで本当に最終的な有意水準を担保できるのでしょうか?この方法には検定の多重性によるαエラーの増大という大きな問題が含まれています。このことについては以下のサイトで詳しく論じられているので是非一度ご覧ください。

ここで述べられているように、最近では検定の多重性の問題を避けるために事前に等分散性の検定を行うことは推奨されていません。その代わりに、等分散であるかどうかにかかわらず使えるウェルチのt検定を最初から用いることがトレンドになっているようです。

対応のある2群の母平均の差の検定

具体的な例

今度は対応のある2群の母平均の差についての具体的な例を考えてみましょう。血圧を下げる薬の効果を確かめるために15人の被験者に対して内服前と内服後の血圧(収縮期血圧)を測定しました。この薬は血圧を下げる効果はあったと言えるでしょうか?

先ほどの対応のない2群の場合はグループAとグループBとで全くの別人の血圧でしたが、今回の例では内服前と内服後とで同じ被検者の血圧を見ていて、その両者の母平均は独立とは言えない(=従属である)という点が大きく異なります。

母平均に差があるかどうかを検定する

それでは内服前と後とで母平均に差があるのかを有意水準5%で検定してみましょう。帰無仮説と対立仮説とは次のようになります。

  • 帰無仮説:内服前の母平均(\(\mu_{pre}\))と内服後の母平均(\(\mu_{post}\))とは差がない (\(\mu_{pre} = \mu_{post}\))
  • 対立仮説:内服前の母平均(\(\mu_{pre}\))と内服後の母平均(\(\mu_{post}\))には差がある (\(\mu_{pre} \neq \mu_{post}\))

仮説検定は先ほどと同様にscipy.statsモジュールを用います。対応のある2群間の平均値の差についてのt検定はttest_rel関数を用いましょう。

from scipy import stats

group_Pre = [134,140,128,136,128,129,143,142,126,133,139,132,126,127,125]
group_Post = [126,135,118,135,119,126,135,146,120,133,136,129,119,125,126]

result = stats.ttest_rel(group_Pre, group_Post)
print(result)
Ttest_relResult(statistic=3.8388594797495723, pvalue=0.001806804671734282)

これよりp値が0.0018… ということが分かります。これは、仮に帰無仮説が真であるとすると今回の標本分布と同じか、より極端な標本分布が得られる確率は0.0018…であるという意味になります。有意水準を5%とすると、0.0018… < 0.05であることからこの帰無仮説は棄却され、内服前と内服後の血圧の母平均には差があると言えます。

ttest_rel関数について

最後に今回使ったttest_rel関数についてみてみましょう。この関数は対応のある2群間のt検定を行うためのものです。

今回の例では両側検定を行っていますが、alternative引数で両側検定か片側検定かを指定できます(デフォルトは両側検定)。

関連記事・スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)