📏 ステップ14: 分散と標準偏差を学ぼう
データのばらつきを数値で表そう!
ステップ13では、中央値と最頻値について学びました。今回は、データの「ばらつき」を数値で表す方法を学びます。平均値だけでは分からない、データの散らばり具合を理解しましょう。
📖 このステップで学ぶこと
・データのばらつきとは何か
・分散(バリアンス)の意味と計算方法
・標準偏差(スタンダードデビエーション)の意味と計算方法
・ばらつきを使ったデータ分析
・母分散と標本分散の違い
学習時間の目安: 3〜3.5時間
🎯 1. データのばらつきとは?
まず、「ばらつき」がなぜ重要なのかを理解しましょう。
🔰 平均だけでは分からないこと
平均が同じでも、データの散らばり方は全然違うことがあります。次の例を見てください。
💡 具体的なイメージ
クラスA:全員が50点(50, 50, 50, 50, 50)
クラスB:点数がバラバラ(10, 30, 50, 70, 90)
どちらも平均は50点ですが、状況は全く違いますよね。
クラスAは全員同じ実力、クラスBは実力差が大きいです。
これをPythonで確認してみましょう。
コード:平均が同じ2つのクラス
# 2つのクラスのテスト結果
class_a = [50, 50, 50, 50, 50] # 全員同じ点数
class_b = [10, 30, 50, 70, 90] # ばらつきが大きい
# 平均を計算
avg_a = sum(class_a) / len(class_a)
avg_b = sum(class_b) / len(class_b)
print("【クラスA】")
print(f"データ: {class_a}")
print(f"平均: {avg_a}点")
print()
print("【クラスB】")
print(f"データ: {class_b}")
print(f"平均: {avg_b}点")
print()
print("💡 平均は同じでも、ばらつきが全く違う!")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
【クラスA】 データ: [50, 50, 50, 50, 50] 平均: 50.0点 【クラスB】 データ: [10, 30, 50, 70, 90] 平均: 50.0点 💡 平均は同じでも、ばらつきが全く違う!
💡 この例から分かること
クラスA:全員が50点で、ばらつきがゼロ
クラスB:10点から90点まで、大きくばらついている
平均だけを見ると「同じ成績のクラス」に見えますが、実際は全く違う状況です。
だから、ばらつきを数値で表す方法が必要なのです!
📘 ばらつきを知ることが大切な場面
実際のビジネスや日常生活では、ばらつきを知ることがとても重要です。
📌 ばらつきが重要な例
| 場面 | 何のばらつき? | なぜ重要? |
| 品質管理 | 製品サイズのばらつき | ばらつきが大きいと不良品が増える |
| 売上分析 | 日々の売上のばらつき | 安定性を評価できる |
| 成績評価 | 生徒間の点数のばらつき | 学力差を把握できる |
| 投資判断 | 株価のばらつき | リスクの大きさを評価できる |
📐 2. 分散(バリアンス)とは?
ばらつきを数値で表す方法の1つが分散(ぶんさん)です。英語では「variance(バリアンス)」と言います。
🔰 分散の意味
分散とは、各データが平均からどれだけ離れているかを表す値です。
📌 分散のイメージ
分散が小さい → データが平均の近くに集まっている
分散が大きい → データが平均から離れてばらついている
📝 分散の計算手順
分散は、次の4つのステップで計算します。この手順を理解することがとても大切です。
📝 書き方:分散の計算手順
ステップ1:平均を計算する
ステップ2:各データと平均の差(偏差)を計算する
ステップ3:差を2乗する(マイナスをなくすため)
ステップ4:2乗した値の平均を取る → これが分散!
📘 具体例で計算してみよう
データ [2, 4, 6, 8, 10] の分散を、手順通りに計算してみましょう。
💡 計算例:分散を求める
データ: 2, 4, 6, 8, 10
ステップ1:平均を計算
(2 + 4 + 6 + 8 + 10) ÷ 5 = 30 ÷ 5 = 6
ステップ2:各データと平均の差
2 – 6 = -4、4 – 6 = -2、6 – 6 = 0、8 – 6 = 2、10 – 6 = 4
ステップ3:差を2乗
(-4)² = 16、(-2)² = 4、0² = 0、2² = 4、4² = 16
ステップ4:2乗の平均 = 分散
(16 + 4 + 0 + 4 + 16) ÷ 5 = 40 ÷ 5 = 8
答え: 分散は 8
🔰 なぜ差を2乗するのか?
「なぜ差をそのまま足さないの?」という疑問が出てくると思います。これには重要な理由があります。
⚠️ 差をそのまま足すとゼロになる!
上の例で、差をそのまま足すと:
(-4) + (-2) + 0 + 2 + 4 = 0
プラスとマイナスが打ち消し合ってしまいます!
これではばらつきを表せません。
2乗する理由:
・マイナスの値がなくなる(全て正の値になる)
・大きな差がより強調される(外れ値を見つけやすい)
🔢 3. Pythonで分散を計算する
分散の計算手順をPythonで実装してみましょう。
🔰 ステップごとに計算する
まず、4つのステップを1つずつコードで書いて、処理の流れを確認します。
コード:分散の計算(ステップごと)
# データ
data = [2, 4, 6, 8, 10]
# ステップ1:平均を計算
mean = sum(data) / len(data)
print(f"データ: {data}")
print(f"平均: {mean}")
print()
# ステップ2:各データと平均の差
print("【平均との差】")
differences = []
for value in data:
diff = value - mean
differences.append(diff)
print(f"{value} - {mean} = {diff}")
print()
# ステップ3:差を2乗
print("【差の2乗】")
squared_diff = []
for diff in differences:
sq = diff ** 2
squared_diff.append(sq)
print(f"({diff})² = {sq}")
print()
# ステップ4:2乗の平均 = 分散
variance = sum(squared_diff) / len(squared_diff)
print(f"分散: {variance}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: [2, 4, 6, 8, 10] 平均: 6.0 【平均との差】 2 - 6.0 = -4.0 4 - 6.0 = -2.0 6 - 6.0 = 0.0 8 - 6.0 = 2.0 10 - 6.0 = 4.0 【差の2乗】 (-4.0)² = 16.0 (-2.0)² = 4.0 (0.0)² = 0.0 (2.0)² = 4.0 (4.0)² = 16.0 分散: 8.0
💡 コードの解説
diff = value – mean
・各データから平均を引いて「偏差」を計算します
・偏差は「平均からどれだけ離れているか」を表します
sq = diff ** 2
・**は「べき乗」の演算子です
・diff ** 2 は「diffの2乗」を意味します
・2乗することでマイナスの値がなくなります
variance = sum(squared_diff) / len(squared_diff)
・2乗した値の合計を、データの個数で割ります
・これが分散です!
📘 分散を計算する関数を作る
分散の計算を関数にまとめると、繰り返し使えて便利です。
コード:分散を計算する関数
def calculate_variance(data):
"""
分散を計算する関数
引数:
data: 数値のリスト
戻り値:
分散
"""
# データがない場合のチェック
if len(data) == 0:
return None
# ステップ1:平均を計算
mean = sum(data) / len(data)
# ステップ2〜4:差の2乗の合計を計算し、個数で割る
squared_diff_sum = 0
for value in data:
diff = value - mean
squared_diff_sum += diff ** 2
# 分散 = 差の2乗の平均
variance = squared_diff_sum / len(data)
return variance
# テスト
numbers = [2, 4, 6, 8, 10]
var = calculate_variance(numbers)
print(f"データ: {numbers}")
print(f"分散: {var}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: [2, 4, 6, 8, 10] 分散: 8.0
💡 関数の解説
squared_diff_sum += diff ** 2
・+=は「足し算して代入」の省略形です
・squared_diff_sum = squared_diff_sum + (diff ** 2) と同じ意味
・ループで差の2乗を積み上げていきます
if len(data) == 0:
・空のリストが渡された場合のエラー防止です
・0で割るエラーを防ぎます
📘 より簡潔に書く方法(ジェネレータ式)
Pythonに慣れてきたら、ジェネレータ式を使ってもっと短く書けます。
コード:分散の簡潔な計算
def calculate_variance_short(data):
"""分散を計算(簡潔版)"""
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
return variance
# テスト
numbers = [2, 4, 6, 8, 10]
var = calculate_variance_short(numbers)
print(f"分散: {var}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
分散: 8.0
💡 sum((x – mean) ** 2 for x in data) の意味
これは「ジェネレータ式」という書き方です。
・dataの各要素xについて、(x – mean) ** 2 を計算
・その結果を全部足し合わせる
forループを1行で書いているイメージです。
最初は上の長い書き方で、慣れてきたらこの短い書き方を使いましょう。
📏 4. 標準偏差とは?
分散には1つ問題があります。単位がわかりにくいのです。
🔰 分散の問題点
分散の単位は、元のデータの単位を2乗したものになります。
💡 分散の単位は元の2乗になる
テストの点数(単位:点)の分散を計算すると…
分散の単位は「点²(点の2乗)」になります。
「分散は50点²です」と言われても、ピンときませんよね?
そこで登場するのが標準偏差です。
📝 標準偏差とは
標準偏差(ひょうじゅんへんさ)とは、分散の平方根(ルート)です。英語では「standard deviation(スタンダード・デビエーション)」と言い、「SD」と略されることもあります。
📝 書き方:標準偏差の計算式
標準偏差 = √分散
平方根を取ることで、元のデータと同じ単位に戻ります。
「テストの標準偏差は7.1点」のように表現できます。
📘 Pythonで標準偏差を計算する
平方根を計算するには、mathモジュールのsqrt()関数を使います。
📌 mathモジュールについて
mathモジュールは、Pythonに最初から入っている数学関数の集まりです。
平方根、三角関数、対数など、様々な計算ができます。
使う前にimport mathで読み込みます。
コード:標準偏差の計算
import math
def calculate_variance(data):
"""分散を計算"""
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
return variance
def calculate_std(data):
"""標準偏差を計算"""
# まず分散を計算
variance = calculate_variance(data)
# 標準偏差 = 分散の平方根
std = math.sqrt(variance)
return std
# テスト
numbers = [2, 4, 6, 8, 10]
variance = calculate_variance(numbers)
std = calculate_std(numbers)
print(f"データ: {numbers}")
print(f"分散: {variance}")
print(f"標準偏差: {std:.2f}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: [2, 4, 6, 8, 10] 分散: 8.0 標準偏差: 2.83
💡 コードの解説
import math
・mathモジュールを読み込みます
・プログラムの最初に1回だけ書けばOKです
math.sqrt(variance)
・sqrt は「square root(平方根)」の略です
・math.sqrt(8) は √8 ≈ 2.83 を計算します
{std:.2f}
・小数点以下2桁で表示する書式指定です
📘 標準偏差の方がわかりやすい
テストの点数を例に、分散と標準偏差を比べてみましょう。
コード:単位の比較
import math
def calculate_variance(data):
mean = sum(data) / len(data)
return sum((x - mean) ** 2 for x in data) / len(data)
def calculate_std(data):
return math.sqrt(calculate_variance(data))
# テストの点数
scores = [70, 75, 80, 85, 90]
variance = calculate_variance(scores)
std = calculate_std(scores)
print(f"テストの点数: {scores}")
print(f"平均: {sum(scores)/len(scores)}点")
print()
print(f"分散: {variance}(単位が「点²」でわかりにくい)")
print(f"標準偏差: {std:.1f}点(単位が「点」でわかりやすい)")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
テストの点数: [70, 75, 80, 85, 90] 平均: 80.0点 分散: 50.0(単位が「点²」でわかりにくい) 標準偏差: 7.1点(単位が「点」でわかりやすい)
📌 標準偏差の解釈
「標準偏差が7.1点」ということは…
・データは平均からだいたい7点くらい離れている
・つまり、平均±7点くらいの範囲にデータが多い
標準偏差は、「平均からの典型的な距離」と考えるとわかりやすいです。
📊 5. 実践例:ばらつきを比較する
実際のデータで分散と標準偏差を使ってみましょう。
📘 例1:2つのクラスの成績を比較
同じような平均点のクラスでも、ばらつきに違いがあるか確認します。
コード:成績のばらつきを比較
import math
def calculate_variance(data):
mean = sum(data) / len(data)
return sum((x - mean) ** 2 for x in data) / len(data)
def calculate_std(data):
return math.sqrt(calculate_variance(data))
# 2つのクラスの成績
class_a = [75, 78, 80, 82, 85, 88, 90]
class_b = [50, 60, 70, 80, 90, 100, 110]
# クラスAの分析
mean_a = sum(class_a) / len(class_a)
std_a = calculate_std(class_a)
print("【クラスA】")
print(f"データ: {class_a}")
print(f"平均: {mean_a:.1f}点")
print(f"標準偏差: {std_a:.1f}点")
print()
# クラスBの分析
mean_b = sum(class_b) / len(class_b)
std_b = calculate_std(class_b)
print("【クラスB】")
print(f"データ: {class_b}")
print(f"平均: {mean_b:.1f}点")
print(f"標準偏差: {std_b:.1f}点")
print()
print("💡 考察:")
print(" クラスAは平均の周りに集まっている(標準偏差が小さい)")
print(" クラスBは点数がばらついている(標準偏差が大きい)")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
【クラスA】 データ: [75, 78, 80, 82, 85, 88, 90] 平均: 82.6点 標準偏差: 5.1点 【クラスB】 データ: [50, 60, 70, 80, 90, 100, 110] 平均: 80.0点 標準偏差: 20.0点 💡 考察: クラスAは平均の周りに集まっている(標準偏差が小さい) クラスBは点数がばらついている(標準偏差が大きい)
💡 この例から分かること
クラスA(標準偏差5.1点):
生徒の成績が揃っている。授業についてこれている生徒が多い。
クラスB(標準偏差20.0点):
生徒間の学力差が大きい。個別対応が必要かもしれない。
📘 例2:製品の品質管理
製造業では、製品のばらつきを小さくすることが品質の証です。
コード:製品品質の比較
import math
def calculate_std(data):
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
return math.sqrt(variance)
# 2つの製造ラインの製品サイズ(mm)- 目標は100mm
line_a = [99.8, 100.1, 99.9, 100.2, 100.0, 99.9, 100.1]
line_b = [98.5, 101.2, 99.0, 102.0, 98.8, 101.5, 99.3]
# ラインAの分析
mean_a = sum(line_a) / len(line_a)
std_a = calculate_std(line_a)
print("【製造ラインA】")
print(f"サイズ: {line_a}")
print(f"平均: {mean_a:.2f}mm(目標: 100mm)")
print(f"標準偏差: {std_a:.2f}mm")
# 品質判定
if std_a < 0.5:
print("品質: ✅ 優良(ばらつきが非常に小さい)")
elif std_a < 1.0:
print("品質: ⚠️ 注意(ややばらつきあり)")
else:
print("品質: ❌ 不良(ばらつきが大きい)")
print()
# ラインBの分析
mean_b = sum(line_b) / len(line_b)
std_b = calculate_std(line_b)
print("【製造ラインB】")
print(f"サイズ: {line_b}")
print(f"平均: {mean_b:.2f}mm(目標: 100mm)")
print(f"標準偏差: {std_b:.2f}mm")
if std_b < 0.5:
print("品質: ✅ 優良(ばらつきが非常に小さい)")
elif std_b < 1.0:
print("品質: ⚠️ 注意(ややばらつきあり)")
else:
print("品質: ❌ 不良(ばらつきが大きい)")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
【製造ラインA】 サイズ: [99.8, 100.1, 99.9, 100.2, 100.0, 99.9, 100.1] 平均: 100.00mm(目標: 100mm) 標準偏差: 0.13mm 品質: ✅ 優良(ばらつきが非常に小さい) 【製造ラインB】 サイズ: [98.5, 101.2, 99.0, 102.0, 98.8, 101.5, 99.3] 平均: 100.04mm(目標: 100mm) 標準偏差: 1.33mm 品質: ❌ 不良(ばらつきが大きい)
💡 この例から分かること
両方とも平均は目標の100mmに近いですが...
・ラインA:標準偏差0.13mm → ほぼ均一な品質
・ラインB:標準偏差1.33mm → サイズにばらつきがある
平均だけでなく、ばらつきも見ることで品質の違いがわかります。
📘 例3:売上の安定性分析
売上のばらつきから、ビジネスの安定性を評価できます。
コード:売上の安定性を比較
import math
def calculate_std(data):
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
return math.sqrt(variance)
# 2つの店舗の月別売上(万円)
store_a = [120, 125, 118, 122, 124, 121, 123, 119, 126, 120, 122, 125]
store_b = [80, 150, 100, 180, 90, 160, 95, 170, 85, 175, 100, 165]
# 店舗Aの分析
mean_a = sum(store_a) / len(store_a)
std_a = calculate_std(store_a)
cv_a = (std_a / mean_a) * 100 # 変動係数(%)
print("【店舗A】")
print(f"平均売上: {mean_a:.1f}万円")
print(f"標準偏差: {std_a:.1f}万円")
print(f"変動係数: {cv_a:.1f}%")
print("安定性: ✅ 売上が安定している")
print()
# 店舗Bの分析
mean_b = sum(store_b) / len(store_b)
std_b = calculate_std(store_b)
cv_b = (std_b / mean_b) * 100
print("【店舗B】")
print(f"平均売上: {mean_b:.1f}万円")
print(f"標準偏差: {std_b:.1f}万円")
print(f"変動係数: {cv_b:.1f}%")
print("安定性: ❌ 売上の変動が大きい")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
【店舗A】 平均売上: 122.1万円 標準偏差: 2.6万円 変動係数: 2.1% 安定性: ✅ 売上が安定している 【店舗B】 平均売上: 129.2万円 標準偏差: 40.0万円 変動係数: 31.0% 安定性: ❌ 売上の変動が大きい
💡 変動係数(CV)とは
変動係数 = (標準偏差 ÷ 平均) × 100
標準偏差を平均で割ることで、相対的なばらつきがわかります。
・変動係数が小さい → 安定している
・変動係数が大きい → 不安定で予測しにくい
異なる規模のデータを比較するときに便利です。
🎲 6. 母分散と標本分散
統計学では、分散の計算方法が2種類あります。これは実務でも重要な違いです。
🔰 2種類の分散
📌 母分散と標本分散の違い
| 種類 | 計算方法 | 使う場面 |
| 母分散 | nで割る | 全データがある場合 |
| 標本分散 | n-1で割る | 一部のサンプルしかない場合 |
💡 なぜn-1で割るのか?
サンプル(標本)から全体を推測する場合、nで割ると分散が小さめに計算されてしまう傾向があります。
n-1で割ることで、より正確な推定ができます。
この調整を「不偏推定」と呼びます。
📘 2種類の分散を計算する
コード:母分散と標本分散の比較
def population_variance(data):
"""母分散(nで割る)"""
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
return variance
def sample_variance(data):
"""標本分散(n-1で割る)"""
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / (len(data) - 1)
return variance
# テスト
data = [10, 20, 30, 40, 50]
pop_var = population_variance(data)
samp_var = sample_variance(data)
print(f"データ: {data}")
print(f"データ数: {len(data)}個")
print()
print(f"母分散(nで割る): {pop_var}")
print(f"標本分散(n-1で割る): {samp_var}")
print()
print("💡 標本分散の方がやや大きくなります")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: [10, 20, 30, 40, 50] データ数: 5個 母分散(nで割る): 200.0 標本分散(n-1で割る): 250.0 💡 標本分散の方がやや大きくなります
📌 どちらを使うべき?
実務では、ほとんどの場合標本分散(n-1で割る)を使います。
なぜなら、通常は全データではなく、一部のサンプルを扱うからです。
Pythonの統計ライブラリ(NumPyやPandas)も、デフォルトで標本分散を計算します。
📝 練習問題
ここまで学んだことを、実際に手を動かして確認しましょう。
問題1:分散の計算(初級)
📋 問題
リスト [1, 2, 3, 4, 5] の分散を計算してください。
解答例を見る
コード
data = [1, 2, 3, 4, 5]
# 平均を計算
mean = sum(data) / len(data)
# 分散を計算
variance = sum((x - mean) ** 2 for x in data) / len(data)
print(f"データ: {data}")
print(f"平均: {mean}")
print(f"分散: {variance}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: [1, 2, 3, 4, 5] 平均: 3.0 分散: 2.0
問題2:標準偏差の計算(初級)
📋 問題
リスト [10, 20, 30, 40, 50] の標準偏差を計算してください。
解答例を見る
コード
import math
data = [10, 20, 30, 40, 50]
# 平均を計算
mean = sum(data) / len(data)
# 分散を計算
variance = sum((x - mean) ** 2 for x in data) / len(data)
# 標準偏差を計算
std = math.sqrt(variance)
print(f"データ: {data}")
print(f"平均: {mean}")
print(f"分散: {variance}")
print(f"標準偏差: {std:.2f}")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: [10, 20, 30, 40, 50] 平均: 30.0 分散: 200.0 標準偏差: 14.14
問題3:ばらつきの比較(中級)
📋 問題
2つのデータ [85, 87, 89, 91, 93] と [70, 80, 90, 100, 110] の標準偏差を比較し、どちらがよりばらついているか判定してください。
解答例を見る
コード
import math
def calc_std(data):
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
return math.sqrt(variance)
data1 = [85, 87, 89, 91, 93]
data2 = [70, 80, 90, 100, 110]
std1 = calc_std(data1)
std2 = calc_std(data2)
print("【データ1】")
print(f"データ: {data1}")
print(f"標準偏差: {std1:.2f}")
print()
print("【データ2】")
print(f"データ: {data2}")
print(f"標準偏差: {std2:.2f}")
print()
if std1 > std2:
print("判定: データ1の方がばらついている")
else:
print("判定: データ2の方がばらついている")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
【データ1】 データ: [85, 87, 89, 91, 93] 標準偏差: 2.83 【データ2】 データ: [70, 80, 90, 100, 110] 標準偏差: 14.14 判定: データ2の方がばらついている
問題4:統計サマリー関数(中級)
📋 問題
データを受け取って、平均、分散、標準偏差を表示する関数 stats_summary(data) を作成してください。
解答例を見る
コード
import math
def stats_summary(data, name="データ"):
"""統計サマリーを表示する関数"""
# 平均
mean = sum(data) / len(data)
# 分散
variance = sum((x - mean) ** 2 for x in data) / len(data)
# 標準偏差
std = math.sqrt(variance)
print(f"【{name}】")
print(f"データ: {data}")
print(f"データ数: {len(data)}個")
print(f"平均: {mean:.2f}")
print(f"分散: {variance:.2f}")
print(f"標準偏差: {std:.2f}")
# テスト
scores = [75, 80, 85, 90, 95]
stats_summary(scores, "テストの点数")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
【テストの点数】 データ: [75, 80, 85, 90, 95] データ数: 5個 平均: 85.00 分散: 50.00 標準偏差: 7.07
問題5:外れ値の検出(上級)
📋 問題
データから「平均 ± 2×標準偏差」の範囲外にある値(外れ値)を検出する関数を作成してください。
解答例を見る
コード
import math
def detect_outliers(data):
"""外れ値を検出する関数"""
# 平均と標準偏差を計算
mean = sum(data) / len(data)
variance = sum((x - mean) ** 2 for x in data) / len(data)
std = math.sqrt(variance)
# 正常範囲を計算(平均 ± 2×標準偏差)
lower_bound = mean - 2 * std
upper_bound = mean + 2 * std
# 外れ値を検出
outliers = []
for x in data:
if x < lower_bound or x > upper_bound:
outliers.append(x)
# 結果を表示
print(f"データ: {data}")
print(f"平均: {mean:.1f}")
print(f"標準偏差: {std:.1f}")
print(f"正常範囲: {lower_bound:.1f} 〜 {upper_bound:.1f}")
if len(outliers) > 0:
print(f"外れ値: {outliers}")
else:
print("外れ値: なし")
# テスト1:外れ値あり
data1 = [10, 12, 11, 13, 12, 100, 11, 12]
detect_outliers(data1)
print()
print("=" * 50)
print()
# テスト2:外れ値なし
data2 = [50, 52, 51, 53, 52, 51, 50, 53]
detect_outliers(data2)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
データ: [10, 12, 11, 13, 12, 100, 11, 12] 平均: 22.6 標準偏差: 29.7 正常範囲: -36.8 〜 82.0 外れ値: [100] ================================================== データ: [50, 52, 51, 53, 52, 51, 50, 53] 平均: 51.5 標準偏差: 1.1 正常範囲: 49.3 〜 53.7 外れ値: なし
🎯 このステップのまとめ
✅ 学んだこと
✓ ばらつき:データが平均からどれだけ散らばっているか
✓ 分散:各データと平均の差の2乗の平均
✓ 標準偏差:分散の平方根(元の単位で表せる)
✓ 標準偏差が小さい → データが集まっている
✓ 標準偏差が大きい → データがばらついている
✓ 母分散(nで割る)と標本分散(n-1で割る)の違い
✓ 変動係数で相対的なばらつきを比較できる
💡 次のステップに進む前に確認
以下のことができるようになったか確認しましょう:
□ 分散の計算手順を説明できる
□ 標準偏差の意味を理解している
□ Pythonで分散と標準偏差を計算できる
□ ばらつきの大小を判断できる
これらができたら、次のステップに進みましょう!
❓ よくある質問
Q1: なぜ差を2乗するのですか?
A: 負の値をなくすためです。差をそのまま足すと、プラスとマイナスが打ち消し合ってゼロになります。2乗することで全て正の値になり、ばらつきを正確に測れます。
Q2: 分散と標準偏差、どちらを使うべきですか?
A: 一般的には標準偏差を使います。元のデータと同じ単位で表せるため、理解しやすいです。「平均80点、標準偏差7点」のように使います。
Q3: 標準偏差が0になるのはどんな時ですか?
A: 全てのデータが同じ値の時です。ばらつきがゼロということです。例:[50, 50, 50, 50]の標準偏差は0です。
Q4: 母分散と標本分散、どちらを使うべきですか?
A: 実務では通常標本分散(n-1で割る)を使います。全データではなく、サンプルデータを扱うことが多いためです。NumPyやPandasもデフォルトで標本分散を計算します。
Q5: 変動係数とは何ですか?
A: 標準偏差を平均で割った値(%表示)です。単位が異なるデータ(身長と体重など)の相対的なばらつきを比較するのに使います。計算式は「変動係数 = (標準偏差 ÷ 平均) × 100」です。
学習メモ
Pythonデータ分析入門 - Step 14