Введение

Бутстрап (bootstrap) — это статистический метод, основанный на многократном повторном формировании выборки с возвращением из имеющихся данных. Метод позволяет оценить стандартные ошибки, доверительные интервалы и другие характеристики статистик без параметрических предположений о распределении данных.

Основные преимущества бутстрапа:

  • Не требует знания распределения данных
  • Применим к любым статистикам (медиана, квантили, R², и т.д.)
  • Даёт оценку неопределённости для сложных статистик

Описание датасета

В данной работе используется датасет mtcars — классический набор данных о характеристиках 32 автомобилей, опубликованный в журнале Motor Trend в 1974 году.

# Загрузка и просмотр данных
data(mtcars)
cat("Размер датасета:", nrow(mtcars), "строк,", ncol(mtcars), "столбцов\n")
## Размер датасета: 32 строк, 11 столбцов
head(mtcars)
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

Основные переменные:

  • mpg — расход топлива (миль на галлон)
  • wt — вес автомобиля (1000 фунтов)
  • disp — объём двигателя (куб. дюймы)

Разведочный анализ данных (EDA)

Описательная статистика

Описательная статистика mpg:

summary(mtcars$mpg)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   10.40   15.43   19.20   20.09   22.80   33.90
cat("\n90-й перцентиль mpg:", quantile(mtcars$mpg, 0.9))
## 
## 90-й перцентиль mpg: 30.09

Визуализация

par(mfrow = c(1, 2))

# Гистограмма mpg
hist(mtcars$mpg,
   breaks = 8, col = "steelblue", border = "white",
   main = "Распределение расхода топлива",
   xlab = "Расход топлива (mpg)", ylab = "Частота"
)
abline(v = mean(mtcars$mpg), col = "red", lwd = 2, lty = 2)
abline(v = quantile(mtcars$mpg, 0.9), col = "green", lwd = 2, lty = 2)
legend("topright", legend = c(
   sprintf("Среднее: %.2f", mean(mtcars$mpg)),
   sprintf("90%% перцентиль: %.2f", quantile(mtcars$mpg, 0.9))
), col = c("red", "green"), lty = 2, lwd = 2, cex = 0.8)

# Диаграмма рассеяния
plot(mtcars$wt, mtcars$mpg,
   pch = 19, col = "steelblue", cex = 1.5,
   main = "Зависимость расхода от веса",
   xlab = "Вес автомобиля (1000 фунтов)", ylab = "Расход топлива (mpg)"
)
abline(lm(mpg ~ wt, data = mtcars), col = "red", lwd = 2, lty = 2)
legend("topright", legend = "Линия регрессии", col = "red", lty = 2, lwd = 2)
grid()

Выводы EDA:

  • Распределение mpg унимодальное, слегка асимметричное вправо
  • Среднее значение mpg: 20.09 миль/галлон
  • Наблюдается сильная отрицательная связь между весом и расходом топлива

Реализация бутстрапа на Python

Код программы

#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy import stats

np.random.seed(42)

# Загрузка датасета mtcars
mtcars_data = {
    'mpg': [21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2,
            17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 30.4, 33.9,
            21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26.0, 30.4, 15.8, 19.7, 15.0, 21.4],
    'wt': [2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3.150, 3.440,
           3.440, 4.070, 3.730, 3.780, 5.250, 5.424, 5.345, 2.200, 1.615, 1.835,
           2.465, 3.520, 3.435, 3.840, 3.845, 1.935, 2.140, 1.513, 3.170, 2.770, 3.570, 2.780]
}
df = pd.DataFrame(mtcars_data)

# Функция бутстрапа
def get_percentile_ci(bootstrap_stats, alpha):
    left, right = np.quantile(bootstrap_stats, [alpha / 2, 1 - alpha / 2])
    return left, right

# Параметры
n = len(df['mpg'])
B = 10000
alpha = 0.05
values = df['mpg'].values
pe = np.quantile(values, 0.9)

