データが多いときはp値は使えないのか？

# はじめに
最近（もう結構前）、p値だけを見てデータを評価するのは止めようという動きがあります。

- [「“統計的に有意差なし”もうやめませんか」　Natureに科学者800人超が署名して投稿](https://www.itmedia.co.jp/news/articles/1903/26/news112.html)
- [仮説検定の判断をp値でする危険性](http://fujitora.hatenablog.jp/entry/2016/10/10/224757)

社内でもp値や統計的有意性について話題に上がりました。データの量が多くなるとp値が小さくなってしまい、どんなデータでも有意になってしまうため、ビッグデータにp値を使うのはやめたほうがいいという話です。これは、確かにそうなのですが、なぜ有意になってしまうのかをちゃんと理解せずに「ビッグデータの時代には古臭い統計学なんて役に立たないのね〜」と勘違いしている人がいそうなので今回はp値について考えてみます。

# なぜデータが増えると有意になってしまうのか
議論を簡単にするために、例として母分散が既知の平均値の検定を行うこととします。母集団は無限母集団とし、分散1平均0の標準正規分布に従うとします。

今、この母集団から有限個の標本をサンプリングします。標本のサイズは{$1,10,10^2,...,10^8$}の9パターンとします。標本平均を用いて検定統計量を求め、仮説「H0：母集団の平均値は0、H1：母集団の平均値は0でない」を検定してみましょう。有意水準は5%とします。母集団の平均は0なので、この仮説は棄却されないはずです。

統計検定量は次のように表されます。$\bar x$は標本の平均、$\mu$と$\sigma$はそれぞれH0の下での母集団の平均と分散です。$n$は標本のサイズです。

```math
z = \frac{\bar x-\mu}{\sqrt{\frac{\sigma^2}{n}}} = \bar x\sqrt{n}.
```

この値が有意水準5%に相当する1.96より大きく（または-1.96より小さく）なるか、pythonで計算してみます。

```python
import matplotlib.pyplot as plt
import cupy
import numpy as np


z_list = np.array([])
for i in range(9):
    x = cupy.random.randn(10**i)
    z = (cupy.mean(x)-0.0)/1 * cupy.sqrt(10**i)
    z = cupy.asnumpy(z)
    z_list = np.append(z_list, z)


plt.plot(z_list, '-', marker='.')
plt.axhline(y=1.96, color='r', linestyle=':')
plt.axhline(y=-1.96, color='r', linestyle=':')
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/56fd9150-2266-96ec-3fa6-ffde44584fc0.png)

赤い点線は有意水準95%の線で、$\pm1.96$です。すべてのパターンで仮説H0は棄却されず、有意差はないという結論になりました。データ量が$10^8$と多いときでも有意になりやすいわけではありません。

では次に、少し仮説を変えてみましょう。新しい仮説を「H0：母集団の平均値は0.01、H1：母集団の平均値は0.01でない」として、同様の計算をしてみます。

```math
z = \frac{\bar x-\mu}{\sqrt{\frac{\sigma^2}{n}}} = (\bar x-0.01) \sqrt{n}.
```

pythonの結果は次のようになります。

```python
import matplotlib.pyplot as plt
import cupy
import numpy as np


z_list = np.array([])
for i in range(9):
    x = cupy.random.randn(10**i)
    z = (cupy.mean(x)-0.01)/1 * cupy.sqrt(10**i)
    z = cupy.asnumpy(z)
    z_list = np.append(z_list, z)


plt.plot(z_list, '-', marker='.')
plt.axhline(y=1.96, color='r', linestyle=':')
plt.axhline(y=-1.96, color='r', linestyle=':')
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/b8defae4-6934-20dc-8b6d-a045dbf201b3.png)

パターン$10^4$までは仮説H0は棄却されず、パターン$10^5$以降では棄却されます。これはどういうことでしょうか？

このことを理解するために信頼区間を考えてみます。母平均の信頼区間は次のように表されます。

```math
(\bar x - 1.96\sqrt{\frac{\sigma^2}{n}}, \  \bar x + 1.96\sqrt{\frac{\sigma^2}{n}}).
```

標本平均の周りの$\pm 1.96\sqrt{\frac{\sigma^2}{n}}$の範囲が母平均の信頼区間です。
では、この信頼区間を上の9パターンで求めてみます。結果は次のようになりました。

| パターン       |       信頼区間 |
|:-----------------|------------------:|
| $1$             |              (-2.88, 1.04) |
| $10$             |              (-0.952, 0.288) |
| $10^2$           |            (-0.141, 0.251) |
| $10^3$             |              (-0.0730, 0.0509) |
| $10^4$          |              (-0.272, 0.120)|
| $10^5$           |            (-0.00493, 0.00747) |
| $10^6$             |              (0.0000244, 0.00394) |
| $10^7$          |              (-0.000419, 0.000821) |
| $10^8$           |            (-0.000334, 0.0000578) |

信頼区間がどんどん狭くなっていることがわかります。そしてH0で仮定した0.01がパターン$10^5$で範囲外になることがわかります。下の図は、信頼区間をプロットしたもので、赤色の点線は0.01です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/0c8579fa-3925-d4e4-67ef-cfe1bb747ab9.png)

