後から平均や分散を計算したいとき
大量のデータから平均や分散を計算したいが、全体のデータを分割した部分的なデータの平均や分散は持っているが、全体は捨ててしまっている場合がある。このときはそれぞれのデータ数と標本平均と標本分散から全体の標本平均や標本分散を求めることができる。
計算方法
今、全体のデータ $\mathbf{x}$ が $d$ 個に分割されていて、
$n_i$ 個の値からなるデータ $\mathbf{x}_i$ $(i = 1, \ldots, d)$ になっているとする。
$i$ 番目のデータの標本平均を $E_i$、標本分散(標本不偏分散ではない)を $V_i$ とする。また、$\mathbf{n} := (n_1, \ldots, n_d)^T, \mathbf{E} := (E_1, \ldots, E_d)^T, \mathbf{V} := (V_1, \ldots, V_d)^T$ とする。このとき、全体の標本平均 $E$ と標本分散 $V$ は、
E = \frac{\sum_{i = 1}^d n_i E_i}{\sum_{i = 1}^d n_i} \\
= \text{center}(\mathbf{n}, \mathbf{E}), \\
V = \frac{\sum_{i = 1}^d n_i (V_i + E_i^2)}{\sum_{i = 1}^d n_i} - \left( \frac{\sum_{i = 1}^d n_i E_i}{\sum_{i = 1}^d n_i} \right)^2 \\
= \text{center}(\mathbf{n}, \mathbf{V}) + \text{center}(\mathbf{n}, \mathbf{E} \circ \mathbf{E}) - \text{center}(\mathbf{n}, \mathbf{E})^2
から求めることができる。
ただし、ここで $\text{center}$ は
\text{center}(\mathbf{n}, \mathbf{x}) := \frac{\sum_{i = 1}^d n_i x_i}{\sum_{i = 1}^d n_i}
と定義される、 $\mathbf{x}$ の重心を求める関数で、$\circ$ は要素積である。
このようにして個々の標本平均や標本分散から全体の標本平均や標本分散を復元できる。不偏分散が欲しい場合は、標本分散に直してから全体の標本分散を計算し、不偏分散を求めれば良い。
実装例
Julia 言語での実装例は次のようになる。
# 実装
using LinearAlgebra
center(n, x) = n ⋅ x / sum(n)
umean(n, e) = center(n, e)
uvar(n, e, v) = center(n, v) + center(n, e .* e) - center(n, e)^2
# 使用例
using Statistics
n1 = 10
n2 = 20
x1 = rand(n1)
x2 = rand(n2)
e1 = mean(x1)
e2 = mean(x2)
v1 = var(x1; corrected=false)
v2 = var(x2; corrected=false)
x = cat(x1, x2; dims=1)
n = [n1, n2]
e = [e1, e2]
v = [v1, v2]
mean(x) ≈ umean(n, e) # true
var(x; corrected=false) ≈ uvar(n, e, v) # true
注意点は、分散を求める関数 var の corrected はデフォルトだと true になっており、このままだと標本不偏分散になってしまうので、標本分散を求めるために false を指定することである。また、数値計算上の誤差が積もるため、== で比較しても直に計算したものと一致するとは限らないので、≈ でチェックすると良い。