W3docs

Стандартное отклонение в 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 — самый простой способ вычислить стандартное отклонение для небольших наборов данных, не требующий сторонних библиотек.

python— editable, runs on the server

stdev() выбрасывает StatisticsError, если передать менее двух значений, поскольку список из одного элемента не имеет осмысленного разброса.

NumPy std()

NumPy — стандартный выбор при работе с массивами, матрицами или большими наборами данных. Функция np.std() по умолчанию вычисляет стандартное отклонение генеральной совокупности (ddof=0). Передайте ddof=1, чтобы получить стандартное отклонение выборки.

python— editable, runs on the server

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.5714

describe() даёт краткую статистическую сводку, включая стандартное отклонение для каждого числового столбца:

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) / std

StandardScaler из 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()
Статистика по столбцам DataFramepandas.DataFrame.std()
Предобработка признаков для MLsklearn.preprocessing.StandardScaler

Типичные ошибки

  • Неверный ddof: NumPy по умолчанию использует ddof=0 (генеральная совокупность), а pandas — ddof=1 (выборка). Всегда проверяйте нужное значение перед сравнением результатов из двух библиотек.
  • Список из одного элемента: statistics.stdev() выбрасывает ошибку; np.std() молча возвращает 0.0.
  • Обучение масштабировщика на тестовых данных: всегда вызывайте scaler.fit_transform() на обучающем наборе и scaler.transform() (но не fit_transform) на тестовом. Обучение на тестовых данных приводит к утечке информации и завышенным метрикам качества. Подробнее — в главе о разделении на обучающую и тестовую выборки.
  • Выбросы искажают std: одно экстремальное значение может резко увеличить стандартное отклонение, как показано в примере с обнаружением аномалий. Сначала рекомендуется проверить данные на наличие выбросов (см. главу о распределении данных).

Связанные главы

Was this page helpful?