Размах, дисперсия и стандартное отклонение

Центр говорит, где данные, а разброс — насколько они кучные или разбросанные. Без разброса картина неполная.

Стандартное отклонение — это, грубо говоря, среднее расстояние от точек до их среднего. Маленькое — данные кучные, большое — разбросанные.

Размах — самая простая мера

Размах (range) — это просто разница между максимумом и минимумом. Он мгновенно говорит, в каком диапазоне лежат данные, но учитывает только две крайние точки и потому очень чувствителен к выбросам.

data = [12, 15, 14, 10, 18, 16]
print("Максимум:", max(data))
print("Минимум:", min(data))
print("Размах:", max(data) - min(data))

Вывод:

Максимум: 18
Минимум: 10
Размах: 8

От идеи к дисперсии

Хочется меры, которая учитывает все точки, а не только края. Логичная идея: посмотреть, насколько каждая точка отклоняется от среднего, и усреднить эти отклонения. Но если просто складывать отклонения, плюсы и минусы взаимно сократятся и сумма всегда даст ноль. Поэтому отклонения возводят в квадрат (убираем знак) и усредняют. Это и есть дисперсия.

Посчитаем дисперсию вручную, по шагам, чтобы увидеть всю кухню.

from statistics import mean

data = [2, 4, 4, 4, 5, 5, 7, 9]
m = mean(data)
print("Среднее:", m)

# Квадраты отклонений от среднего
sq = [(x - m) ** 2 for x in data]
print("Квадраты отклонений:", sq)

# Дисперсия совокупности = средний квадрат отклонения
variance = sum(sq) / len(data)
print("Дисперсия (population):", variance)

Вывод:

Среднее: 5
Квадраты отклонений: [9, 1, 1, 1, 0, 0, 4, 16]
Дисперсия (population): 4.0

Стандартное отклонение — возвращаемся к единицам

У дисперсии есть неудобство: она в квадратных единицах (рубли в квадрате?). Чтобы вернуться к исходным единицам, берут квадратный корень из дисперсии — это и есть стандартное отклонение (σ). Его уже можно толковать как «типичное отклонение от среднего».

import math
from statistics import pstdev, pvariance

data = [2, 4, 4, 4, 5, 5, 7, 9]
print("Дисперсия:", pvariance(data))
print("Корень из дисперсии:", math.sqrt(pvariance(data)))
print("pstdev напрямую:", pstdev(data))

Вывод:

Дисперсия: 4
Корень из дисперсии: 2.0
pstdev напрямую: 2.0

Важный нюанс: деление на n или на n−1

В модуле statistics есть две пары функций, и путать их — частая ошибка:

  • pvariance / pstdev — для всей совокупности, делят на n.
  • variance / stdev — для выборки, делят на n − 1 (поправка Бесселя).

Деление на n − 1 чуть увеличивает оценку и компенсирует то, что по выборке мы недооцениваем истинный разброс. На практике вы почти всегда работаете с выборкой, поэтому берите stdev и variance.

from statistics import stdev, pstdev

data = [2, 4, 4, 4, 5, 5, 7, 9]
print("Выборочное (n-1):", round(stdev(data), 3))
print("Для совокупности (n):", round(pstdev(data), 3))

Вывод:

Выборочное (n-1): 2.138
Для совокупности (n): 2.0

Зачем это аналитику

Стандартное отклонение позволяет сравнивать стабильность. Две доставки с одинаковым средним временем 30 минут, но σ = 3 и σ = 15 — это небо и земля: первая предсказуема, вторая то за 15 минут, то за час. Среднее их не различает, а стандартное отклонение — сразу.

Итог

  • Размах = максимум − минимум; прост, но смотрит только на края.
  • Дисперсия — средний квадрат отклонения от среднего (учитывает все точки).
  • Стандартное отклонение = корень из дисперсии, в исходных единицах.
  • Для выборки делят на n−1 (stdev), для совокупности — на n (pstdev).
Проверьте себя
1. Почему при расчёте дисперсии отклонения от среднего возводят в квадрат?
AЧтобы числа были больше
BПотому что сумма обычных отклонений от среднего всегда равна нулю
CЧтобы получить результат в исходных единицах
DЭто требование модуля statistics
2. Чем стандартное отклонение удобнее дисперсии?
AОно всегда меньше
BОно измеряется в тех же единицах, что и сами данные
CЕго не нужно вычислять
DОно не зависит от выбросов
3. Какую функцию взять для оценки разброса по ВЫБОРКЕ?
Apstdev (деление на n)
Bstdev (деление на n−1)
Cmean
Dmedian
Поддержать проект