スタートページJavaScript他言語Python 目次

確率分布関数 scipy


概要

spipy は、Python の高度な科学計算を行うための拡張ライブラリです。そのうち scipy.stats は統計分野のモジュールで豊富な統計分布関数を提供しています。
本ページでは、次の分布を取り上げます。

                 scipy.stats   np.np.random
   正規分布        norm         normal 
   指数分布        expon        exponential
    ポアソン分布    poisson      poisson
   二項分布        binom        binomial
   幾何分布        geom
   超幾何分布      hypergeom
   負の二項分布    nbinom
   カイ二乗分布    chi2
   t分布           t

乱数発生関数は、scipy にも numpy にもあります。単に乱数を得るだけの場合、numpy で記述することが多いようです。
豊富な分布関数を提要しています。ここでは、その代表的な関数の実例を掲げます。

from scipy import stats           # 確率分布関数の利用
import numpy as np                # 乱数発生、配列処理を伴うため
import pandas as pd               # データフレームを使うため
import matplotlib.pyplot as plt   # グラフ表示のため

   「stats.分布名.メソッド( ) 」の形式で関数を呼び出します。

以降の青線部分をGoogle Colaboratryの「コード」部分にコピーアンドペースト(ペーストは Cntl+V)して実行すれば、その結果が表示されます。そのとき、上の3行が記述されているものとします。

主なメソッド

rvs (Random variates) 乱数発生
pdf (Probability density function) 確率密度関数(連続型)
pmf (Probability mass function) 確率質量関数(離散型)
cdf (Cumulative distribution function) 累積分布関数
sf (Survival function) 生存関数
ppf (Percent point function) パーセント点関数
isf (Inverse survival function) 逆生存関数
interval (Endpoints of the range that contains alpha percent of the distribution) 区間推定

引数の記述法

scipy.stats の引数は、順序引数、名前付き引数の両方が使えます。
次の3つが使えます。
    cdf(x=60, loc=50, scale=10) // 基本的な表現 loc: 期待値. 平均、scale:標準偏差
    cdf(60, scale=10, loc=50)   // 名前付き引数の順序は任意
    cdf(60, 50, 10)             // 順序引数

いくつもの関数を記述するとき、毎度同じ「loc=xxx, scale=xxx」を書くのは面倒です。
  frozen を用いることにより簡素化できます。
    rv = scipy.stats.norm(loc=50, scale=10)  // rv は任意の名称
    rv.pdf(60) 
    rv.cdf(60)

正規分布 norm

乱数発生とヒストグラム

# 乱数発生
    # 期待値=50, 標準偏差=10, 個数=100
    #   scipy のとき
    rnd = stats.norm.rvs(loc=50, scale=20, size=100)
    #   Numpy のとき
    rnd = np.random.normal(50, 10, 100)

# ヒストグラム matplotlib.pyplot(plt) を用いる
    # bins: 棒の数、ec: 棒の色、alpha:透明度
    plt.hist(rnd, bins=10, ec='blue', alpha=0.3)
    plt.show()

以下は、x→p,c, s および c, s→x の計算をする関数です。

確率密度関数(x→p) stats.norm.pdf(x, loc=平均, scale=標準偏差)

    # X=x が発生する確率
    # 標準正規分布でx=1 すなわち1σの確率
  p =  stats.norm.pdf(1, loc=0, scale=1)       # 0.242
    # 平均 50, 標準偏差 10 のとき x=60 の確率
  p =  stats.norm.pdf(60, loc=50, scale=10)    # 0.0242

累積分布関数(x→c) stats.norm.cdf(x, loc=平均, scale=標準偏差)

    # 確率変数Xがある値x以下となる確率
    # 標準正規分布で1σ以下の確率
  c = stats.norm.cdf(1, loc=0, scale=1)       # 0.841
    # 平均 50, 標準偏差 10 のとき 60 以下の確率
  c = stats.norm.cdf(60, loc=50, scale=10)    # 0.841

生存関数(x→s) stats.norm.sf(x, loc=平均, scale=標準偏差)

    # 確率変数Xがある値x以上となる確率 sf=1-cdf の関係
    # 標準正規分布で1σ以下の確率
  s = stats.norm.sf(1, loc=0, scale=1)       # 0.158
    # 平均 50, 標準偏差 10 のとき 60 以下の確率
  s = stats.norm.sf(60, loc=50, scale=10)    # 0.158

