1. ホーム
  2. プログラマーのための線形代数
  3. 統計学の基本
  4. 分散と標準偏差

分散と標準偏差

ここでは統計学の基本的ツールである分散について解説します。

当ページで学ぶこと

  • 分散とは
  • Pythonで分散を求める
  • 標準偏差とは
  • Pythonで標準偏差を求める
目次

分散とは

確率変数 \(X\) の分散とは、確率論においては、確率分布において確率変数の値が全体的に平均からどれぐらい散らばっているかを示す指標です。これは記号では \({\rm Var}[X]\) と表されます。

たとえば以下のデータがあるとします。

\[\begin{eqnarray}
X_1
&=&
\begin{bmatrix}
1 & 2 & 3 & 4 & 5 & 6
\end{bmatrix}\\
\end{eqnarray}\]

このデータの平均値(期待値)は \(3.5\) です。

分散は、これらのデータと平均値を使って次のように計算します。

\[
{\rm Var}[X] = E[(X-E[X])^2]
\]

具体的には、\(X_1\) の分散は以下の通りに求められます。

\[\begin{eqnarray}
{\rm Var}[X_1]
&=&
\dfrac
{(1-3.5)^2 + (2-3.5)^2 + (3-3.5)^2 + (4-3.5)^2 + (5-3.5)^2 + (6-3.5)^2}
{n}
\\
&=&
\dfrac
{17.5}
{6}
\approx
2.9
\end{eqnarray}\]

このように、分散とは、確率分布の中のそれぞれの値とその値の期待値の差の二乗の期待値であり、データの中身のばらつき具合を示しています。わざわざ二乗するのは、そうすることによって±の符号を気にせず、純粋にデータのばらつき具合のみに注目することができるからです。

以上をまとめると、分散を求めるための式は次のように一般化することができます。

\[\begin{eqnarray}
{\rm Var}[X]
&=&
\sum p(x_1) \times (x_1-E[X])^2, \ p(x_2) \times (x_2-E[X])^2, \cdots, p(x_n) \times (x_n-E[X])^2
\end{eqnarray}\]

なお、コイントスやサイコロ投げのように確率変数のそれぞれの値の確率が全て同様に確からしいときは、以下のよりシンプルな計算式で分散を求めることができます。上述の計算例は、こちらの方法で計算しているものです。

\[\begin{eqnarray}
{\rm Var}[X]
&=&
\dfrac{1}{n} \times \sum (x_1-E[X])^2, \ (x_2-E[X])^2, \cdots, (x_n-E[X])^2
\end{eqnarray}\]

なお統計学では、母分散は母集団から抽出した標本から推定されるのが一般的です。そして標本から推定された母分散は \(\sigma^2\) と表記されます。これは以下のように、\(n-1\) で割ることで求められます。この \(-1\) はバイアスを正すためのものです(バイアスについては自由度についての深い議論になってしまうので詳細は割愛します)

\[\begin{eqnarray}
\sigma^2
&=&
\dfrac{1}{n-1} \times \sum^n_{i=1}(x_i-\mu)^2
\end{eqnarray}\]

Pythonで分散を求める

Python では np.var 関数を使うことで NumPy で作成した配列の分散 \({\rm Var}[X]\) を求めることができます。そして、この関数で標本から母分散を推定したいときは、オプション引数で ddof=1 と指定します。

続いて、以下のコードでは標本から母分散を推定しています。

In [1]:
import numpy as np
# ベクトルを作成
v = np.array([1,2,3,4,5,6])
print(v)
[1 2 3 4 5 6]
In [2]:
# ベクトルの母分散を算出
var = np.var(v, ddof=1)
print(var)
3.5
In [3]:
# 行列を作成
A = np.array([
    [1,2,3,4,5,6],
    [1,2,3,4,5,6]])
print(A)
[[1 2 3 4 5 6]
 [1 2 3 4 5 6]]
In [4]:
# 行列全体の母分散を算出
var= np.var(A, ddof=1)
print(var)
3.1818181818181817
In [5]:
# 行の母分散を算出
r_var=np.var(A, ddof=1, axis=1)
print(r_var)
[3.5 3.5]
In [6]:
# 列の母分散を算出
c_var=np.var(A, ddof=1, axis=0)
print(c_var)
[0. 0. 0. 0. 0. 0.]

標準偏差とは

標準偏差は母分散の平方根を求めたもので、記号の \(s\) で書き表されます。

\[s=\sqrt{\sigma^2}\]

なお、分散はこの標準偏差の記号との関係から \(s^2\) と書き表されることもあります。

Python で標準偏差を求める

Python では NumPy の std 関数を使って標準偏差を求めることができます。var 関数と同じようにオプション引数の ddof=1 と指定すると、標本から推定した母集団の標準偏差を求めることができます。

In [1]:
import numpy as np
# ベクトルを作成
v = np.array([1,2,3,4,5,6])
print(v)
[1 2 3 4 5 6]
In [2]:
# ベクトルの標準偏差を算出
var = np.std(v, ddof=1)
print(var)
1.8708286933869707
In [3]:
# 行列を作成
A = np.array([
    [1,2,3,4,5,6],
    [1,2,3,4,5,6]])
print(A)
[[1 2 3 4 5 6]
 [1 2 3 4 5 6]]
In [4]:
# 行列全体の標準偏差を算出
var= np.std(A, ddof=1)
print(var)
1.7837651700316894
In [5]:
# 行の標準偏差を算出
r_var=np.std(A, ddof=1, axis=1)
print(r_var)
[1.87082869 1.87082869]
In [6]:
# 列の標準偏差を算出
c_var=np.std(A, ddof=1, axis=0)
print(c_var)
[0. 0. 0. 0. 0. 0.]