11月28日のレポートにおける質問(要求)と回答です。

(1) 講義における修正がよくわからなかった。もう一度書いてほしい。

回答: ウェブでも書いておくべきでした。次のセルが修正前の内容です。

In [1]:
%matplotlib inline
import numpy as np
from scipy import stats as st
import matplotlib.pyplot as plt

x = np.linspace(-4, 4, 10000)
plt.plot(x, stats.norm.pdf(x,0,1), label=r'N(%i,%i)$' % (0,1))  # statsを使用
plt.axis([-4,4,-0.02,0.5]) 
plt.axhline(0,c='g',ls='-.')
plt.axvline(-2,c='b',ls='--')
plt.axvline(2,c='b',ls='--')
x = np.linspace(-2, 2, 10000)
plt.fill_between(x, stats.norm.pdf(x,0,1)) # statsを使用
plt.show()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-febf876155a8> in <module>
      5 
      6 x = np.linspace(-4, 4, 10000)
----> 7 plt.plot(x, stats.norm.pdf(x,0,1), label=r'N(%i,%i)$' % (0,1))  # statsを使用
      8 plt.axis([-4,4,-0.02,0.5])
      9 plt.axhline(0,c='g',ls='-.')

NameError: name 'stats' is not defined

問題はstats.norm.pdfと書いているにもかかわらず、statsが定義されていないため、このようにエラーになります。ここは以下のように、statsではなく(定義した)stを使うべきでした。

In [2]:
%matplotlib inline
import numpy as np
from scipy import stats as st
import matplotlib.pyplot as plt

x = np.linspace(-4, 4, 10000)
plt.plot(x, st.norm.pdf(x,0,1), label=r'N(%i,%i)$' % (0,1))
plt.axis([-4,4,-0.02,0.5]) 
plt.axhline(0,c='g',ls='-.')
plt.axvline(-2,c='b',ls='--')
plt.axvline(2,c='b',ls='--')
x = np.linspace(-2, 2, 10000)
plt.fill_between(x, st.norm.pdf(x,0,1))
plt.show()

(2) st.norm.pdfのカッコ内に入れる数字について,解説が欲しいです

回答: 資料には次のように書きました(演習問題の直前)

関数のまとめ

注: numpyをnp, np.randomを random、 matplotlib.pyplotをplt、pandasをpd、scipy.statsをstと略記する

目的 関数名とモジュール 使い方
一様分布に従う乱数(復習) random.random(個数) random.random(10) # [0,1)の乱数を10個
正規分布に従う乱数 random.normal(平均,標準偏差,個数) random.normal(50,10,10) # N(50, 10^2)に従う乱数10個
指定の範囲の数の生成 np.linspace(最小値,最大値,個数) np.linspace(35, 65, 10000) # [35,65]の範囲の数を10000個
正規分布の密度関数 st.norm.pdf(xデータ,平均,標準偏差) plt.plot(x, st.norm.pdf(x,50,10.0**0.5)) # $N(50,\sqrt{10})$の正規分布の関数描画

つまり、

  1. $N(\mu,\sigma^2)$のグラフを書きたければscipy.stats.norm.pdf(x,$\mu$,$\sigma$)
  2. $N(\mu,\sigma^2)$に従う乱数を$n$個生成したければnumpy.random.norm($\mu$,$\sigma$,n)

をそれぞれ使うのです。注意すべきはscipy.stats.norm.pdfもnumpy.random.normも「分散」ではなく「標準偏差」を引数に取る、ということです

(3) ヒストグラムを書いたときに出る赤いエリアの文字って何かわかりますか。

回答: matplotlibのバージョンがあがって、今まで引数オプションとして使われていたnormedではなくdensityを使うことになった、という警告です。 いかにその例を示します。

In [3]:
import numpy as np
import numpy.random as random
from scipy import stats as st
import matplotlib.pyplot as plt
%matplotlib inline

meanArray = np.array([ np.mean(random.normal(50, 10.0, 10)) for _ in range(10000)])
plt.hist(meanArray,normed=True, ec='k')  # normedオプションを指定
x = np.linspace(35, 65, 10000)
plt.plot(x, st.norm.pdf(x,50,10.0**0.5), ls='--',label=r'$N(%i,%i^2)$' % (50,10))
plt.grid()
plt.legend()
plt.show()
/opt/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:8: MatplotlibDeprecationWarning: 
The 'normed' kwarg was deprecated in Matplotlib 2.1 and will be removed in 3.1. Use 'density' instead.
  

このように警告が出ました。ちゃんと'normed'ではなく'density'を使え、と書いてあります。(警告はエラーではありません)

In [4]:
import numpy as np
import numpy.random as random
from scipy import stats as st
import matplotlib.pyplot as plt
%matplotlib inline

meanArray = np.array([ np.mean(random.normal(50, 10.0, 10)) for _ in range(10000)])
plt.hist(meanArray,density=True, ec='k')  # normedの代わりにdensityを指定
x = np.linspace(35, 65, 10000)
plt.plot(x, st.norm.pdf(x,50,10.0**0.5), ls='--',label=r'$N(%i,%i^2)$' % (50,10))
plt.grid()
plt.legend()
plt.show()

このように、今度は警告が出ません。以降はこれに注意してコードを書きましょう。

(4) グラフの書き方の解説をもう一度してほしいです。複数の標本分布の形状を表示する方法が分かりませんでした。

これをやっているともう1時間くらかかってしまいます。復習したり、Web検索で調べてみてください。 複数の標本分布の表示については以下を比べてみてください。
In [2]:
# すべてを重ね書きする
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as st
x =  np.linspace(-3,3,1000)

for n in range(1,6):
    plt.plot(x,st.norm.pdf(x,0,(1/n)),label=r"$n=%i^2$"%(n))
plt.xlabel('x')
plt.ylabel('norm(x,0,np.sqrt(1/n))')
plt.legend()
plt.show()
In [8]:
# 別々に表示
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as st

x =  np.linspace(-3,3,1000)
for n in range(1,6):
    plt.plot(x,st.norm.pdf(x,0,(1/n)),label=r"$n=%i^2$"%(n))
    plt.xlabel('x')
    plt.ylabel('norm(x,0,np.sqrt(1/n))')
    plt.legend()
    plt.show()
In [13]:
# 別々に表示
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as st

x =  np.linspace(-3,3,1000)
plt.figure(figsize=(12,6))
for n in range(1,6):
    plt.subplot(2,3,n)
    plt.plot(x,st.norm.pdf(x,0,(1/n)),label=r"$n=%i^2$"%(n))
    plt.xlabel('x')
    plt.ylabel('norm(x,0,np.sqrt(1/n))')
    plt.legend()
plt.show()