パーセント点関数(c→x) stats.norm.ppf(c, loc=平均, scale=標準偏差)

    # 累積分布関数cdfの逆関数
  x = stats.norm.ppf(0.842, 0, 1)  # 1
  x = stats.norm.ppf(0.842, 0, 1)  # 60
    # よく使われる値
  x = stats.norm.ppf(0.995, 0, 1)  #  2.575 両側1%
  x = stats.norm.ppf(0.99,  0, 1)  #  2.326 片側1%
  x = stats.norm.ppf(0.975, 0, 1)  #  1.960 両側5%
  x = stats.norm.ppf(0.95,  0, 1)  #  1.644 片側5%
  x = stats.norm.ppf(0.05,  0, 1)  # -1.644 片側5%
  x = stats.norm.ppf(0.025, 0, 1)  # -1.960 両側5%
  x = stats.norm.ppf(0.01,  0, 1)  # -2.326 片側1%
  x = stats.norm.ppf(0.005, 0, 1)  # -2.575 両側1%

逆生存関数(s→x) stats.norm.isf(s, loc=平均, scale=標準偏差)

    # 生存関数 sf の逆関数。s=1-c としたときのパーセント点関数と同じ
  x = stats.norm.isf(0.158, 0, 1)         # 1
  x = stats.norm.isf(0.158, 0, 1)       # 60
    # loc=0, scale=1 のとき、パーセント点関数の正負が逆になる
  x = stats.norm.ppf(0.995, 0, 1)  # -2.575 両側1%
  x = stats.norm.ppf(0.99,  0, 1)  # -2.326 片側1%
  x = stats.norm.ppf(0.05,  0, 1))  #  1.644 片側5%
  x = stats.norm.ppf(0.025, 0, 1)  #  1.960 両側5%

区間推定 lower, upper = stats.norm.interval(alpha, loc=0, scale=1)

    # alpha: 信頼水準  0.99, 0.95 など
    # lowerに信頼下限、upperに信頼上限が戻る
  lower, upper = stats.norm.interval(0.99, 0, 1)   # -2.576 ~ 2.576
  lower, upper = stats.norm.interval(0.95, 0, 1)   # -1.960 ~ 1.960
  lower, upper = stats.norm.interval(0.99, 50, 10) # 34.24 ~ 85.76
  lower, upper = stats.norm.interval(0.95, 50, 10) # 40.40 ~ 79.60

確率密度関数と累積分布関数の作図

# 入力データ(適宜設定)
xmean = 0   # 平均
xsd   = 1   # 標準偏差
# 計算
xmin = -4*xsd+xmean
xmax =  4*xsd+xmean
dx = xsd/10
x = np.arange(start=xmin, stop=xmax, step=dx)
y1 = stats.norm.pdf(x, loc=xmean, scale=xsd)
y2 = stats.norm.cdf(x, loc=xmean, scale=xsd)
# 補助線を引く
xstep = np.arange(xmin, xmax, xsd)
plt.vlines(xstep, 0, 1, linewidth=0.3, linestyle='dashed')
ystep = np.arange(0, 1, 0.1)
plt.hlines(ystep, xmin, xmax, linewidth=0.3, linestyle='dashed')
# 軸線を引く
plt.hlines(0, xmin, xmax, linewidth=1)
plt.hlines(1, xmin, xmax, linewidth=1)
plt.vlines(xmean, 0, 1, linewidth=1)
# グラフ作成
plt.plot(x, y1)
plt.plot(x, y2)
# グラフ表示
plt.show()

指数分布 expon

指数分布の特徴
  期待値(平均)=1/λ, 分散 =1/λ2, 標準偏差 =1/λ 


確率密度関数(x → p)stats.expon.pdf(x, loc=平均, scale=標準偏差)
    # f(x,λ) = λ e-λx
    # 単位時間の間に平均(期待値)で λ回発生する事象において次のx分に事象が発生する確率
    # 平均到着率が1/λのとき、客が到着してから、時間 x に次の客が来る確率
  p = stats.expon.pdf(x, scale=1/1)    # 0.135
    # 2分後に次の客がくる確率は 13.5%

