Стандартное отклонение в Python
Как вычислить стандартное отклонение в Python с помощью statistics, NumPy и pandas, а также примеры применения в машинном обучении.
Стандартное отклонение измеряет, насколько значения рассеяны вокруг среднего. Это одна из наиболее широко используемых статистик в анализе данных и машинном обучении — от проверки нормального распределения набора данных до масштабирования признаков перед обучением модели. В этой главе объясняется, что такое стандартное отклонение, как вычислить его в Python с помощью модуля statistics, NumPy и pandas, а также как оно применяется в типичных задачах машинного обучения.
Что такое стандартное отклонение?
Стандартное отклонение (σ для генеральной совокупности, s для выборки) количественно выражает среднее расстояние каждой точки данных от среднего значения. Малое стандартное отклонение означает, что значения плотно сгруппированы вокруг среднего; большое — что они широко разбросаны.
Оно является квадратным корнем из дисперсии:
variance = Σ(xᵢ − x̄)² / N # population
variance = Σ(xᵢ − x̄)² / (N − 1) # sample (Bessel's correction)
std dev = √varianceСтандартное отклонение генеральной совокупности и выборки
| Термин | Знаменатель формулы | Когда использовать |
|---|---|---|
| Std генеральной совокупности | N | Есть все точки данных (например, все оценки в классе) |
| Std выборки | N − 1 | Есть подмножество, и нужно оценить всю совокупность |
Знаменатель N − 1 (поправка Бесселя) корректирует смещение, возникающее при оценке по выборке. На практике для больших наборов данных разница незначительна, но для малых выборок она важна.
Пример вычисления вручную
data = [10, 20, 30, 40, 50]
mean = (10 + 20 + 30 + 40 + 50) / 5 = 30
Differences from mean: -20, -10, 0, 10, 20
Squared differences: 400, 100, 0, 100, 400
Population variance = (400 + 100 + 0 + 100 + 400) / 5 = 200
Sample variance = (400 + 100 + 0 + 100 + 400) / 4 = 250
Population std dev = √200 ≈ 14.14
Sample std dev = √250 ≈ 15.81Модуль statistics
Встроенный модуль Python statistics — самый простой способ вычислить стандартное отклонение для небольших наборов данных, не требующий сторонних библиотек.
stdev() выбрасывает StatisticsError, если передать менее двух значений, поскольку список из одного элемента не имеет осмысленного разброса.
NumPy std()
NumPy — стандартный выбор при работе с массивами, матрицами или большими наборами данных. Функция np.std() по умолчанию вычисляет стандартное отклонение генеральной совокупности (ddof=0). Передайте ddof=1, чтобы получить стандартное отклонение выборки.
NumPy также позволяет вычислять стандартное отклонение вдоль определённой оси двумерного массива, что удобно, когда каждая строка — это наблюдение, а каждый столбец — признак:
import numpy as np
# 3 samples, 2 features
X = np.array([[1, 10],
[2, 20],
[3, 30]])
print(np.std(X, axis=0, ddof=1)) # std per feature: [1. 10.]
print(np.std(X, axis=1, ddof=1)) # std per sample: [6.36 6.36 6.36] (approx)pandas std() и describe()
Когда данные хранятся в DataFrame, pandas предоставляет метод std() непосредственно для любого столбца или всего фрейма. По умолчанию pandas использует ddof=1 (стандартное отклонение выборки), что соответствует соглашению R.
import pandas as pd
temps = [72, 68, 75, 80, 65, 70, 78]
df = pd.DataFrame({"temperature": temps})
print(df["temperature"].std()) # 5.4116 (sample std, ddof=1)
print(df["temperature"].mean()) # 72.5714describe() даёт краткую статистическую сводку, включая стандартное отклонение для каждого числового столбца:
import pandas as pd
df = pd.DataFrame({
"height_cm": [165, 170, 175, 160, 180],
"weight_kg": [55, 70, 80, 50, 90],
})
print(df.describe())Строка std в выводе показывает стандартное отклонение выборки для каждого столбца:
height_cm weight_kg
count 5.000000 5.000000
mean 170.000000 69.000000
std 7.905694 16.733201
min 160.000000 50.000000
25% 165.000000 55.000000
50% 170.000000 70.000000
75% 175.000000 80.000000
max 180.000000 90.000000Стандартное отклонение в машинном обучении
Масштабирование признаков с помощью StandardScaler
Исходные признаки нередко имеют очень разные масштабы (возраст в годах против дохода в тысячах). Алгоритмы, такие как линейная регрессия, SVM и k-ближайших соседей, чувствительны к этому дисбалансу. Стандартизация (также называемая нормализацией z-оценок) преобразует каждый признак так, чтобы среднее = 0, а стандартное отклонение = 1:
z = (x − mean) / stdStandardScaler из scikit-learn применяет это автоматически:
from sklearn.preprocessing import StandardScaler
import numpy as np
# 3 samples, 2 features
features = np.array([[1, 2],
[3, 4],
[5, 6]])
scaler = StandardScaler()
scaled = scaler.fit_transform(features)
print(scaled)
# [[-1.2247 -1.2247]
# [ 0. 0. ]
# [ 1.2247 1.2247]]После масштабирования каждый столбец имеет среднее 0 и стандартное отклонение 1. Затем можно просмотреть выученные параметры:
print(scaler.mean_) # [3. 4.]
print(scaler.scale_) # [1.6330 1.6330]Сравнение вариативности групп
Стандартное отклонение помогает определить, действительно ли две группы различаются или просто шумят. Два класса могут иметь схожее среднее, но значительно отличаться по разбросу:
import statistics
scores_a = [78, 80, 82, 79, 81] # consistent group
scores_b = [60, 100, 55, 95, 70] # high-variance group
print(f"Group A — mean: {statistics.mean(scores_a)}, std: {statistics.stdev(scores_a):.2f}")
# Group A — mean: 80, std: 1.58
print(f"Group B — mean: {statistics.mean(scores_b)}, std: {statistics.stdev(scores_b):.2f}")
# Group B — mean: 76, std: 20.43У группы A и группы B схожие средние, однако стандартное отклонение группы B примерно в 13 раз больше, что указывает на значительно менее предсказуемые результаты.
Обнаружение аномалий с помощью z-оценок
Z-оценка показывает, на сколько стандартных отклонений значение отстоит от среднего. Значения с |z| > 3 традиционно считаются кандидатами в выбросы:
import numpy as np
values = np.array([2.0, 2.5, 3.0, 2.8, 100.0, 2.2, 3.1])
mean = np.mean(values)
std = np.std(values, ddof=1)
z_scores = (values - mean) / std
print(z_scores.round(2))
# [-0.39 -0.38 -0.37 -0.37 2.27 -0.39 -0.36]Значение 100.0 имеет z-оценку 2.27, которая — с учётом крошечного набора данных — уже явно выделяется как вероятный выброс.
Оценка неопределённости модели
Стандартное отклонение также используется при оценке модели на нескольких фолдах кросс-валидации. Высокое стандартное отклонение по фолдам говорит о нестабильности модели или высокой дисперсии в данных. Подробный разбор — в главе о кросс-валидации.
Выбор подходящего инструмента
| Ситуация | Рекомендуемый инструмент |
|---|---|
| Быстрое вычисление без зависимостей | statistics.stdev() / statistics.pstdev() |
| Операции с массивами или матрицами | numpy.std() |
| Статистика по столбцам DataFrame | pandas.DataFrame.std() |
| Предобработка признаков для ML | sklearn.preprocessing.StandardScaler |
Типичные ошибки
- Неверный
ddof: NumPy по умолчанию используетddof=0(генеральная совокупность), а pandas —ddof=1(выборка). Всегда проверяйте нужное значение перед сравнением результатов из двух библиотек. - Список из одного элемента:
statistics.stdev()выбрасывает ошибку;np.std()молча возвращает0.0. - Обучение масштабировщика на тестовых данных: всегда вызывайте
scaler.fit_transform()на обучающем наборе иscaler.transform()(но неfit_transform) на тестовом. Обучение на тестовых данных приводит к утечке информации и завышенным метрикам качества. Подробнее — в главе о разделении на обучающую и тестовую выборки. - Выбросы искажают std: одно экстремальное значение может резко увеличить стандартное отклонение, как показано в примере с обнаружением аномалий. Сначала рекомендуется проверить данные на наличие выбросов (см. главу о распределении данных).
Связанные главы
- Среднее, медиана и мода — другие меры центральной тенденции, дополняющие стандартное отклонение
- Перцентили — ранговые меры разброса, устойчивые к выбросам
- Нормальное распределение данных — стандартное отклонение является ключевым параметром нормального распределения
- Масштабирование — более широкие стратегии масштабирования признаков, выходящие за рамки стандартизации
- Распределение данных — визуализация разброса и выявление асимметрии