閉じる

NumPyで標準偏差(std)と分散(var)を計算する方法:引数ddofやaxisの使い分けを解説

データ分析や機械学習において、データのばらつきを正しく把握することは極めて重要です。

Pythonの数値計算ライブラリであるNumPyは、膨大なデータセットに対して高速に分散や標準偏差を計算するための強力な関数を提供しています。

本記事では、NumPyのstd関数とvar関数に焦点を当て、基本的な使い方から実務で欠かせないddofaxisといった引数の詳細な仕様までを網羅的に解説します。

最新のデータサイエンスの現場でも多用されるこれらの機能をマスターし、より正確なデータ解析を実現しましょう。

NumPyにおける統計計算の重要性

データサイエンスの分野において、NumPyは数値計算の基盤となるライブラリです。

特にデータの中心傾向を示す平均値だけでなく、データの「広がり」を示す分散や標準偏差の計算は、データの特性を理解するための第一歩となります。

NumPyを使用することで、Python標準のリストやループ処理を用いるよりも圧倒的に高速かつ簡潔な記述で計算を行うことが可能です。

2026年現在のAI・データ分析シーンにおいても、NumPyの効率的な多次元配列操作は、ディープラーニングの前処理や統計モデリングにおいて不可欠なスキルであり続けています。

分散(var)と標準偏差(std)の基本概念

計算方法を学ぶ前に、まずは統計学的な意味を簡単におさらいしておきましょう。

分散(Variance)とは何か

分散とは、データの個々の値が平均値からどの程度離れているかを表す指標です。

各データ値と平均値の差(偏差)を2乗し、それらを平均することで算出されます。

分散の値が大きいほど、データが広く散らばっていることを意味します。

逆に分散が小さい場合は、データが平均値の周辺に密集していることを示します。

標準偏差(Standard Deviation)とは何か

標準偏差は、分散の正の平方根をとった値です。

分散は2乗の計算を含むため、単位が元のデータとは異なってしまいます。

標準偏差は元のデータと同じ単位で扱えるため、直感的にデータのばらつきを理解する際に非常に便利です。

正規分布に従うデータの場合、平均値からプラスマイナス1標準偏差の範囲内に約68%のデータが含まれるといった性質があります。

NumPyでの基本的な実装方法

NumPyで分散を計算するにはnumpy.var()、標準偏差を計算するにはnumpy.std()を使用します。

numpy.var関数の使い方

まずは、基本的な1次元配列に対する分散の計算例を見てみましょう。

Python
import numpy as np

# サンプルデータの作成
data = np.array([10, 20, 30, 40, 50])

# 分散の計算
variance = np.var(data)

print(f"データの分散: {variance}")
実行結果
データの分散: 200.0

このように、関数に配列を渡すだけで簡単に計算結果を得ることができます。

numpy.std関数の使い方

同様に、標準偏差も1つの関数呼び出しで計算可能です。

Python
import numpy as np

# サンプルデータの作成
data = np.array([10, 20, 30, 40, 50])

# 標準偏差の計算
std_dev = np.std(data)

print(f"データの標準偏差: {std_dev}")
実行結果
データの標準偏差: 14.142135623730951

計算結果は分散(200)の平方根である約14.14となっていることが分かります。

自由度(ddof)の理解と使い分け

NumPyの統計計算において最も注意すべき点が、自由度(ddof: Delta Degrees of Freedom)の設定です。

母分散と不偏分散の違い

統計学には「母分散」と「不偏分散」という2つの概念が存在します。

母分散は、対象となる全データ(母集団)が手元にある場合に使用します。

不偏分散は、母集団から抽出された一部のデータ(標本)を用いて、母集団の分散を推定する場合に使用します。

不偏分散では、平均からの偏差の2乗和を「データ数 – 1」で割ることで、推定の偏りを修正します。

ddof引数による調整

NumPyのデフォルト設定では、ddof=0となっており、母分散を計算するようになっています。

しかし、統計学の標準的なテキストやPandasといった他のライブラリでは、デフォルトで不偏分散(n-1で割る設定)が採用されていることが多いです。

不偏分散(または不偏標準偏差)を求めたい場合は、必ずddof=1を明示的に指定してください。

Python
import numpy as np

data = np.array([10, 20, 30, 40, 50])

# デフォルト(ddof=0): 母分散
var_pop = np.var(data)

# 不偏分散(ddof=1): 標本分散
var_sample = np.var(data, ddof=1)

print(f"母分散 (ddof=0): {var_pop}")
print(f"不偏分散 (ddof=1): {var_sample}")
実行結果
母分散 (ddof=0): 200.0
不偏分散 (ddof=1): 250.0

この結果からわかる通り、ddofの指定一つで値が大きく変わるため、解析の目的に合わせて慎重に選択する必要があります。