累積分布関数(x → c)stats.expon.cdf(x, loc=平均, scale=標準偏差)
    # F(x,λ) = 1 - e-λx
    # 単位時間の間に平均(期待値)で λ回発生する事象において次のx分までに事象が発生する確率
    # 平均到着率が1/λのとき、客が到着してから次の客が来るまでの時間が x 以内である確率
  c = stats.expon.cdf(x, scale=1/1)    # 0.864
        # 2分後までに次の客がくる確率は 86.4%
    # ある店では、1時間に平均5人の客が来る(客の平均到着間隔は12分である)。
   # 客が来てから次の客が来るまでの間隔が15分以内である確率を求めよ。
  c = stats.expon.cdf(15, scale=12)    # 0.713

逆生存関数(s → x)stats.expon.isf(sx,c, loc=平均, scale=標準偏差)
  x = stats.expon.isf(0.136, scale=1/1)    # 2
    # 確率が13.6%で「2分後までは次の客が来ない」といえる

ポアソン分布 poisson

確率質量関数(x→p) stats.poisson.pmf(x, λ)
    # ポアソン分布は離散型なので pdf ではなく pmf を用いる
    # 単位時間に発生する回数の平均値が λ(=1) のとき、X(=2)回発生する確率 p を求める
  p =  stats.poisson.pmf(2, 1)       # 0.184
    #   x    0      1      2      3      4      5      6
    #   p  0.368  0.368  0.184  0.061  0.015  0.003  0.001

累積分布関数(x→c) stats.poisson.cdf(x, λ)
    # 単位時間に発生する回数の平均値が λ(=1) のとき、発生回数がX(=2)以下の確率 c を求める
  c =  stats.poisson.cdf(2, 1)       # 0.920
    #   x    0      1      2      3      4      5      6
    #   p  0.368  0.736  0.920  0.981  0.996  0.999  1.000

生存関数(x→s) stats.poisson.sf(x, λ)
    # 発生回数がX(=2)以上の確率
  s =  stats.poisson.sf(2, 1)       # 0.080

パーセント点関数(c→x)stats.poisson.ppf(c, λ)
    # cdf の逆関数
  x = stats.poisson.sf(0.920, 1)       # 3
    # 2でなく3になることに注意!

逆生存関数(s→x)stats.poisson.isf(s, λ)
    # sf の逆関数
  x = stats.poisson.isf(0.080, 1)       # 3
    # 2でなく3になることに注意!

二項分布 binom

確率質量関数(x → px)stats.binom.pmf(x, n, p)
    # 1回の試行で発生する確率が p のとき、n 回の試行で x 回発生する確率 px を求める。
    #  サイコロを2個投げたとき、1個が1の目である確率
  px = stats.binom.pmf(1, 2, 1/6)  # 0.2778 ← 2*(1/6)(5/6)
    #  硬貨を5枚投げたとき、表が3枚になる確率
  px = stats.binom.pmf(3, 5, 0.5)  # 0.3125

累積分布関数(x → cx)stats.binom.cdf(x, n, p)
    #  硬貨を5枚投げたとき、表が3枚以下になる確率
  cx = stats.binom.cdf(3, 5, 0.5)  # 0.8125

生存関数(x → sx)stats.binom.sf(x, n, p)
    #  硬貨を5枚投げたとき、表が3枚以上になる確率 sx = 1-cx
  sx = stats.binom.sf(3, 5, 0.5)  # 0.1875

パーセント点関数(cx → x)stats.binom.ppf(cx, n, p)
    # cdf の逆関数
    # 確率81%だと表の個数は何個以下か
  x = stats.binom.ppf(0.8125, 5, 0.5)       # 3

逆生存関数(sx → x)stats.pbinom.isf(sx, n, p)
    # sf の逆関数 確率19%だと表の個数は何個以上か
  x = stats.binom.isf(0.1875, 5, 0.5)       # 3

幾何分布 geom

幾何分布は、ある事象が起こる確率がpのとき、n回の試行により、はじめてその事象が起こる確率を求めます。硬貨やサイコロを投げて、x回目に最初に表や1の目がでる確率を求めます。実務的には1分間に客が来る平均を知っているとき、客が来てから次の客が来るまでの時間xの確率を求めるというようにポアソン分布や指数分布と密接な関係があります。

