Берём открытый датасет iris. Для бутстрапа будем
оценивать медиану переменной Sepal.Length
(так работа будет отличаться от предыдущих вариантов, где было среднее и
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)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 4.300 5.100 5.800 5.843 6.400 7.900
ggplot(iris, aes(x = Sepal.Length)) +
geom_histogram(bins = 14, fill = "lightcoral") +
theme_minimal() +
labs(title = "Распределение Sepal.Length",
x = "Sepal.Length",
y = "Частота")
Простое объяснение графика:
Гистограмма показывает, какие значения Sepal.Length
встречаются чаще всего.
ggplot(iris, aes(x = Species, y = Sepal.Length)) +
geom_boxplot(fill = "khaki") +
theme_minimal() +
labs(title = "Sepal.Length по видам ириса",
x = "Species",
y = "Sepal.Length")
Простое объяснение графика:
Boxplot показывает медиану (линия внутри), разброс (коробка) и возможные
выбросы (точки).
Бутстрап: много раз выбираем случайную выборку с возвращением и считаем статистику (здесь — медиану).
import numpy as np
import matplotlib.pyplot as plt
# Sepal.Length из iris (значения берем прямо числом для автономности примера)
data = np.array([
5.1,4.9,4.7,4.6,5.0,5.4,4.6,5.0,4.4,4.9,
5.4,4.8,4.8,4.3,5.8,5.7,5.4,5.1,5.7,5.1,
5.4,5.1,4.6,5.1,4.8,5.0,5.0,5.2,5.2,4.7,
4.8,5.4,5.2,5.5,4.9,5.0,5.5,4.9,4.4,5.1,
5.0,4.5,4.4,5.0,5.1,4.8,5.1,4.6,5.3,5.0,
7.0,6.4,6.9,5.5,6.5,5.7,6.3,4.9,6.6,5.2,
5.0,5.9,6.0,6.1,5.6,6.7,5.6,5.8,6.2,5.6,
5.9,6.1,6.3,6.1,6.4,6.6,6.8,6.7,6.0,5.7,
5.5,5.5,5.8,6.0,5.4,6.0,6.7,6.3,5.6,5.5,
5.5,6.1,5.8,5.0,5.6,5.7,5.7,6.2,5.1,5.7,
6.3,5.8,7.1,6.3,6.5,7.6,4.9,7.3,6.7,7.2,
6.5,6.4,6.8,5.7,5.8,6.4,6.5,7.7,7.7,6.0,
6.9,5.6,7.7,6.3,6.7,7.2,6.2,6.1,6.4,7.2,
7.4,7.9,6.4,6.3,6.1,7.7,6.3,6.4,6.0,6.9,
6.7,6.9,5.8,6.8,6.7,6.7,6.3,6.5,6.2,5.9
])
B = 2500
boot_medians = np.empty(B)
for i in range(B):
sample = np.random.choice(data, size=len(data), replace=True)
boot_medians[i] = np.median(sample)
median_est = np.median(boot_medians)
ci_low, ci_high = np.percentile(boot_medians, [2.5, 97.5])
plt.hist(boot_medians, bins=30)
plt.axvline(median_est, linestyle='--')
plt.axvline(ci_low, linestyle=':')
plt.axvline(ci_high, linestyle=':')
plt.title("Bootstrap distribution of median (Python)")
plt.xlabel("Median Sepal.Length")
plt.ylabel("Frequency")
plt.show()
median_est, (ci_low, ci_high)
## (np.float64(5.8), (np.float64(5.6), np.float64(6.0)))
Простое объяснение графика:
- Гистограмма показывает распределение бутстрап-медиан.
- Пунктир — “типичное” значение медианы.
- Две линии по краям — 95% доверительный интервал.
set.seed(42)
x <- iris$Sepal.Length
B <- 2500
boot_medians <- replicate(B, median(sample(x, replace = TRUE)))
median_est <- median(boot_medians)
ci <- quantile(boot_medians, probs = c(0.025, 0.975))
median_est
## [1] 5.8
ci
## 2.5% 97.5%
## 5.6 6.0
hist(boot_medians, breaks = 30,
col = "lightgray",
main = "Bootstrap distribution of median (R)",
xlab = "Median Sepal.Length")
abline(v = median_est, lty = 2)
abline(v = ci[1], lty = 3)
abline(v = ci[2], lty = 3)
Простое объяснение графика:
Линия в центре — оценка медианы по бутстрапу, крайние линии — границы
95% интервала.