В работе используется открытый датасет iris (встроен в
R).
Для бутстрапа будем анализировать переменную
Petal.Length (длина лепестка).
data(iris)
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
summary(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
ggplot(iris, aes(x = Petal.Length)) +
geom_histogram(bins = 15, fill = "skyblue") +
theme_minimal() +
labs(title = "Распределение Petal.Length",
x = "Petal.Length",
y = "Частота")
Пояснение графика:
Гистограмма показывает, какие значения Petal.Length встречаются чаще.
Видно, что распределение не полностью симметрично из-за различий между
видами ирисов.
ggplot(iris, aes(x = Species, y = Petal.Length)) +
geom_boxplot(fill = "lightgreen") +
theme_minimal() +
labs(title = "Petal.Length по видам ириса",
x = "Вид (Species)",
y = "Petal.Length")
Пояснение графика:
Boxplot показывает медиану, разброс и возможные выбросы. Видно, что
длина лепестка сильно отличается между видами.
Бутстрап — это многократное случайное выборочное извлечение с
возвращением.
Мы будем оценивать среднее Petal.Length и строить
распределение бутстрап-средних.
import numpy as np
import matplotlib.pyplot as plt
# данные Petal.Length
data = np.array([
1.4,1.4,1.3,1.5,1.4,1.7,1.4,1.5,1.4,1.5,
1.5,1.6,1.4,1.1,1.2,1.5,1.3,1.4,1.7,1.5,
1.7,1.5,1.0,1.7,1.9,1.6,1.6,1.5,1.4,1.6,
1.6,1.5,1.5,1.4,1.5,1.2,1.3,1.4,1.3,1.5,
1.3,1.3,1.3,1.6,1.9,1.4,1.6,1.4,1.5,1.4,
4.7,4.5,4.9,4.0,4.6,4.5,4.7,3.3,4.6,3.9,
3.5,4.2,4.0,4.7,3.6,4.4,4.5,4.1,4.5,3.9,
4.8,4.0,4.9,4.7,4.3,4.4,4.8,5.0,4.5,3.5,
3.8,3.7,3.9,5.1,4.5,4.5,4.7,4.4,4.1,4.0,
4.4,4.6,4.0,3.3,4.2,4.2,4.2,4.3,3.0,4.1,
6.0,5.1,5.9,5.6,5.8,6.6,4.5,6.3,5.8,6.1,
5.1,5.3,5.5,5.0,5.1,5.3,5.5,6.7,6.9,5.0,
5.7,4.9,6.7,4.9,5.7,6.0,4.8,4.9,5.6,5.8,
6.1,6.4,5.6,5.1,5.6,6.1,5.6,5.5,4.8,5.4,
5.6,5.1,5.1,5.9,5.7,5.2,5.0,5.2,5.4,5.1
])
B = 3000
boot_means = np.empty(B)
for i in range(B):
sample = np.random.choice(data, size=len(data), replace=True)
boot_means[i] = np.mean(sample)
mean_est = np.mean(boot_means)
ci_low, ci_high = np.percentile(boot_means, [2.5, 97.5])
plt.hist(boot_means, bins=35)
plt.axvline(mean_est, linestyle='--')
plt.axvline(ci_low, linestyle=':')
plt.axvline(ci_high, linestyle=':')
plt.title("Bootstrap means of Petal.Length (Python)")
plt.xlabel("Mean Petal.Length")
plt.ylabel("Frequency")
plt.show()
mean_est, (ci_low, ci_high)
## (np.float64(3.7578711111111107), (np.float64(3.4766166666666667), np.float64(4.038016666666667)))
Пояснение графика:
- Гистограмма показывает распределение бутстрап-средних.
- Пунктирная линия — оценка среднего.
- Две линии по краям — границы 95% доверительного интервала (percentile
CI).
Вывод (Python):
Метод бутстрапа позволяет оценить среднее Petal.Length и получить
доверительный интервал без строгих предположений о распределении
данных.
Повторим тот же подход в R, используя данные
iris$Petal.Length.
set.seed(2026)
x <- iris$Petal.Length
B <- 3000
boot_means <- replicate(B, mean(sample(x, replace = TRUE)))
mean_est <- mean(boot_means)
ci_percentile <- quantile(boot_means, probs = c(0.025, 0.975))
mean_est
## [1] 3.757568
ci_percentile
## 2.5% 97.5%
## 3.483983 4.044700
hist(boot_means, breaks = 35,
col = "lightblue",
main = "Bootstrap means of Petal.Length (R)",
xlab = "Mean Petal.Length")
abline(v = mean_est, lty = 2)
abline(v = ci_percentile[1], lty = 3)
abline(v = ci_percentile[2], lty = 3)
Пояснение графика:
Линия по центру — среднее бутстрап-оценок.
Линии по краям показывают 95% доверительный интервал.
se_boot <- sd(boot_means)
ci_normal <- c(mean_est - 1.96*se_boot, mean_est + 1.96*se_boot)
ci_normal
## [1] 3.476762 4.038375
Короткий вывод:
Percentile CI строится по квантилям бутстрап-распределения, а Normal CI
использует оценку стандартной ошибки и приближение нормальностью.
iris был выбран как открытый пример.