確率質量関数(x → p)stats.geom.pmf(x, p)
    # 硬貨を3回投げたとき、初めて表が出る(裏-裏-表になる)確率 黒線
  p = stats.geom.pmf(3, 0.5)    # 0.125 =0.5*0.5*0.5
    # サイコロを5回投げたとき、初めて1の目が出る確率 赤線
  p = stats.geom.pmf(5, 1/6)    # 0.080
    # ある災害は平均3年に1度発生するという。4年後に次の災害が発生する確率(3年間は無発生) 青線
  p = stats.geom.pmf(4, 0.3)    # 0.103

累積分布関数(x → c)stats.geom.cdf(x, p)
    #  硬貨を3回投げたとき、それまでに表が出る(2回、3回表のこともある)確率 黒線
  c = stats.geom.cdf(3, 0.5)    # 0.875
    # ある災害は平均3年に1度発生するという。災害発生後、次の4年間に災害が発生する確率 青線
  c = stats.geom.cdf(4, 0.3)    # 0.760

パーセント点関数(c → x)stats.binom.ppf(c, p)
    # サイコロを投げて、50%の確率で1の目が出るようにするには何回投げる必要があるか 赤線
  x = stats.geom.ppf(0.5, 1/6)  # 9

超幾何分布 hypergeom

超幾何分布とは、次のような問題を扱います。
「袋の中に、赤玉と白玉が入っている。全体でN個、赤玉M個、白玉N-M個である。これから無作為にn個を取り出したとき、赤玉がx個である確率を求めよ。」

確率質量関数(x → p)  stats.hypergeom.pmf(x, N, n, M)
    # 赤玉3個、白玉4個が入っている袋から、2個取り出したとき、赤玉が1個である確率
  p = stats.hypergeom.pmf(1, 3+4, 2, 3)   # 0.5714
       # x     0       1       2
       # p   0.2857  0.5714  0.14285 (合計=1)

累積分布関数(x → c)  stats.hypergeom.cdf(x, N, n, M)
    # 赤玉3個、白玉4個が入っている袋から、2個取り出したとき、赤玉が含まれている確率
  c = stats.hypergeom.cdf(1, 3+4, 2, 3)   # 0.8571 = 0.2857 + 0.5714

パーセント点関数(c → x)   stats.hypergeom.ppf(c, N, n, M)
    # 赤玉3個、白玉4個が入っている袋から2個取り出すとき、確率80%で赤玉はいくつ含まれているか
  x = stats.hypergeom.ppf(0.8, 3+4, 2, 3)   # 1 (2個取り出したとき、赤玉が含まれている確率が85.7%)

負の二項分布 nbinom

負の二項分布は、幾何分布の「ある事象が1回起こるまでの試行回数」を「ある事象がr回起こるまでの試行回数:に拡張したものです。次の関係があります。
    stats.nbinom.pmf(x, 1, p) = tats.geom.pmf(x+, p)
1回での試行である事象が発生する確率がpのとき、その事象が初めてr回発生するまで試行を繰り返します。x回試行したときの実現確率を求めます。
例えば「硬貨が3回表になるまで繰り返すとき、5回投げたときにはじめて表が3回になる確率を求めよ」は、x=5, r=3, p=0.5 になります。

当然ながら、試行回数がr未満で実現することはありません。それで、現在r回の試行をしており、あとx(0~)回試行するということになります。

確率質量関数(x → px)stats.nbinom.pmf(x, r, p)
    # 硬貨を投げる試行で5回目(x=5-3=2)で初めて表が3回になる確率
  px = stats.nbinom.pmf(2, 3, 0.5)    # 0.188
    # サイコロを5回投げたときに、初めて1の目が2回でる確率 x=5-2=3
  px = stats.nbinom.pmf(3, 2, 1/6)    # 0.064

累積分布関数(x → cx)stats.nbinom.cdf(x, r, p)
    # 5回硬貨を投げたとき、それまでに表が3回になる確率(5回目には表が4回になっているかもしれない)
  cx = stats.nbinom.cdf(2, 3, 0.5)    # 0.5 = pmf(0, 3, 0.5) + pmf(1, 3, 0.5) + pmf(2, 3, 0.5)
    # サイコロを5回投げたときに、初めて1の目が2回でる確率 x=5-2=3
  cx = stats.nbinom.cdf(3, 2, 1/6)    # 0.196

パーセント点関数(cx → x)stats.binom.ppf(cx, n, p)
    # 硬貨を投げて、確率80%で表が3回以上になるには何回投げる必要があるか
  x = stats.nbinom.ppf(0.8, 3, 0.5)       # x=5   最初からでは 5+3=8回