信頼区間は母平均が存在する範囲を推定したものですので、信頼区間が狭くなるということは精度が上がっているということです。つまり、標本サイズが大きくなるほど精度が上がっています。そして標本サイズが$10^5$ほど大きくなり精度が上がったところで、母平均0と仮説H0の平均0.01の違いを検出できるようになった、ということです。

以上のことから、「データが増えると有意になってしまう」のは仮説に対する検証の精度が上がり、ほんの少しの違いでも検出できてしまうから、ということがわかりました。したがって、検定をするときは有意かどうかだけでなく、どれくらいの違いがあるのかを信頼区間から判断する必要があります。例えばある飲み物に含まれるビタミンCの平均値を検定するときに、標本サイズを大きくして有意という結論が得られても、0.0000001mgほどの差しかなかったら食品としては影響がありません。

# むしろデータが多い方がよい！？
もう一度、母平均の検定を考えてみます。仮説は「H0：母集団の平均値は0、H1：母集団の平均値は0でない」とします。

検定量の式から次のことがわかります。標本サイズが大きくなると分母が小さくなるため、標本サイズの増加は検定量の値が大きくなるほうに寄与します。一方で標本サイズが大きくなると$\bar x$は真の平均に収束していくので、$\mu$が真の平均であれば分子の$\bar-\mu$は0に近づいていきます。これによって分子と分母が釣り合って、検定量がだいたい$\pm1.96$の範囲に収まるわけです。

```math
z = \frac{\bar x-\mu}{\sqrt{\frac{\sigma^2}{n}}}.
```

ところで、この統計量は標本平均$\bar x$が正規分布に従っていることを利用しています。中心極限定理により、母集団の分布によらず平均は正規分布に従いますが、母集団の分布によっては正規分布への収束がおそいです。したがって、標本サイズが小さいうちは正規分布に収束しておらず、分子の$\bar-\mu$が0に近づくスピードよりも分母が0に近づくスピードが速いため、有意側に出る可能性があります。

と思って、母集団の分布を自由度2のカイ二乗分布で試してみたのですが、ほとんどわかりませんね。。。
もっと面白い分布で試してみると良いかもしれません。

```python
import matplotlib.pyplot as plt
import cupy
import pandas as pd


trial_list = []
for i in range(100):
    z_list = np.array([])
    for i in range(1,101):
        k = 2
        x = cupy.random.chisquare(k, 10*i)
        z = (cupy.mean(x)-k)/cupy.sqrt(2*k) * cupy.sqrt(10*i)
        z = cupy.asnumpy(z)
        z_list = np.append(z_list, z)
    trial_list.append(z_list)

pd.DataFrame(np.asarray(trial_list).reshape(-1,100)).boxplot()
plt.axhline(y=1.96, color='r', linestyle=':')
plt.axhline(y=-1.96, color='r', linestyle=':')
plt.xticks([])
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/d47c1b18-37c7-833a-edcd-c88f3acee2c5.png)

# おわりに
実際に私達が扱うビジネスのデータは完全には正規分布にしたがっていませんし、平均値の推定の精度もそんなに必要ない場合が多いです。したがって、何も考えずに大量データで検定を行うと常に有意となってしまいます。これは統計学が間違っているのではなく、ビジネスへの当てはめ方の問題です。私達は常に、この検定がどのようなビジネスの数値に使用されるのかを気にする必要があります。