# Бутстрап
bootstrap_values = np.random.choice(values, (B, n), replace=True)
bootstrap_stats = np.quantile(bootstrap_values, 0.9, axis=1)
ci = get_percentile_ci(bootstrap_stats, alpha)

print(f"Точечная оценка 90-го перцентиля: {pe:.2f} mpg")
print(f"95% ДИ: ({ci[0]:.2f}, {ci[1]:.2f}) mpg")

Результаты Python

EDA графики Python
EDA графики Python

Рисунок 1. Разведочный анализ данных: гистограмма mpg и зависимость расхода от веса.

Бутстрап результаты Python
Бутстрап результаты Python

Рисунок 2. Бутстрап-распределение 90-го перцентиля и Q-Q plot.

Сравнение групп Python
Сравнение групп Python

Рисунок 3. Сравнение лёгких и тяжёлых автомобилей.

Ключевые результаты Python:

Параметр Значение
Точечная оценка 90-го перцентиля 30.09 mpg
95% ДИ (22.80, 32.40) mpg
Стандартная ошибка бутстрапа 2.79

Выводы по Python:

  1. 90-й перцентиль расхода топлива составляет 30.09 mpg
  2. Лёгкие автомобили имеют статистически значимо более высокий расход (разница 12.45 mpg, ДИ не включает 0)
  3. Q-Q plot подтверждает нормальность бутстрап-распределения

Реализация бутстрапа на R

Код программы

library(boot)
set.seed(42)

# Функция для вычисления R²
rsq_function <- function(formula, data, indices) {
   d <- data[indices, ]
   fit <- lm(formula, data = d)
   return(summary(fit)$r.square)
}

# Исходная регрессия
original_fit <- lm(mpg ~ wt, data = mtcars)
original_rsq <- summary(original_fit)$r.squared
cat("Исходный R²:", round(original_rsq, 4), "\n")
## Исходный R²: 0.7528
# Бутстрап
B <- 2000
reps <- boot(data = mtcars, statistic = rsq_function, R = B, formula = mpg ~ wt)
print(reps)
## 
## ORDINARY NONPARAMETRIC BOOTSTRAP
## 
## 
## Call:
## boot(data = mtcars, statistic = rsq_function, R = B, formula = mpg ~ 
##     wt)
## 
## 
## Bootstrap Statistics :
##      original      bias    std. error
## t1* 0.7528328 0.004827619  0.05883449

Визуализация бутстрапа R

par(mfrow = c(1, 2))
plot(reps)

Доверительные интервалы

ci_result <- boot.ci(reps, type = c("norm", "basic", "perc", "bca"))
print(ci_result)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 2000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = reps, type = c("norm", "basic", "perc", "bca"))
## 
## Intervals : 
## Level      Normal              Basic         
## 95%   ( 0.6327,  0.8633 )   ( 0.6487,  0.8780 )  
## 
## Level     Percentile            BCa          
## 95%   ( 0.6277,  0.8570 )   ( 0.5843,  0.8392 )  
## Calculations and Intervals on Original Scale

Ключевые результаты R:

Параметр Значение
Исходный R² 0.7528
Среднее бутстрап R² 0.7577
Стандартная ошибка 0.0588
95% BCa ДИ (0.58, 0.84)

Выводы по R:

  1. R² ≈ 0.75 — вес объясняет 75% вариации расхода топлива
  2. BCa доверительный интервал подтверждает стабильность оценки
  3. Q-Q plot показывает приблизительно нормальное распределение

Сравнение подходов Python и R

Аспект Python R
Используемые библиотеки numpy, scipy boot
Статистика 90-й перцентиль R² регрессии
Метод ДИ Перцентильный BCa, Normal, Basic
Количество итераций 10000 2000

Преимущества каждого подхода:

Python: - Полный контроль над алгоритмом - Гибкость в выборе визуализаций - Легко масштабируется

R (пакет boot): - Встроенная поддержка различных типов ДИ - Автоматический расчёт смещения - Готовые функции визуализации