<.pre>


カイ二乗(χ2)分布 chi2

パーセント点関数(c→x)stats.chi2.ppf(確率, 自由度)
    # 自由度φ=3のとき、下方が95%になる点はx≦7.81になる
  x1 = stats.chi2.ppf(0.95, 3)  # 7.8147
    # 下方が5%になる点はx≦0.35になる
  x2 = stats.chi2.ppf(0.05, 3)  # 0.3518

逆生存関数(1-c=s→x)stats.chi2.isf(確率, 自由度)
    # 自由度φ=3のとき、上方が95%になる点はx≧0.35になる
  x1 = stats.chi2.isf(0.95, 3)  # 0.3518
    # 下方が5%になる点はx≧7.81になる
  x2 = stats.chi2.isf(0.05, 3)  # 7.8147


累積分布関数(x→c) stats.chi2.cdf(x, 自由度)
    # 自由度φ=3のとき、x≦7.81となる確率は95%である
  c1 = stats.chi2.cdf(7.81, 3)  # 0.95
    # x≦0.35となる確率は5%である
  c2 = stats.chi2.cdf(0.35, 3)  # 0.05

区間推定 lower, upper = stats.chi2.interval(信頼確率, 自由度)
    # 自由度φ=3のとき、確率90%(両側が5%)で 下0.35≦x≦7.81 になる
  lower, upper = stats.chi2.interval(0.9, 3)   # 0.3518  7.8147

カイ二乗(χ2)検定

検定ではp値が重要です。
検定では「比較する両者の間に差がない」という帰無仮説が棄却されるか否かで判断します。計算で得たp値は「帰無仮説が成立する=差がない」ことが発生する確率です。
p値が小さい(p≦0.05)ならば、「帰無仮説が成立する」確率が稀なので棄却され、「差がある」といえます。この5%を危険度あるいは95%を信頼度といい、有意差があるといいます。
逆に、p≧0.05なば、「差がない」ことが棄却されないので「差があるとはいえない(有意差がない)」ことになります。これは積極的に「差がない」ことにはなりません。しかし、p≒1 に近いならば「差がない」ことがよく発生するということなので、厳密ではないが「差が小さいらしい」程度の判断になります。

標本分散と母分散の一致性

考え方
 上記の x は、次のような物理量である。
   x = 自由度*標本分散/母分散
    ∴ 母分散 = 自由度*標本分散/x
 母分散の信頼区間を求めるには、次の操作をすればよい
   自由度 * 標本分散 / stats.chi2.interval(信頼確率, 自由度)

数値例
    # 標本 = [1, 2, 3, 4, 5]
    # 自由度 φ = 5-1 =4
  # 標本分散 μ= ((1-3)2+ … +(5-3)2)/5 = 2.5
  # 信頼確率 a = 95%での母分散 μ0 の信頼区間を求める
  x1, x2 = stats.chi2.interval(0.05, 4)  # 3.20, 3.52
  upper = 4*2.5/x1   # 3.13
  lower = 4*2.5/x2   # 2.84

    # 上側2.5%点
  x1 = stats.chi2.ppfl(0.025, 4) # 0.484
  2,5*10/0.484 = 20.64
      # 上側2.5% は μ0≧20.64 の場合である
    # 下側2.5%点
  x2 = stats.chi2.ppfl(0.975, 4) # 11.14 
  2,5*10/11.14 = 0.8974
      # 下側2.5% は μ0≦0.8974 の場合である
 したがって母分散 μ0 は信頼確率95%で 0,90~11.1 の間にあるといえる。

独立性の検定

「勉強好きの学生と勉強嫌いの学生の試験の合格/不合格の結果がある。
         合格  不合格
   勉強好き  30  70
   勉強嫌い  20  80
これから、勉強の好き嫌いは合格に関係があるだろうか」というような問題です。
「勉強の好き嫌い」の変数と「合格/不合格」の変数の間に関係がない(独立性がある)ことの検定です。

stats.chi2_contingency関数を用います。

chi2, p, dof, expected = chi2_contingency( df, correction=False)

パラメタ
    df: 二次元配列のデータ
       data = np.array([30, 70], [20, 80])
    correction: 計算の方法、省略時はイエーツの修正を行うで、行わないときは False にする、
実行
    chi2, p, dof, expected = stats.chi2_contingency(data) 
