標本誤差が気になった件について

この記事は[古川研究室 Advent_calendar](https://qiita.com/advent-calendar/2019/flab) 21日目の記事です。
本記事は古川研究室の学生が学習の一環として書いたものです。内容が曖昧であったり表現が多少異なったりする場合があります。

# はじめに
統計について全然詳しくないんですが，Twitterでサーフィンを楽しんでいるときに「中学生200人に聞いた将来の夢ランキング！(こんなんじゃなかったかもだけどｗ)」みたいなランキング画像付きツイートをみて，200人でわかるもんなんかね？って疑問を持ちました．同じことを思った人がいたのかリプライで「200人とか調査になってなくない？」なんてコメントがついてたんですがそれに対するリプライで「信頼区間95%で標本誤差10%以内になってるし調査にはなってるよ」といったものがありました。聞いたことあるし大学の授業でやった覚えがあるけど…残念ながら思い出せなかったのでgoogle先生に聞いてみることに…

# 標本誤差
標本誤差とは標本から母集団における数値を推定するときに伴う誤差のことである．ふむふむ…習った気がする．テストで信頼区間がどーたらって問題あったな、って記憶がかすかによみがえりました．
[こちらのサイト](http://kenkou888.com/category13/sample_suu.html)が分かりやすくさっきの例で実際に計算してみると…

```math
\begin{align}
\bar{p}=0.5\\
n=200\\
1.96\sqrt{\cfrac{\bar{p}(1-\bar{p})}{n}}&=1.96\sqrt{\cfrac{0.5(1-0.5)}{200}}\\
&=0.0692924...
\end{align}
```

標本誤差7%になるみたいです．(ちなみにサンプル100個で10%くらいになった、うっそやろおい)
標本誤差の考え方は意識しておいた方がいいなあって思いましたまる

# こっからはおまけのお遊び(本文短っｗ)
完全に無作為に選ばれたサンプルであればいいと聞いて…
母集団としてSaddle shapeのデータを用意してあげてそっからランダムな標本どのくらい用意してあげたら本来のSaddle shapeを推定できるのっと…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458318/1dfee412-a44c-11e1-be4f-3604189d4856.png)

```python
import numpy as np

    map_size = 60
    def create_data(nb_samples, input_dim=3, retdim=False):
        latent_dim = 2
        z1 = np.random.rand(nb_samples) * map_size - map_size/2
        z2 = np.random.rand(nb_samples) * map_size - map_size/2

        x = np.zeros((nb_samples, input_dim))
        x[:, 0] = z1
        x[:, 1] = z2
        x[:, 2] = z1 ** 2 - z2 ** 2

        if retdim:
            return x, latent_dim
        else:
            return x

    # parameters to make data
    x_sigma = 0.1
    nb_samples = 900
    seed = 1

    # make data
    np.random.seed(seed)
    X = create_data(nb_samples)
    X += np.random.normal(0, x_sigma, X.shape)
```

こんなかんじでSaddle shapeを作成！900サンプルからスタートしてガウス過程回帰を使って30*30のノード点を推定してみる
X軸，Y軸の座標からZ軸を推定するね！分散入れて描画すると大変なことになるから平均を青点でプロットしました！

```python
from matplotlib import pyplot as plt
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process import kernels as sk_kern
    x_input = X[:,:2]
    y_input = X[:,2]
    kernel = sk_kern.RBF(1.0, (1e-3, 1e3))  # + sk_kern.ConstantKernel(1.0,(1e-3,1e3)) + sk_kern.WhiteKernel()
    clf = GaussianProcessRegressor(
        kernel=kernel,
        alpha=1e-10,
        optimizer="fmin_l_bfgs_b",
        n_restarts_optimizer=20,
        normalize_y=True)

    clf.fit(x_input,y_input )
    clf.kernel_

    test_x = np.linspace(-map_size/2,map_size/2,30)
    test = np.meshgrid(test_x,test_x)
    test=np.dstack(test).reshape(900,2)

    pred_mean, pred_std = clf.predict(test, return_std=True)

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, aspect='equal', projection='3d')
    ax.scatter(X[:,0],X[:,1],X[:,2],color='r')
    ax.scatter(test[:,0],test[:,1],pred_mean)
    plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458318/9368f7a1-bb4e-86e9-9a63-59c68e178479.png)

まあそら900点こんだけびっしりありゃできますわな、さっきの式で計算したら誤差は3%くらいらしいですわ
こっからはサンプル数少ないほうから
まずは50!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458318/5cbbddd1-5094-1016-9823-3371d70349df.png)
ふむふむ…ぐにゃぐにゃやんな
ちなみにさっきの式での標本誤差は約14%
お次は100!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458318/1df55fdc-90c5-1200-a012-05198da5d3dc.png)
鞍っぽい形してるぞ！！さすが10%
200もやってみよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458318/eef01f12-9a77-ea6d-52a0-ed01fa5bb083.png)
多少股ずれ？はおこりそうだけど十分乗れるやん！
誤差は7%
400で最後にするか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458318/ce092f3d-d1f3-989e-a3e1-a98bb2c8d45f.png)
え、これ900と遜色なくない？

# まとめ
標本誤差の考え方って面白いなーって思いました！(こんなんに統計学のタグ付けて怒られたりしないかなってビクビクしてる)
ちょっといそがしくておまけの章は全然厳密な実験計画立ててないからなんとなくそれっぽい図を貼りまくってるだけで全然意味が無かったりするのはご愛敬ですm(_ _)m