Общие выводы

  1. Метод бутстрапа — мощный непараметрический инструмент для оценки неопределённости статистик.

  2. Для датасета mtcars показана возможность применения бутстрапа как для простых статистик (перцентили), так и для сложных (R² регрессии).

  3. Оба языка (Python и R) предоставляют эффективные инструменты для реализации бутстрапа:

    • Python даёт больше контроля и гибкости
    • R через пакет boot предоставляет готовые решения
  4. Визуализация помогает интерпретировать результаты и проверять предположения (нормальность распределения).

  5. Практическое применение: бутстрап особенно полезен при малых выборках и для статистик, для которых сложно вывести аналитические формулы.


Приложение: консольный вывод скриптов

Python вывод

ДАТАСЕТ: mtcars (Motor Trend Car Road Tests)
   Количество наблюдений: 32
   Переменные: mpg (расход топлива, миль/галлон), wt (вес, 1000 фунтов)

РАЗВЕДОЧНЫЙ АНАЛИЗ ДАННЫХ (EDA)

Описательная статистика переменной mpg:
count    32.000000
mean     20.090625
std       6.026948
min      10.400000
25%      15.425000
50%      19.200000
75%      22.800000
max      33.900000
Name: mpg, dtype: float64

   90-й перцентиль mpg: 30.09

График EDA сохранён: eda_plots.png

БУТСТРАП: ОЦЕНКА 90-ГО ПЕРЦЕНТИЛЯ MPG

Параметры бутстрапа:
   Размер выборки (n): 32
   Количество бутстрап-итераций (B): 10000
   Уровень значимости (α): 0.05

Результаты:
   Точечная оценка 90-го перцентиля: 30.09 mpg
   95% доверительный интервал: (22.80, 32.40) mpg
   Стандартная ошибка бутстрапа: 2.79

График бутстрапа сохранён: bootstrap_results.png

БУТСТРАП: СРАВНЕНИЕ ТЯЖЁЛЫХ И ЛЁГКИХ АВТОМОБИЛЕЙ

Группировка по весу (медиана: 3.33):
   Лёгкие автомобили (n=16): wt ≤ 3.33
   Тяжёлые автомобили (n=16): wt > 3.33

   90-й перцентиль mpg лёгких: 31.40
   90-й перцентиль mpg тяжёлых: 18.95
   Разница: 12.45 mpg

Результаты бутстрапа для разницы:
   Точечная оценка разницы: 12.45 mpg
   95% ДИ для разницы: (7.45, 15.55) mpg
   Отличия статистически значимые: Да

График сравнения сохранён: bootstrap_comparison.png
Все графики сохранены в текущей директории!

R вывод

ORDINARY NONPARAMETRIC BOOTSTRAP

Bootstrap Statistics :
     original      bias    std. error
t1* 0.7528328 0.004827619  0.05883449

BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Level       BCa          
95%   ( 0.5843,  0.8392 )

Информация о сессии

sessionInfo()
## R version 4.5.2 (2025-10-31)
## Platform: x86_64-pc-linux-gnu
## Running under: CachyOS
## 
## Matrix products: default
## BLAS:   /usr/lib/libblas.so.3.12.0 
## LAPACK: /usr/lib/liblapack.so.3.12.0  LAPACK version 3.12.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: Europe/Samara
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] boot_1.3-32
## 
## loaded via a namespace (and not attached):
##  [1] digest_0.6.39   R6_2.6.1        fastmap_1.2.0   xfun_0.56      
##  [5] cachem_1.1.0    knitr_1.51      htmltools_0.5.9 rmarkdown_2.30 
##  [9] lifecycle_1.0.5 cli_3.6.5       sass_0.4.10     jquerylib_0.1.4
## [13] compiler_4.5.2  tools_4.5.2     evaluate_1.0.5  bslib_0.10.0   
## [17] yaml_2.3.12     rlang_1.1.7     jsonlite_2.0.0