戻り値
    chi2: カイ二乗値    # 2.16
    p:    p値           # 0.1416
    dof:  自由度        # 1
    expected: 期待度数  # [[25, 75], [25,75]]
p値
    p ≦ 0.05 ならば危険確率5%で帰無仮説(差がない、独立している)棄却。独立している
    ここでは p ≧ 0.05 なので棄却されない。独立していないとは結論付けられない。  

---------
p値大(独立していない)例
    data = np.array([[1, 2, 3, 4, 5], [2, 2, 3, 4, 5]])
        # p:  0.99

p値小(独立している)例
    data = np.array([[1, 2, 3, 4, 5], [5, 3, 2, 0, 0]])
        # p:  0.021

適合度検定

「サイコロを60回投げたとき、どの目が出るかは理論的にはすべて同じで10回になります。
ところが実際に投げたときは、バラバラでした。
  理論値 = [10, 10, 10, 10, 10, 10]
    実現値 = [ 9, 11,  8, 12, 10, 10]
このサイコロは正しいかどうか?」というような検定です。

stats.chisquare 関数を用います。

    statistic, pvalue = stats.chisquare(実現値, 理論値) # 順序がどちらでも同じ結果になります。
        # pvalue = 0.963≧0.05  帰無仮説(差がある)は棄却できない
        # イカサマだと結論づけることはできない

---------
近似式の検定
「(x1,y1)~(x5,y5) の5点について、近似式 y = f(x) を設定した。この近似式はよく適合しているか?
      x    1  2  3  4  5
      y    3  6  6 10 12
     fx    3  5  7  9 11」

statistic, pvalue = stats.chisquare([3, 6, 6, 10, 12], [3, 5, 7, 9, 11])
pvalue = 0.969 ≒1 一致していないとはいえない( p≒1 なのでよく適合しているといえよう)

t分布 t

自由度(標本数-1)φ = 10 確率密度関数と累積分布関数を示します。
横軸のαは 平均からの差/標準偏差 の値です。確率密度関数は標準正規分布と似たような形状です。

累積分布関数(α → c)stats.t.cdf(α, φ)
    # α=1.812 のとき c=0.95 になる→95%はα≦1.812にある
  c = stats.t.cdf(1.812, 10)  # 0.95

生存関数(α → c)stats.t.sf(α, φ)
    # α=1.812 のとき s=0.05 になる→はα≧1.812になるのは5%である。
  c = stats.t.sf(1.812, 10)  # 0.05

パーセント点関数(c→x)stats.t.ppf(c, φ)
    # 95% は α≦1.812 にある
  α = stats.t.ppf(0.95, 10)  # 1.812

逆生存関数(s→α)stats.t.isf(c, φ)
    # 大きいほうからの 5% は α≧1.812 にある
  α = stats.t.isf(0.05, 10)  # 1.812 

区間推定 lower, upper = stats.t.interval(alpha, φ)
    # alpha: 信頼水準  0.99, 0.95 など
    # lowerに信頼下限、upperに信頼上限が戻る
  lower, upper = stats.t.interval(0.95, 10)   # -2.228, 2.228
  lower, upper = stats.t.interval(0.975, 10)  # -2.634, 2.634

t検定

検定ではp値が重要です。
検定では「比較する両者の間に差がない」という帰無仮説が棄却されるか否かで判断します。計算で得たp値は「帰無仮説が成立する=差がない」ことが発生する確率です。
p値が小さい(p≦0.05)ならば、「帰無仮説が成立する」確率が稀なので棄却され、「差がある」といえます。この5%を危険度あるいは95%を信頼度といい、有意差があるといいます。
逆に、p≧0.05なば、「差がない」ことが棄却されないので「差があるとはいえない(有意差がない)」ことになります。これは積極的に「差がない」ことにはなりません。しかし、p≒1 に近いならば「差がない」ことがよく発生するということなので、厳密ではないが「差が小さいらしい」程度の判断になります。

母平均との比較

成人男性10人を無作為に選び身長を測定したところ、次の結果を得た。
  170, 175, 165, 180, 175, 155, 165, 170, 160, 185 [cm]
→ 平均 μ=170, 標準偏差 σ=9, 自由度 φ=10-1=9

  α = stats.t.isf(0.05, 9)  # 1.833
   x = μ ± ασ = 170 ± 9*1.833 = 153.5, 186.5