多次元配列におけるaxis引数の活用

実務では、行列形式のデータ(多次元配列)を扱う機会が非常に多いです。

その際、どの方向に沿って計算するかを制御するのがaxis引数です。

行方向・列方向の計算

2次元配列(行列)を例に挙げると、axis=0は列ごとの計算、axis=1は行ごとの計算を意味します。

Python
import numpy as np

# 3行2列の配列を作成
matrix = np.array([
    [10, 20],
    [30, 40],
    [50, 60]
])

# 列ごとの標準偏差(各列の特徴量を分析する場合など)
std_axis0 = np.std(matrix, axis=0)

# 行ごとの標準偏差(各サンプルごとのばらつきを見る場合など)
std_axis1 = np.std(matrix, axis=1)

print(f"列ごとの標準偏差: {std_axis0}")
print(f"行ごとの標準偏差: {std_axis1}")
実行結果
列ごとの標準偏差: [16.32993162 16.32993162]
行ごとの標準偏差: [5. 5. 5.]

axisを省略した場合は、配列内のすべての要素をフラットにした状態での全体の統計量が算出されます。

keepdims引数のメリット

axisを指定して計算すると、通常は結果の配列の次元が一つ減ります。

しかし、元の配列との演算(ブロードキャスト)を行いたい場合には、次元を維持しておくと便利です。

その際は、keepdims=Trueを設定します。

Python
# keepdimsを使用した場合
std_keep = np.std(matrix, axis=0, keepdims=True)

print(f"形状(通常): {std_axis0.shape}")
print(f"形状(keepdims=True): {std_keep.shape}")
実行結果
形状(通常): (2,)
形状(keepdims=True): (1, 2)

これにより、元の行列との引き算や割り算が非常にスムーズに行えるようになります。

実践的なデータ処理:標準化(Standardization)

分散と標準偏差の最も一般的な応用例の一つが「データの標準化」です。

標準化とは、データの平均を0、標準偏差を1に変換する処理を指します。

これにより、単位の異なる複数の特徴量を同じスケールで比較できるようになります。

Python
import numpy as np

# サンプルデータ(各列が異なる特徴量とする)
X = np.array([
    [1, 200],
    [2, 300],
    [3, 400]
])

# 平均と標準偏差の計算(列方向)
mean = np.mean(X, axis=0)
std = np.std(X, axis=0)

# 標準化の実行
X_scaled = (X - mean) / std

print("標準化後のデータ:")
print(X_scaled)
実行結果
標準化後のデータ:
[[-1.22474487 -1.22474487]
 [ 0.          0.        ]
 [ 1.22474487  1.22474487]]

このようにNumPyのブロードキャスト機能とstd関数を組み合わせることで、簡潔なコードで前処理を記述できます。

注意点とパフォーマンスの最適化

計算を行う上での技術的な注意点もいくつか存在します。

欠損値(NaN)の扱い

NumPyの標準的なstdvarは、配列内にNaN(欠損値)が含まれていると、結果もNaNになってしまいます。

実データには欠損が含まれることが多いため、その場合はnanstdnanvarを使用します。

Python
data_with_nan = np.array([1, 2, np.nan, 4])

# 通常の関数(nanが返る)
print(f"通常のstd: {np.std(data_with_nan)}")

# nanを無視する関数
print(f"nanstd: {np.nanstd(data_with_nan)}")
実行結果
通常のstd: nan
nanstd: 1.247219128924647

データクレンジングが不十分な可能性がある場合は、nan対応の関数を検討しましょう。

計算精度(dtype)の影響

非常に大きな値を含む配列や、逆に非常に精密な計算が必要な場合、データ型(dtype)に注意を払う必要があります。

デフォルトでは入力配列の型が維持されるか、float64が使用されます。

メモリを節約するためにfloat32を使用している場合、合計値の計算過程で精度落ちが発生し、分散の値が不安定になることがあります。

必要に応じて、関数の引数内でdtype='float64'を指定することで、計算過程の精度を確保することが可能です。

まとめ

本記事では、NumPyを使用した分散と標準偏差の計算方法について詳しく解説しました。

numpy.varnumpy.stdは、単に数値を計算するだけでなく、ddofによる不偏性の調整や、axisによる多次元的な解析など、非常に柔軟な運用が可能です。

特に統計学的な背景に基づく「n」で割るか「n-1」で割るかの違いは、分析結果の解釈に影響を与えるため、正しく理解しておく必要があります。

また、欠損値を含むデータには専用の関数を活用し、標準化などの実務的な処理へ応用させていきましょう。

NumPyのこれらの機能を使いこなすことで、複雑なデータセットに対しても正確かつ効率的なアプローチが可能になります。

URLをコピーしました!