結論
  大きいほうから2.5%は身長 186.5 以上である
  大きいほうから2.5%は身長 153.5 以下である
  全体の95%は 153.5 ~ 186.5 の間にある     信頼区間

----------

標本データと母平均の比較
    # 次の標本データがある。母平均が 180cm であるといえるか
  x  = [170, 175, 165, 180, 175, 155, 165, 170, 160, 185]
  t, p = stats.ttest_1samp(a, popmean=180)
      # t=-3.464  p= 0.007 ≦ 0.05 差がない(180cm である)との帰無仮説が棄却された。180cmとはいえない 
      # popmean  180     175    170
      #  p値    0.007   0.117   1.0  

2集団の平均の差の検定

[注意]以下 alternative で片側検定もできるような記述がありますが、SciPy のバージョンにより、この機能がなく、
    すべて両側検定になることがあります(執筆現在の私の環境もこの機能がありません)。

2つの集団に対応がない場合(要素数が異なっていてもよい) stats.ttest_ind

既に統計値が計算されている場合

statistic, pvalue = stats.ttest_ind_from_stats(
    # 集団1
    mean1=平均,
    std1=標準偏差,
    nobs1=要素数,
    # 集団2
    mean2=平均,
    std2=標準偏差,
    nobs2=平均,
    # 共通
    alternative = 'two-sided',  # デフォルトは両側検定 'less’greater’
                                # バージョンによってはサポートされていない。両側検定だけになる。
    equal_var = True,           # True:スチューデントのt検定。 母分散が等しいと仮定。
                                # False;ウェルチのt検定を実行(このほうがよいとのこと)
                                # 母分散が等しいとは想定していません
}

statistic, pvalue = stats.ttest_ind_from_stats(
    mean1=5, std1=1, nobs1=10,
    mean2=6, std2=2, nobs2=15,
    equal_var = True,
)
pvalue # 0.159  集団1>集団2、集団2<集団1の場合もある ↓


-----------

標本データから統計量を計算する場合

statistic, pvalue = tats.ttest_ind(
    a, b,
    alternative = 'two-sided',  # デフォルトは両側検定 'less’greater’
    equal_var = True,           # True:スチューデントのt検定。 母分散が等しいと仮定。
                                # False;ウェルチのt検定を実行(このほうがよいとのこと)
                                # 母分散が等しいとは想定していません
                           # 以降は通常デフォルト
    axis = 0,                   # テストを計算するための軸。Noneの場合、配列全体、a、およびbを計算。
    nan_policy = 'propagate',   # 入力にnanが含まれている場合の処理​​方法を定義。通常は省略」
    permutations = None,        # デフォルトの場合、t分布を使用してp値を計算
    random_state = None,        # 
    trim = 0                    #
)

「2つのクラスで試験を行った。
    クラスA = [50, 60, 70, 80, 90]
    クラスB = [40, 50, 70, 80, 80, 90, 90]
  成績に差があるといえるか」

  statistic, pvalue = stats.ttest_ind(クラスA, クラスB, equal_var = False)
  pvalue   # 0.196

2つの集団に対応がある場合 stats.ttest_rel

diff = a-b とすれば、0との比較になり、以下と等価になる
stats.ttest_ind(diffs, np.zeros(len(diffs)), ~)

statistic, pvalue = tats.ttest_ind(
    a, b,
    alternative = 'two-sided',  # デフォルトは両側検定 'less’greater’
    equal_var = True,           # True:スチューデントのt検定。 母分散が等しいと仮定。
                                # False;ウェルチのt検定を実行(このほうがよいとのこと)
                                # 母分散が等しいとは想定していません
                           # 以降は通常デフォルト
    axis = 0,                   # テストを計算するための軸。Noneの場合、配列全体、a、およびbを計算。
    nan_policy = 'propagate',   # 入力にnanが含まれている場合の処理​​方法を定義。通常は省略」
)

「特定の学生を対象に、昨年度の成績と今年度の成績を調べた。
    学生      A  B  C  D  E  F
    昨年度 = [5, 4, 4, 3, 3, 3]
    今年度 = [5, 5, 5, 5, 5, 3]
変化があったといえるか」

  statistic, pvalue = stats.ttest_ind(昨年度, 今年度,
      equal_var = False
  )
    pvalue   # 0.059 > 0.05 ではあるが、変化があったといってよい