Ако имаме наблюдения \(x_1, ..., x_n\) над случайна величина \(X \sim \mathcal{N}(\mu, \sigma^2)\), то можем да мислим на всяко наблюдение \(x_i\) като на наблюдение от случайна величина \(X_i\) разпределена като \(X\) и \(X_i\) са независими. Тоест, имаме независими и еднакво разпределени (н.е.р.) случайни величини \(X_1, ..., X_n \overset{distr}{\sim} X \sim \mathcal{N}(\mu, \sigma^2)\), като сме получили по едно наблюдение от всяка. Векторът \((X_1,...,X_n)\) наричаме случайна извадка.
Тогава \(\bar{x} := \frac{1}{n}\sum_{i=1}^n{x_i}\) е наблюдение от случайната величина \(\bar{X} := \frac{1}{n}\sum_{i=1}^n{X_i} \sim \mathcal{N}(\mu, \frac{\sigma^2}{n})\), понеже \[ E[\bar{X}] = E[\frac{1}{n}\sum_{i=1}^n{X_i}]=\frac{1}{n}\sum_{i=1}^n{E[X_i]}=\frac{1}{n}n\mu = \mu\\ Var[\bar{X}]=Var[\frac{1}{n}\sum_{i=1}^n{X_i}] = \frac{1}{n^2}n\sigma^2=\frac{\sigma^2}{n} \]
Забелязваме, че \(Var[\bar{X}] \xrightarrow[n\to \infty]{} 0\). Тоест, колкото повече наблюдения имаме, толкова повече \(\bar{x}\) има вероятност да е близо до истинския параметър \(\mu\), понеже ще е наблюдение от нормално разпределена случайна величина с дисперсия \(\frac{\sigma^2}{n}\) и очакване \(\mu\).
Можем да наблюдаваме този факт със следната симулация
# library("tidyverse")
# library("ggplot2")
# брой извадки които взимаме
n <- 1000
# 1000 пъти взимаме средно на 10, 100 и 1000 наблюдения от N(25, 40^2)
c(10, 100, 1000) %>%
map(function(size) {
# Взимаме средното на size на брой наблюдения от N(25, 40^2)
map(1:n, ~mean(rnorm(size, mean = 25, sd = 40))) %>%
unlist() %>%
data.frame(x = ., size = as.character(size))
}) %>%
bind_rows() %>%
ggplot() +
geom_density(mapping = aes(x = x, fill = size)) +
facet_wrap(~size) +
ggtitle("Плътност на извадково средно при n=10, 100, 1000") +
xlab("извадково средно") +
ylab("емпирична плътност на извадково средно") +
# theme_pomological_nobg(base_family = "Pacifico", base_size = 16) +
theme_pomological_nobg(base_family = "Pacifico", base_size = 16) +
scale_fill_pomological() +
scale_color_pomological()
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Още една визуализация
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
## Picking joint bandwidth of 0.721
## Warning: This manual palette can handle a maximum of 9 values. You have supplied
## 10.
\(\bar{X}\) наричаме точкова оценка за параметъра \(\mu\). Това, че \(Е(\bar{X}) = \mu\) наричаме неизместеност на оценката. Когато една точкова оценка \(f_{\theta}(\overrightarrow{X})\) приближава по вероятност своя параметър \(\theta\), тоест \[ \lim_{n\to \infty}Pr(|f_{\theta}(\overrightarrow{X}) - \theta| > \epsilon) = 0 \text{ за } \forall \epsilon > 0 \] казваме, че точковата оценка \(f_{\theta}(\overrightarrow{X})\) е асимптотично консистента.
Стандартното отклонение на оценката, обикновено наричаме стандартна грешка.
Ако имаме наблюдения над случайна величина \(X \sim \mathcal{N}(\mu^?, \sigma^2)\) за която \(\mu^?\) е неизвестен параметър, но \(\sigma^2\) е известна (в практиката рядко ще знаем който и да е параметър), то знаем, че
\[ Z := \frac{\bar{X} - \mu^?}{\sigma/\sqrt{n}} \sim \mathcal{N}(0, 1) \]
и следователно, можем да използваме определен квантил q от \(\mathcal{N}(0, 1)\), така че
\[ P(-q < \frac{\bar{X} - \mu^?}{\sigma/\sqrt{n}} < q) = \gamma \]
Така, с вероятност \(\gamma\) (ниво на достоверност) можем да сме сигурни, че
\[ \bar{X} - q \frac{\sigma}{\sqrt{n}} < \mu^? < \bar{X} + q \frac{\sigma}{\sqrt{n}} \]
В R за 95% интервал на достоверност, това ще стане по следния начин
# брой елементи
n <- 1000
# сигма ни е известно, но мю не ни е и се опитваме да го оценим
known_sd <- 10
x <- rnorm(n, 14.55, known_sd)
emp_mean <- mean(x)
q <- qnorm(0.975)
c(emp_mean - q * known_sd / sqrt(n), emp_mean + q * known_sd / sqrt(n))
## [1] 13.60031 14.83990
В повечето случаи обаче, \(\sigma\) не ни е известно. Тогава, ако заместим с извадковото стандартно отклонение S, случайната величина \(\frac{\bar{X} - \mu}{S/\sqrt{n}}\) има \(\mathcal{T}\) разпределение с \(n - 1\) степени на свобода. В този случай, трябва просто да използваме квантилите от \(\mathcal{T}\) разпределение.
n <- 1000
x <- rnorm(n, 25, 7.654)
emp_mean <- mean(x)
emp_sd <- sd(x)
q <- qt(0.975, df = n - 1)
c(emp_mean - q * emp_sd / sqrt(n), emp_mean + q * emp_sd / sqrt(n))
## [1] 24.59308 25.54813
Или с t.test функцията
t.test(x)
##
## One Sample t-test
##
## data: x
## t = 103.03, df = 999, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 24.59308 25.54813
## sample estimates:
## mean of x
## 25.07061
Получената оценка за \(\mu\) се нарича интервална оценка. Ето как изглеждат интервалите на достоверност при Нормално и \(\mathcal{T}\) разпределение за случайната величина Z дефиниране по-горе.
# library("ggridges")
n <- 100000
list("normal" = rnorm(n), "t" = rt(n, 100000 - 1)) %>%
imap(~data.frame(x = .x, distribution = .y)) %>%
bind_rows() %>%
ggplot(aes(x = x, y = distribution, fill = factor(stat(quantile)))) +
stat_density_ridges(
geom = "density_ridges_gradient",
calc_ecdf = TRUE,
quantiles = c(0.025, 0.975)
) +
scale_fill_manual(
name = "Probability", values = c("#FF0000A0", "#62b5b2", "#FF0000A0"),
labels = c("(0, 0.025]", "(0.025, 0.975]", "(0.975, 1]")
) +
xlab("Z") +
theme_minimal()
## Picking joint bandwidth of 0.09
Нека симулираме различни извадки от нормално разпределена случайна величина с \(\mu=3\) и \(\sigma^2 = 2\) и да видим в колко от случаите ще попадаме в интервала на достоверност.
simulate_t <- function(n, mu, sigma) {
x <- rnorm(n, mu, sigma)
b1 <- mean(x) - qt(0.975, df = n - 1) * (sd(x) / sqrt(n))
b2 <- mean(x) + qt(0.975, df = n - 1) * (sd(x) / sqrt(n))
between(mu, b1, b2)
}
# да преброим колко елементи са в интервала на достоверност
simulations <- replicate(10000, simulate_t(40, 4, 4))
mean(simulations)
## [1] 0.9538
Виждме, че наистина в около 95% от случаите попадаме в интервала на достоверност.
Хипотеза наричаме какво да е твърдение за функцията на разпределение \(F_X\) на случайната величина \(Х\) върху която имаме извадка \((X_1, ..., X_n)\).
Нека наблюдаваме данни идващи от нормално разпределение, примерно от \(\mathcal{N}(176, 6^2)\) за които не знаем истинската стойност на \(\mu\) (за момент забравяме, че сме ги генерирали с \(\mu=176\))
heights <- rnorm(100, 176, 6)
Ако примем, че истинското математическо очакване \(\mu\) е по-голямо или равно на 190, то случайната величина
\[ Z := \frac{\bar{X} - 190}{\sigma / \sqrt{n}} \] ще бъде нормално разпределена с \(\mu=0\) и \(\sigma^2=1\)
# z-statistic
z <- (mean(heights) - 190) / (6 / sqrt(100))
z
## [1] -24.37082
Можем да видим вероятността да имаме стойност z или по-малка използвайки функцията pnorm
pvalue <- pnorm(z)
# Вероятността да сме наблюдавали z или по-крайна стойност на z
pvalue
## [1] 1.744098e-131
Виждаме, че ако хипотезата, че \(\mu \ge 190\) e вярна, то е изключително малко вероятно да наблюдаваме \(z\)-статистиката, която имаме (или по-крайна). Тогава, можем да отхвърлим хипотезата, че \(\mu \ge 190\). Но колко трябва да е малко нашето pvalue, така че да отхвърлим хипотезета \(H_0\) че \(\mu \ge 190\) и да приемем алтернативата \(H_1\) че \(\mu < 190\). Ако изберем някакво \(\alpha\), примерно \(\alpha = 0.05\) (ниво на значимост) можем да отхвърляме хипотезата \(H_0\) само когато \(pvalue < \alpha := 0.05\) и вероятността \(P(\text{Отхвърляне}|H_0=True):= \alpha\) да отхвърлим хипотезата \(H_0\), когато тя е вярна е 0.05 (Грешка от първи род). Областта \(\mathcal{C}\) в която избираме да отхвърлим нулевата хипотеза, когато вектора на наблюденията \((x_1, ..., x_n)\) попадне в нея, наричаме критична област. В нашия случай, критичната област е
\[ \mathcal{C}:= \{(x_1, ..., x_n): \frac{\bar{x}-\mu_{H}}{\sigma/\sqrt{n}} < q^{\mathcal{N}(0,1)}_{\alpha}\} \]
Ако не успеем да отхвърлим хипотезата \(H_0\), а тя се окаже грешна, правиме грешка от втори род. Нейната вероятност \(P(\text{Приемане}|H_0=False)\) бележим с \(\beta\). Сила на теста \(\pi:= 1-\beta\) наричаме вероятността да отхвърлим \(H_0\) при условие, че \(H_0\) наистина е грешна и е вярна \(H_1\).
| Вярно | Приемаме \(H_0\) | Отхвърляме \(H_0\) |
|---|---|---|
| \(H_0\) | Вярно | Грешка от 1ви род с вероятност \(\alpha\) |
| \(H_1\) | Грешка от 2ри род с вероятност \(\beta\) | Вярно със сила \(\pi := 1-\beta\) |
Когато \(\sigma\) също е неизвестна, то
\[ Т := \frac{\bar{X} - 190}{S / \sqrt{n}} \sim \mathcal{T}(n-1) \] и за да видим вероятността да наблюдаваме такава стойност или по-крайна (при услувие, че нулевата хипотеза е вярна), трябва да използваме функцията pt и да заместим \(\sigma\) с \(S\) във формулата за \(Z\)
t <- (mean(heights) - 190) / (sd(heights) / sqrt(100))
pvalue <- pt(t, length(heights) - 1)
# вероятността да сме наблюдавали z или по-крайна стойност от z, при условие, че
# нулевата хипотеза е вярна.
pvalue
## [1] 3.131185e-44
Отново, можем да използваме функцията t.test, която да ни даде цялата информация.
t.test(heights, mu = 190, alternative = "less")
##
## One Sample t-test
##
## data: heights
## t = -24.575, df = 99, p-value < 2.2e-16
## alternative hypothesis: true mean is less than 190
## 95 percent confidence interval:
## -Inf 176.3655
## sample estimates:
## mean of x
## 175.3775
За разлика от подхода при интервални оценки, при тестване на хипотези, центрираме тестовата статистика \(Z\) около хипотетичен параметър и отхвърляме нулевата хипотеза \(H_0\) когато наблюдаваната (или по-крайна) тест статистика \(Z\) се случва с много малък шанс.
## Picking joint bandwidth of 0.0899
# Тестване на хипотезата, че E(X) < 130
t.test(heights, mu = 130, alternative = "greater")
##
## One Sample t-test
##
## data: heights
## t = 76.263, df = 99, p-value < 2.2e-16
## alternative hypothesis: true mean is greater than 130
## 95 percent confidence interval:
## 174.3896 Inf
## sample estimates:
## mean of x
## 175.3775
## Picking joint bandwidth of 0.0901
# Тестване на хипотезата, че E(X) = 165
t.test(heights, mu = 130, alternative = "two.sided")
##
## One Sample t-test
##
## data: heights
## t = 76.263, df = 99, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 130
## 95 percent confidence interval:
## 174.1969 176.5581
## sample estimates:
## mean of x
## 175.3775
Ако не искаме да правим грешка от първи род, можем да намалим областта на \(\alpha\), но така ще отхвърляме прекалено лесно и ще качим вероятността за грешка от втори род.
Нека симулираме \(T\)-статистиката при вярна нулева хипотеза.
simulate_t <- function(n, th_mean, th_std, hyp_mean) {
x <- rnorm(n, th_mean, th_std)
(mean(x) - hyp_mean) / (sd(x) / sqrt(n))
}
# да преброим колко елементи са в критичната област
simulations <- replicate(10000, simulate_t(40, 4, 4, 4))
q <- qt(p = 0.05, df = 39)
mean(simulations <= q)
## [1] 0.0488
Виждаме, че дори при вярна нулева хипотеза, в 1 на 20 случаи ще попадаме в критичната област. Тогава, ако попаднем в тази област при вярна нулева хипотеза, ще отхвърлим нулевата хипотеза като грешна и ще направим грешка от първи род.
Нека симулираме данни от две различни разпределение ; \(X_1 \sim \cal{N(\mu_1, \sigma^2)}\) и \(X_2 \sim \cal{N(\mu_2, \sigma^2)}\) с цел да видим как се променят грешките от втори род \(\beta\) при увеличаване на броя на елементите \(n\) с които изграждаме тестовата статистика.
simulate_t <- function (n, m, std = 10) {
observations <- rnorm(n, m, std)
mean(observations) / (sd(observations) / sqrt(n))
}
simulate_ht <- function(n, n_sim, mean1, mean2, std = 10) {
set.seed(1)
bind_rows(
data.frame(
x = replicate(n_sim, simulate_t(n, mean1, std)),
distribution = paste0("средно=", mean1),
n = as.factor(n)
),
data.frame(
x = replicate(n_sim, simulate_t(n, mean2, std)),
distribution = paste0("средно=", mean2),
n = as.factor(n)
)
)
}
c(5, 10, 20, 30, 70, 140) %>%
imap(~simulate_ht(.x, 10000, 5, 8, 6)) %>%
bind_rows() %>%
ggplot(mapping = aes(x = x, fill = distribution)) +
geom_density(alpha = 0.55) +
xlim(c(-5, 20)) +
facet_wrap(~n) +
xlab("Т-статистика") +
ylab("Вероятностни плътности") +
ggtitle("Промяна на силата при увеличаване на броя на елементи") +
theme_pomological_nobg(base_family = "Pacifico", base_size = 16) +
scale_fill_pomological() +
scale_color_pomological() +
theme(legend.position = "bottom")
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
## Warning: Removed 48 rows containing non-finite values (stat_density).
Виждаме, че при растящ брой елементи \(n\), областта в която бихме могли да направим грешка от втори род намалява, понеже дисперсията на T-статистиката под нулевата хипотеза намалява и разпределението се центрира около хипотетичния си параметър. По този начин, \(\beta\) намалява, докато силата на теста \(\pi:= 1-\beta\) се увеличава.
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Забелязваме, че силата на теста \(\pi\) расте при увеличаване на броя на наблюденията, но при по-голямо стандартно отклонение, скоростта на растеж на \(\pi\) намалява.
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
При качване на нивото на значимост \(\alpha\), качваме силата на теста (\(\pi\)) и намаляваме вероятността за грешка от втори род \(\beta\), но по този начин увеличаваме вероятността за грешка от първи род \(\alpha\).
Ако имаме еднакъв брой наблюдения от две случайни величини \(X\) и \(Y\), които са нормално разпределени с еднакви дисперсии - съответно, \(X \sim \mathcal{N}(\mu_1, \sigma^2)\) и \(Y \sim \mathcal{N}(\mu_2, \sigma^2)\), можем да зададем нулева хипотеза \(H_0 := \mu_1 = \mu_2\). Ако нулевата хипотеза е вярна, то \(\bar{X} - \bar{Y} \sim \mathcal{N}(0, \frac{2\sigma^2}{n})\). Тогава
\[ Т := \frac{\bar{X}-\bar{Y}}{\sqrt{\frac{S_1^2}{n} + \frac{S_2^2}{n}}} \sim \mathcal{T}(2n - 2) \]
Тогава, можем да използваме досегашния подход при тестване на хипотези за да проверим дали наистина \(\mu_1=\mu_2\).
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Aко имаме \(pvalue < \alpha\), където \(\alpha\) е нивото на значимост, а t e наблюдаваната стойност за T-статистиката, можем да отхвърлим нулевата хипотеза, че \(\mu_1=\mu_2\).
# брой елементи в двете случайни извадки
n <- 40
# Симулации на случайни извадки от с.в. X ~ N(3, 9) и Y ~ N(4, 9)
x <- rnorm(n, 3, 3)
y <- rnorm(n, 4, 3)
# Извадкови вариации
v1 <- var(x)
v2 <- var(y)
# Степени на свобода за T-разпределението
degrees_of_freedom <- 2 * n - 2
# Наблюдаваната стойност от T-статистиката
t <- (mean(x) - mean(y)) / sqrt(v1 / 40 + v2 / 40)
# Изчисление за pvalue при двустранен тест
pval <- 2 * min(
pt(q = t, df = degrees_of_freedom, lower.tail = TRUE),
pt(q = t, df = degrees_of_freedom, lower.tail = FALSE)
)
# резултат
c("t" = t, "pvalue" = pval, "df" = degrees_of_freedom)
## t pvalue df
## -1.9004828 0.0610646 78.0000000
Или ако просто използваме t.test
t.test(x, y, var.equal = TRUE)
##
## Two Sample t-test
##
## data: x and y
## t = -1.9005, df = 78, p-value = 0.06106
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -2.67067950 0.06201836
## sample estimates:
## mean of x mean of y
## 2.835611 4.139941
Когато работим с предположението, че дисперсиите са еднакви, но имаме различен брой наблюдения от двете случайни извадки, за да оценим по-точно общата дисперсия посредством извадъчните дисперсии, използваме формулата за комбинирана извадъчна дисперсия и съответно - фoрмулата за комбинирано стандартно отклонение.
\[ S_p^2 = \frac{(n - 1)S_1^2 + (m - 1)S_2^2}{n + m - 2} \]
където \(n\) и \(m\) са броят на елементите в двете извадки, а \(S_i\) са извадъчните дисперсии на двете извадки. В този случай T-статистиката е
\[ Т := \frac{\bar{X}-\bar{Y}}{S_p\sqrt{\frac{1}{n} + \frac{1}{m}}} \sim \mathcal{T}(n + m - 2) \]
# Формула за смесено извадъчно стандартно отклонение
pooled_sd <- function (x, y) {
n1 <- length(x)
n2 <- length(y)
sqrt(
((n1 - 1) * var(x) + (n2 - 1) * var(y))
/
(n1 + n2 - 2)
)
}
# броя на елементите в двете случайни извадки които ще симулираме
n <- 30
m <- 40
# Симулации с различен брой над с.в.
x <- rnorm(n, 3, 2)
y <- rnorm(m, 4, 2)
# Степени на свобода
degrees_of_freedom <- n + m - 2
# Наблюдавана стойност t на Т-статистиката
t <- (mean(x) - mean(y)) / (pooled_sd(x, y) * sqrt((1 / n) + (1 / m)))
# Изчисление за pvalue при двустранен тест
pvalue <- 2 * min(
pt(t, degrees_of_freedom, lower.tail = TRUE),
pt(t, degrees_of_freedom, lower.tail = FALSE)
)
# резултат
c("t" = t, "pvalue" = pvalue, "df" = degrees_of_freedom)
## t pvalue df
## -1.86249033 0.06685454 68.00000000
Или с t.test
t.test(x, y, var.equal = TRUE)
##
## Two Sample t-test
##
## data: x and y
## t = -1.8625, df = 68, p-value = 0.06685
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -1.80818636 0.06232572
## sample estimates:
## mean of x mean of y
## 2.937953 3.810884
Когато работим с предположението, че дисперсиите на двете случайни величини \(X\) и \(Y\) не са еднакви, тоест \(\sigma_X^2 := D(X) \neq D(Y) =: \sigma_Y^2\), за степените на свобода използваме формулата за комбинирани степени на свобода.
\[ df_{c} := \frac{(\frac{S_1^2}{n} + \frac{S_2^2}{m})^2}{\frac{(S_1^2/n)^2}{n-1} + \frac{(S_2^2/m)^2}{m-1}} \]
В този случай Т-статистиката ще е
\[ Т := \frac{\bar{X}-\bar{Y}}{\sqrt{\frac{S_1^2}{n} + \frac{S_2^2}{m}}} \sim \mathcal{T}(df_{c}) \]
# брой наблюдения над симулираните случайни извадки
n <- 30
m <- 40
# Симулации с различен брой наблюдения над нормално разпределени с.в.
x <- rnorm(n, 3, 2)
y <- rnorm(m, 4, 3)
# Извадъчни дисперсии
v1 <- var(x)
v2 <- var(y)
# Смесени степени на свобода
degrees_of_freedom <- (
(v1 / n + v2 / m)^2
/
((v1 / n)^2 / (n - 1) + (v2 / m)^2 / (m - 1)))
t <- (mean(x) - mean(y)) / sqrt(v1 / n + v2 / m)
# Изчисление за pvalue при двустранен тест
pvalue <- 2 * min(
pt(t, degrees_of_freedom, lower.tail = TRUE),
pt(t, degrees_of_freedom, lower.tail = FALSE)
)
# резултат
c("t" = t, "pvalue" = pvalue, "df" = degrees_of_freedom)
## t pvalue df
## -1.151663 0.253680 64.971366
Или за по-кратко с t.test
t.test(x, y, alternative = "two.sided")
##
## Welch Two Sample t-test
##
## data: x and y
## t = -1.1517, df = 64.971, p-value = 0.2537
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -1.9534532 0.5245233
## sample estimates:
## mean of x mean of y
## 3.077375 3.791840
Сдвоени данни (наблюдения) от две извадки наричаме, такива при при които имаме зависимост между извадките и няблюденията идват от едни и същи индивиди, но в различен етап от време. Тоест \(x_i\) и \(y_i\) са наблюдения върху един и обект. Пример за това би бил ефекта върху нивото на холестерола преди и след приемането на лекарство от едни и същи хора. При несдвоени данни, имаме наблюдения от независими извадки \(X\) и \(Y\). Пример за това би бил, кръвното на група която не приема определено лекарство, и кръвното на група която е приела лекарството. При t.test в този случай, при нулева хипотеза \(H_0 := \mu_0=0\), тест статистиката \(Т\) би била \[ T := \frac{(\bar{X} - \bar{Y})-(\mu_1-\mu_2)}{st.dev(\bar{X}-\bar{Y})} = \frac{\bar{X}_D-\mu_0}{S_D/\sqrt{n}} \sim \mathcal{T}(n - 1) \] където \(\bar{X}_D\) и \(S_D\) са извадъчното средно и стандартно отклонение върху разликите между всички наблюдения.
# Брой елементи от които ще симулираме извадка
n <- 30
# Симулираме наблюдения от с.в.
x <- rnorm(n, 80, 4)
y <- rnorm(n, 84, 4)
# Тест статистика при сдвоен тест
t <- mean(x - y) / (sd(x - y) / sqrt(30))
# Изчисление на pvalue
pvalue <- 2 * min(pt(t, n - 1), pt(t, n - 1, lower.tail = FALSE))
# резултат
c("t" = t, "pvalue" = pvalue, "df" = n - 1)
## t pvalue df
## -2.38593558 0.02378466 29.00000000
Отново, можем да ползваме t.test
t.test(x, y, paired = TRUE)
##
## Paired t-test
##
## data: x and y
## t = -2.3859, df = 29, p-value = 0.02378
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -4.5515669 -0.3499634
## sample estimates:
## mean of the differences
## -2.450765
Т-тестът работи с предположението, че имаме извадки от нормално разпределени случайни величини (популации) и в този случай, трябва да проверим дали нашите данни отговарят на това условие. Поради Централната Гранична Теорема, стига да имаме достатъчно наблюдения (като правило се счита над 30), можем да ползваме Т-тест и без данните ни да следват нормално разпределение, защото
\[ \frac{\bar{X} - \mu}{\sigma/\sqrt{n}} \to_d \mathcal{N}(0, 1) \]
Когато тези условия не са спазени, можем да ползваме Непараметричен тест на Уилкоксън.
Тестът на Уилкоксън е непараметричен тест, който ни позволява да да сравним две извадки, без да правим преположение за вероятностното разпределение което стои зад тях. Предположенията върху които той стъпва са следните
При теста на Уилкоксън, работим с нулевата хипотеза \(H_0 := P(x_i > y_i) = \frac{1}{2}\), срещу алтернативата \(H_1 := P(x_i > y_i) \neq \frac{1}{2}\) и следната \(U\)-статистика.
Нека имаме \(X_1, ...,X_n\) е независима случайна извадка от \(X\) и \(Y_1, ...,Y_n\) е независима случайна извадка от \(Y\) и
\[ U := \sum_{i=1}^n\sum_{j=1}^mS(X_i, Y_j) \]
където
\[ S(X, Y) := \begin{cases} 1,& \text{if } Y < X\\ 1/2, & \text{if } Y = X \\ 0, & \text{if } Y > X \\ \end{cases} \] Разпределението на \(U\) е добре известно и го има във всеки справочник. В R функцията на разпределението му е pwilcox. Виждаме, че \(U\) брои броя на инверсиите между Y и Х. Тоест, ако имаме изместеност (Y и X не са с един център), наблюдаваната стойност за \(U\)-статистиката ще бъде в някаква крайна област на разпределението.
s <- function(x, y) (y < x) + .5 * (y == x)
x <- c(1, 5, 7, 2, 5, 9, 3, 2, 1, 12)
y <- c(8, 3, 13, 11, 6, 12, 15, 10, 6, 8)
U <- sum(unlist(map(x, ~sum(s(.x, y)))))
c("U" = U, "pvalue" = 2 * pwilcox(U, n = length(x), m = length(y)))
## U pvalue
## 18.00000000 0.01468964
Отново, има функция която изпълнява целия тест
# Дава леко по-различни резултати поради вътрешни оптимизации
wilcox.test(x, y)
## Warning in wilcox.test.default(x, y): cannot compute exact p-value with ties
##
## Wilcoxon rank sum test with continuity correction
##
## data: x and y
## W = 18, p-value = 0.01696
## alternative hypothesis: true location shift is not equal to 0
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Виждаме, че разпределението прилича на Нормално разпределение при увеличение на броя на наблюдения \(n\). При достатъчен брой наблюдения, разпределението на тест статистиката може да се апроксимира с нормално.
Тестът на Уилкоксън може да бъде изпълнен при всички от горните случаи
Ако имаме случайна извадка \((Y_1, ..., Y_n)\) от биномно разпределена сл.в. \(Y \sim Bin(n, p)\), можем да обозначим броя наблюдавани успехи (елементи от едната група) с \(О_S\), а броя наблюдавани неуспехи с \(О_F\) (елементи от другата група), и съответно техните очаквани стойности с \(E_S\) и \(E_F\).
Тогава, от Централната гранична теорема
\[ X := \frac{Y-np}{\sqrt{np(1-p)}} \to_d \mathcal{N}(0, 1) \]
Следователно \(X^2 \to_d \chi^2(1)\) и ако имаме достатъчно наблюдения \(n\), \(X^2\) ще има приблизително \(\chi^2\) разпределение с една степен на свобода.
Oт това, че \(\frac{1}{p(1-p)}=\frac{1}{p} + \frac{1}{n-p}\), и това, че \((Y-np)^2=[(n-Y)-n(1-p)]^2\), можем да представим \(X^2\) по следния начин \[ X^2 := \frac{(Y-np)^2}{np(1-p)} = \frac{(Y-np)^2}{np}+\frac{(Y-np)^2}{n(1-p)}=\\ = \frac{(Y-np)^2}{np}+\frac{[(n-Y)-n(1-p)]^2}{n(1-p)} =\\ = \frac{(O_S-E_S)^2}{E_S}+\frac{(O_F-E_F)^2}{E_F} \] По този начин, при \(n\) наблюдавани стойности, можем да тестваме нулева хипотеза, че очакваният брой успехи (елементи от едната група) \(E_S = np_S\) е определено число, а очаквания брой неуспехи ( елементи от другата група) \(E_F =np_F\)е друго число. Също, можем да тестваме и хипотези за самите вероятности на двете групи \(p_S\) и \(p_F\). Ако нулевата хипотеза не е вярна, наблюдаваната \(X^2\) статистика ще е прекалено надясно от \(0\).
Както при биномно разпределена случайна величина, така и при такава с много групи (мултиномно разпределена), съществува асимптотична апроксимация с нормално разпределение. В такъв случай, можем да направим сходни разсъждения за \(k\) на брой различни групи и \[ X^2 := \sum_{i=1}^k\frac{(O_i-E_i)^2}{E_i} \]
ще има, отново асимптотично приблизително \(\chi^2\) разпределение, но този път с \(k-1\) степени на свобода, където \(О_i\) и \(E_i\) са наблюдавания и очаквания брой елементи под \(H_0\) от \(i\)-тата група.
| Група 1 | Група 2 | … | Група k | |
|---|---|---|---|---|
| Наблюдавани | \(O_1 := n\hat{p_1}\) | \(O_2 := n\hat{p_2}\) | … | \(O_k := n\hat{p_k}\) |
| Очаквани под \(H_0\) | \(E_1 := np_1\) | \(E_2 := np_2\) | … | \(E_k := np_k\) |
Нека симулираме разпределенията на \(X^2\) при вярна нулева хипотеза и различен брой групи, с цел да видим, че наистина имат приблизително \(\chi^2\) разпределения.
simulate_chsq <- function(n = 60, th_probs, hyp_probs) {
k = length(hyp_probs)
# Правим извадка от к на брой групи с теоретични вероятности за всяка - th_probs
x <- sample(1:k, prob = th_probs, size = n, replace = TRUE)
# изграждаме брой елементи във всяка група
observed <- unlist(map(1:k, ~sum(x == .x)))
# очакваните бройки елементи ако нулевата хипотеза е вярна
expected <- n * hyp_probs
# връщаме X^2 статистиката
sum((observed - expected)^2 / expected)
}
# общ брой елементи от всички групи
n <- 120
# Брой симулации на X^2-статистиката
s <- 2000
# за степени на свобода от 4 до 10 генерираме X^2 статистики
5:11 %>%
imap(
~data.frame(
# Задаваме истинските вероятности за нулева хипотеза, така че да видим разпределенията
x = replicate(s, simulate_chsq(n, th_probs = rep(1 / .x, .x), hyp_probs = rep(1 / .x, .x))),
df = as.factor(.x)
)
) %>%
# сливаме всички data.frames в един data.frame с цел да визуализираме по-лесно
bind_rows() %>%
ggplot(mapping = aes(x = x, fill = df)) +
geom_density(alpha = 0.25) +
ggtitle("X^2 статистиката с Хи-квадрат разпределение") +
xlab("X^2") +
ylab("Емпирична Плътност") +
theme_pomological_nobg(base_family = "Pacifico", base_size = 16) +
scale_fill_pomological() +
scale_color_pomological()
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Нека направим тест с четири групи симулирани с теоретични вероятности 1/4 за всяка и \(n=60\). Тогава, ако тестваме нулевата хипотеза \(H_0 := \{p_1=1/2, p_2 = p_3=p_4=1/6\}\), нашата \(X^2\) статистика би трябвало да е прекалено надясно от нулата.
xsquared <- simulate_chsq(n = 60, th_probs = rep(1 / 4, 4), hyp_probs = c(1/2, 1/6, 1/6, 1/6))
pvalue <- pchisq(xsquared, df = 3, lower.tail = FALSE)
c("X^2" = xsquared, "pvalue" = pvalue, "df" = 3)
## X^2 pvalue df
## 15.800000000 0.001246226 3.000000000
| Група 1 | Група 2 | Група 3 | Група 4 | |
|---|---|---|---|---|
| Истински Очаквания | 15 | 15 | 15 | 15 |
| \(O_i := n\hat{p_i}\) := Наблюдавани | 14 | 13 | 17 | 16 |
| \(E_i := np_i\) := Очаквани под \(H_0\) | 30 | 10 | 10 | 10 |
| \(\frac{(O_i-E_i)^2}{E_i}\) | \(\frac{(14-30)^2}{30}=8.53\) | \(\frac{(13-10)^2}{10}=0.90\) | \(\frac{(17-10)^2}{10}=4.90\) | \(\frac{(16-10)^2}{10}=3.60\) |
Виждаме, че вероятността да наблюдаваме стойност по-голяма или равна от \(17.93\) на \(X^2\)-статистиката е много малка (\(pvalue := P(X^2\ge17.93) < 0.005\)). В такъв случай, можем да отхвълим нулевата хипотеза, че очакваните вероятности са \(\{p_1=1/2, p_2 = p_3=p_4=1/6\}\).
Критичните области и техните pvalue-та биха изглеждали така
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
## Picking joint bandwidth of 1.71
В R за улеснение, използваме функцията chisq.test(x, p) където x ще е наблюдаван брой елементи в различните групи, а p е вероятностите под нулевата хипотеза, за различните групи.
Ако имаме дискретни данни, бихме могли да тестваме хипотезата, че наблюдаваната извадка идва от дискретна случайна величина с избрано от нас разпределение.
Нека имаме случайна извадка \(X_1, ..., X_{100} \sim^d X \sim Poi(2)\). Искаме да тестваме хипотезата \(H_0 := \lambda = 2.5\) срещу алтернативата \(H_1 := \lambda \neq 2.5\)
# брой наблюдения които имаме
n <- 100
set.seed(2)
# Стойностите които примерно сме наблюдавали
observed_props <- rpois(n, lambda = 2) %>%
table() %>%
prop.table() %>%
unname() %>%
as.vector()
# Хипотетични вероятности под нулева хипотеза
hypothet_props <- dpois(0:6, lambda = 2.5)
# Калибрация с цел по-лесно тестване. chisq.test изисква вероятностите да се сумират до 1
hypothet_props <- hypothet_props + (1 - sum(hypothet_props)) / 7
# Визуализация на пропорциите
bind_rows(
data.frame(x = 0:6, y = hypothet_props, type = "Хипотетични"),
data.frame(x = 0:6, y = observed_props, type = "Наблюдавани")
) %>%
ggplot(mapping = aes(x = x, y = y, fill = type)) +
geom_bar(position = "dodge", stat = "identity") +
ggtitle("Наблюдавани и хипотетични вероятности") +
xlab("X") +
ylab("Плътност") +
theme_pomological_nobg(base_family = "Pacifico", base_size = 16) +
scale_fill_pomological() +
scale_color_pomological()
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Така, ако нулевата хипотеза е вярна,
\[ X^2 := \sum_{i=0}^6\frac{(n\hat{p_i}-np_i)^2}{np_i} \sim^d_{aprox} \chi^2_{6} \]
observed <- n * observed_props
expected <- n * hypothet_props
xsquared <- sum((observed - expected)^2 / expected)
pvalue <- pchisq(xsquared, lower.tail = FALSE, df = 6)
c("X^2" = xsquared, "df" = 6, "pvalue" = round(pvalue, 6))
## X^2 df pvalue
## 16.964442 6.000000 0.009415
Така виждаме, че е много малко вероятно да наблюдаваме съответната тестова статистика, ако истинското разпоределение беше \(Poi(2.5)\). В такъв случай, бихме могли да отхвърлим нулевата хипотеза при избрано от нас ниво на съгласие \(\alpha\).
В R за по-лесно това би станало така
chisq.test(observed, p = hypothet_props)
## Warning in chisq.test(observed, p = hypothet_props): Chi-squared approximation
## may be incorrect
##
## Chi-squared test for given probabilities
##
## data: observed
## X-squared = 16.964, df = 6, p-value = 0.009415
Ако имаме непрекъснати данни и искаме да тестваме хипотезата, че те идват от случайна величина с дадено непрекъснато разпределение, бихме могли да дискретизираме данните в под интервали и да проверим дали честотата с която се падат е същата като при същата дискретизация на плътността на тестваното от нас разпределение.
Нека имаме \(2000\) на брой наблюдения \(X_1, ..., X_{2000}\) от случайна величина \(X \sim \Gamma(12, 4)\) и нека тестваме нулева хипотеза с истинските параметри \(\alpha = 12, \beta = 4\). В този случай, не би трябвало да можем да отхвърлим нулевата хипотеза.
# Брой наблюдения
n <- 2000
# Параметри под нулевата хипотеза за разпределението
hyp_shape <- 12; hyp_rate <- 4;
# seed с цел възпроизвеждане на резултатите
set.seed(16)
# Симулирани данни от Гама разпределена случайна величина
x <- rgamma(n, 12, 4)
# Дискретизация
divisions <- seq(0.5, 6.5, by = 0.5)
# Хипотетични честоти ако нулевата хипотеза е вярна
hyp_props <- pgamma(divisions, hyp_shape, hyp_rate) - pgamma(divisions - 0.5, hyp_shape, hyp_rate)
# таблица с брой наблюдения в интервалите
observed_table <- x %>%
cut(c(0, divisions)) %>%
table()
# Наблюдавани честоти
observed <- as.vector(unname(observed_table))
# Визуализация на честотите (подобно е на хистограма)
bind_rows(
data.frame(x = names(observed_table), y = observed, type = "Наблюдавани"),
data.frame(x = names(observed_table), y = n * hyp_props, type = "Хипотетични"),
) %>%
ggplot(mapping = aes(x = x, y = y, fill = type)) +
geom_bar(position = "stack", stat = "identity") +
coord_flip() +
xlab("Интервали на Дискретизация") +
ylab("Честота на срещане в интервала") +
ggtitle("Честота на Дискретизирани данни") +
theme_pomological_nobg(base_family = "Pacifico", base_size = 16) +
scale_fill_pomological() +
scale_color_pomological()
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
# добавяме остатъка за да се сумират до 1
hyp_props <- hyp_props + (1 - sum(hyp_props)) / length(hyp_props)
# изпълнение на теста
chisq.test(observed, p = hyp_props)
## Warning in chisq.test(observed, p = hyp_props): Chi-squared approximation may be
## incorrect
##
## Chi-squared test for given probabilities
##
## data: observed
## X-squared = 7.6662, df = 12, p-value = 0.8106
Не успяваме да отхвърлим нулевата хипотеза, че данните са наблюдения от случайна величина \(X \sim \Gamma (12, 4)\).
Ако имаме две случайни извадки \(X_1, ..., X_n \sim^d X\) и \(Y_1, ..., Y_n \sim^d Y\), бихме могли отново да изградим таблици с пропорции \(\hat{p}_{ij} :=\hat{P}(X = i, Y = j)\) от наблюдаваните стойности, и съответно маргиналните пропорции (емпирични вероятности)
\(\hat{p}_{i, \forall}:= \hat{P}(X=i)=\sum_{j = 1}^c\hat{p}_{ij}\) и \(\hat{p}_{\forall, j}:= \hat{P}(Y=j)=\sum_{i = 1}^r\hat{p}_{ij}\), където \(r\) и \(c\) са бройките елементи за \(X\) и \(Y\).
В такъв случай, ако случайните величини \(X\) и \(Y\) са независими, то \(P(X = x_i, Y = y_j) = P(X = x_i)\cdot P(Y=y_j) := p_{i, \forall}p_{\forall,j}\) за всяко \(i, j\) и би трябвало да наблюдаваме емпирични вероятности които приблизително притежават това свойство.
Тогава
\[ X^2 := \sum_{i=1}^r\sum_{j=1}^c \frac{(O_{i,j}-E_{i,j})^2}{E_{i,j}} \underset{appr}{\overset{distr}{\sim}} \chi^2_{(r-1)(c-1)} \]
Нека симулираме две извадки с големина \(n=600\) от независими случайни величини \(X \sim Bin(8, 0.5), Y \sim Poi(2.3)\) и изпълним \(\chi^2\)-тест за независимост, като евентуално след това, бихме могли да добавим зависимост между част от наблюденията с цел да видим как се променят резултатите от \(\chi^2\) теста.
# генериране на две независими случайни величини
x <- rbinom(600, size = 8, prob = 1 / 2)
y <- rpois(600, 2.3)
# Вкарване на зависимост
y[400:600] <- y[400:600] + x[400:600]
# таблица брояща наблюдавани комбинации от вида (X, Y)
observed <- table(x, y)
# брой на всички елементи, N = n * m
N <- sum(observed)
# Маргинални емпирични вероятности
x_marginal <- prop.table(table(x))
y_marginal <- prop.table(table(y))
# Очаквани бройки при предположение за независимост
expected <- N * (x_marginal %*% t(y_marginal))
# X^2 статистика
xsquare <- sum((observed - expected)^2 / expected)
# Степени на свобода df = (r - 1) * (s - 1)
degrees_of_freedom <- prod(dim(observed) - 1)
# pvalue за съответната наблюдавана Х^2 статистика
pvalue <- pchisq(xsquare, df = degrees_of_freedom, lower.tail = FALSE)
# връщане на резултат
c("X^2" = xsquare, "df" = degrees_of_freedom, "pvalue" = pvalue)
## X^2 df pvalue
## 1.461809e+02 1.040000e+02 4.054662e-03
Или за кратко с функцията chisq.test
chisq.test(observed)
## Warning in chisq.test(observed): Chi-squared approximation may be incorrect
##
## Pearson's Chi-squared test
##
## data: observed
## X-squared = 146.18, df = 104, p-value = 0.004055
Функцията chisq.test автоматично разбира, че става въпрос за тест за независимост, когато ѝ се подаде таблица.
Често се налага да обясним една непрекъсната променлива чрез друга, примерно
Нека разгледаме данни от последния пример
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Виждаме, че има добра линейна връзка между печалбите и приходите вложени в ТВ реклами. Данните като цяло се движат около права линия около която има лек случаен шум. Ако моделираме печалбата като случайна величини \(Y\) и \(X\), бихме могли да кажем, че
\[ Y = \beta_0 + \beta_1X + \epsilon, \] където \(\epsilon\) е нашия случаен елемент, който за леснота можем да считаме като независими наблюдения oт нормално разпределена случайна величина, тоест
\[ \epsilon_1, ..., \epsilon_n \sim^d \epsilon \sim \mathcal{N}(0, \sigma^2) \]
За леснота, можем да считаме, че \(Х\) са наблюдавани константи и техните вероятностни свойства не ни интересуват.
По този начин,
\[ E[Y] = E(\beta_0 + \beta_1x + \epsilon) = \beta_0 + \beta_1x\\ Var[Y] = Var(\beta_0 + \beta_1x + \epsilon) = \sigma^2\\ Y \sim \mathcal{N}(\beta_0+\beta_1x, \sigma^2) \]
и математическото очакването за \(Y\) ще е права линия около която наблюденията варират.
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Един начин по който бихме могли да оценим математическото очакване на \(Y\) е метода на най-малките квадрати.
Понеже знаем, че върху математическото очакване може да се гледа като на център на тежестта, естествен начин за неговата оценка е да изберем минималното разстояние между вектора на наблюденията \(\overrightarrow{y} = (y_1, ..., y_n)'\) и вектора-линия \(\beta_0 + \beta_1\overrightarrow{x}=(\beta_0 + \beta_1x_1, ..., \beta_0 + \beta_1x_n)'\), тоест за \(\beta_0\) и \(\beta_1\) да изберем такива коефициенти, че
\[ (\hat{\beta_0}, \hat{\beta_1}) := \underset{\beta_0, \beta_1}{argmin}\text{ }\rho(\overrightarrow{y}, \beta_0 + \beta_1 \overrightarrow{x})^2=\\ =\underset{\beta_0, \beta_1}{argmin}\text{ }\left\lVert \overrightarrow{y}-\beta_0 - \beta_1 \overrightarrow{x} \right\rVert^2_2=\\ =\underset{\beta_0, \beta_1}{argmin}\text{ }\sum_{i=1}^n(y_i-\beta_0-\beta_1 x_i)^2 \]
Тоест, избираме коефициенти \(\beta_0\) и \(\beta_1\), такива че нашата линия \(f(x) := \beta_0 + \beta_1x\) максимално да приближава наблюденията \((y_1, ..., y_n)\) които имаме. Функцията която минимизираме по-горе, наричаме сума на квадратите на грешките и най-често обозначаваме с RSS,
която като функция на \(\beta_0\) и \(\beta_1\) би изглеждала така
Един начин по който можем да намерим минимума на горната функция е като намерим първите частни производни и ги положим на 0, т.е.
\[ \frac{\partial{(RSS)}}{\beta_0}=0\\ \frac{\partial{(RSS)}}{\beta_1}=0 \]
и да намерим инфлексната точка на функцията. Решавайки за \(\beta_0\) и \(\beta_1\) получаваме
\[ \hat{\beta_0} = \bar{y}-\beta_1\bar{x}\\ \]
и съответно
\[ \hat{\beta_1} = \frac{\sum_{i=1}^n(x_i-\bar{x})(y_i-\bar{y})}{\sum_{i=1}^n(x_i-\bar{x})^2}\\ \] В R това би станало така
x <- advertisement$tv
y <- advertisement$sales
# Оценка за коефициента β1
beta1_estimate <- sum((x - mean(x)) * (y - mean(y))) / sum((x - mean(x))^2)
# Оценка за коефициента β0
beta0_estimate <- mean(y) - beta1_estimate * mean(x)
# връщане на резултат
c("β0 Оценка" = beta0_estimate, "β1 Оценка" = beta1_estimate)
## β0 Оценка β1 Оценка
## 111.6637544 0.8243548
Или просто с функцията lm
lm(sales ~ tv, data = advertisement)
##
## Call:
## lm(formula = sales ~ tv, data = advertisement)
##
## Coefficients:
## (Intercept) tv
## 111.6638 0.8244
Забелязваме, че оценката на \(\beta_1\) може да се представи и така
\[ \hat{\beta_1} = \langle\frac{(\overrightarrow{x}-\bar{x})}{||\overrightarrow{x}-\bar{x}||_2},\frac{(\overrightarrow{y}-\bar{y})}{||\overrightarrow{x}-\bar{x}||_2} \rangle \]
Тоест, оценката за \(\beta_1\) ни дава колко наблюдаваните вектори \(\overrightarrow{x}\) и \(\overrightarrow{y}\) (центрирани и нормирани спрямо \(\overrightarrow{x}\)) са в една посока, или колко \(\overrightarrow{y}\) се променя спрямо \(\overrightarrow{x}\) (скаларно произведение).
По този начин, получената оценка за \(EY\) e
\[ \hat{Y} :=: \hat{f}(x) := \hat{\beta_0}+\hat{\beta_1}x \]
Нека разгледаме свойствата на оценките \(\hat{\beta_0}\) и \(\hat{\beta_1}\).
\[ Е[\hat{\beta}_1] = E[\frac{\sum_{i=1}^n(x_i-\bar{x})(Y_i-\bar{Y})}{\sum_{i=1}^n(x_i-\bar{x})^2}] =\\ =\frac{\sum_{i=1}^n(x_i-\bar{x})E[Y_i]}{\sum_{i=1}^n(x_i-\bar{x})^2}=\\ =\frac{\sum_{i=1}^n(x_i-\bar{x})(\beta_0 + \beta_1x_i)}{\sum_{i=1}^n(x_i-\bar{x})^2}=\\ =\frac{\sum_{i=1}^n(x_i-\bar{x})\beta_0}{\sum_{i=1}^n(x_i-\bar{x})^2}+\frac{\beta_1\sum_{i=1}^n(x_i-\bar{x})(x_i-\bar{x}+\bar{x})}{\sum_{i=1}^n(x_i-\bar{x})^2}=\\ 0+\frac{\beta_1\sum_{i=1}^n(x_i-\bar{x})^2}{\sum_{i=1}^n(x_i-\bar{x})^2}+0=\\ =\beta_1 \]
и така, оценката \(\hat{\beta_1}\) за \(\beta_1\) е неизместена оценка.
\[ Е[\hat{\beta_0}]=E[\bar{y}-\hat{\beta_1}\bar{x}]=E[\beta_0+\beta_1\bar{x}+\bar{\epsilon}-\hat{\beta_1}\bar{x}]=\beta_0 \]
и следователно \(\hat{\beta}_0\) също е неизместена оценка за \(\beta_0\).
\[ Var[\hat{\beta}_1] = Var[\frac{\sum_{i=1}^n(x_i-\bar{x})(Y_i-\bar{Y})}{\sum_{i=1}^n(x_i-\bar{x})^2}]=\\ =\frac{\sum_{i=1}^n(x_i-\bar{x})^2\sigma^2}{[\sum_{i=1}^n(x_i-\bar{x})^2]^2}=\frac{\sigma^2}{\sum_{i=1}^n(x_i-\bar{x})^2} \]
За дисперсията на \(\hat{\beta}_0\) получаваме
\[ Var[\hat{\beta}_0]=Var[\bar{y}-\hat{\beta_1}\bar{x}]=\\ =\frac{\sigma^2}{n}+\bar{x}^2Var[\hat{\beta_1}]+Cov[\bar{y}, \hat{\beta_1}]=\\ =\frac{\sigma^2}{n}+\frac{\bar{x}^2\sigma^2}{\sum_{i=1}^n(x_i-\bar{x})^2} \]
понеже \(Cov[\bar{y}, \hat{\beta_1}] = 0\) (Проверете сами!).
За ковариацията между \(\hat{\beta}_0\) и \(\hat{\beta}_1\) получаваме
\[ Cov(\hat{\beta}_0, \hat{\beta}_1) = E[(\bar{y}-\hat{\beta}_1\bar{x})\hat{\beta}_1] - \beta_0\beta_1= E[\bar{y}]E[\hat{\beta}_1]-\bar{x}E[\hat{\beta}_1^2]=\\ =(\beta_0+\beta_1\bar{x})\beta_1-\bar{x}Var[\hat{\beta}_1]-\bar{x}\beta_1^2-\beta_0\beta_1=\\ =-\bar{x}Var[\hat{\beta}_1]=-\frac{\bar{x}\sigma^2}{\sum_{i=1}^n(x_i-\bar{x})^2} \]
Нека разгледаме минимизираната стойност на \(RSS\) като случайна величина
\[ \hat{RSS} := \rho(\overrightarrow{Y},\overrightarrow{\hat{Y}})^2 = ||\overrightarrow{Y}- \overrightarrow{\hat{Y}}||_2^2 = \sum_{i=1}^n{(Y_i-\hat{Y}_i)^2} = \sum_{i=1}^n{(Y_i-\hat{\beta}_0 -\hat{\beta}_1x_i)^2} \]
Тогава
\[ \frac{\hat{RSS}}{\sigma^2} \sim \chi^2_{n-2} \] и ако вземем математическото очакване на \(\hat{RSS}\)
\[ E[\frac{\hat{RSS}}{\sigma^2}] = n-2 \implies E[\frac{\hat{RSS}}{n-2}] = \sigma^2 \]
Така получаваме неизместена оценка \(\hat{\sigma}^2 := \frac{\hat{RSS}}{n-2}\)
Получената оценка можем да използваме в гореполучените дисперсии на \(\hat{\beta_0}\) и \(\hat{\beta_1}\) за да изградим оценки за техните дисперсии.
# брой елементи които наблюдаваме
n <- nrow(advertisement)
# Оценка за очакването на Y(x)
y_fitted <- beta0_estimate + beta1_estimate * x
# Оценка за дисперсията
var_estimate <- sum((y_fitted - y)^2) / (n - 2)
# Оценка за стандартното отклонение
sd_estimate <- sqrt(var_estimate)
# Оценка за дисперсията на оценката на β0
beta0_var_est <- var_estimate / n + (mean(x)^2 * var_estimate) / sum((x - mean(x))^2)
# Оценка за дисперсията на оценката на β1
beta1_var_est <- var_estimate / (sum((x - mean(x))^2))
# Оценка за стандартното отклонение на оценката на β0
beta0_sd_est <- sqrt(beta0_var_est)
# Оценка за стандартното отклонение на оценката на β1
beta1_sd_est <- sqrt(beta1_var_est)
# резултат
data.frame(
estimation = c(
"Оценка за стандартното отклонение",
"Оценка за стандартното отклонение на оценката за β0",
"Оценка за стандартното отклонение на оценката за β1"
),
value = c(sd_estimate, beta0_sd_est, beta1_sd_est)
)
## estimation value
## 1 Оценка за стандартното отклонение 37.80484374
## 2 Оценка за стандартното отклонение на оценката за β0 7.63869509
## 3 Оценка за стандартното отклонение на оценката за β1 0.04595558
Или написано по-кратко чрез lm и summary
lm(sales ~ tv, advertisement) %>%
summary() %>%
{data.frame(
estimation = c(
"Оценка за стандартното отклонение",
"Оценка за стандартното отклонение на оценката за β0",
"Оценка за стандартното отклонение на оценката за β1"
),
value = c(.$sigma, .$coefficients[1, 2], .$coefficients[2, 2])
)}
## estimation value
## 1 Оценка за стандартното отклонение 37.80484374
## 2 Оценка за стандартното отклонение на оценката за β0 7.63869509
## 3 Оценка за стандартното отклонение на оценката за β1 0.04595558
Тъй като \(\hat{\beta}_0 \sim \mathcal{N}(\beta_0, \frac{\sigma^2}{n}+\frac{\bar{x}^2\sigma^2}{\sum_{i=1}^n(x_i-\bar{x})^2})\) и следователно
\[ Z_0 := \frac{\hat{\beta}_0 - \beta_0}{\sqrt{Var(\hat{\beta}_0)}}:= \frac{\hat{\beta}_0 - \beta_0}{\sqrt{\frac{\sigma^2}{n}+\frac{\bar{x}^2\sigma^2}{\sum_{i=1}^n(x_i-\bar{x})^2}}} \sim \mathcal{N}(0, 1) \]
и
\[ T_0 := \frac{\hat{\beta_0}-\beta_0}{\sqrt{\hat{Var}(\hat{\beta}_0)}} = \frac{\hat{\beta}_0 - \beta_0}{\sqrt{\frac{\hat{\sigma}^2}{n}+\frac{\bar{x}^2\hat{\sigma}^2}{\sum_{i=1}^n(x_i-\bar{x})^2}}} \sim \mathcal{T}(n - 2) \]
то можем да изградим \(\gamma\)-доверителни интервали, както и да тестваме различни хипотези на базата на горните статистики.
Аналогични разсъждения са валидни и за \(\beta_1\), тъй като
\[ Z_1 := \frac{\hat{\beta}_1-\beta_1}{\sqrt{Var(\hat{\beta_1})}}= \frac{(\hat{\beta}_1-\beta_1)\sqrt{\sum_{i=1}^n(x_i-\bar{x})^2}}{\sigma} \sim \mathcal{N}(0, 1) \] и
\[ T_1 := \frac{\hat{\beta}_1-\beta_1}{\sqrt{\hat{Var}(\hat{\beta}_1)}} = \frac{(\hat{\beta}_1-\beta_1)\sqrt{\sum_{i=1}^n(x_i-\bar{x})^2}}{\hat{\sigma}} \sim \mathcal{T}(n - 2) \]
# Квантил от Т-разпределение с n-2 степени на свобода
q <- pt(0.975, df = n - 2)
# 95% доверителен интервал за параметъра β0
c(beta0_estimate - q * beta0_sd_est, beta0_estimate + q * beta0_sd_est)
## [1] 105.2929 118.0346
c(beta1_estimate - q * beta1_sd_est, beta1_estimate + q * beta1_sd_est)
## [1] 0.7860270 0.8626827
# Хипотетичен параметър под който т статистиката има Т-разпределение
hypothetical_beta0 <- 0
# наблюдавана т-статистика
t0 <- (beta0_estimate - hypothetical_beta0) / beta0_sd_est
# pvalue за т-статистиката
pval0 <- 2 * min(pt(t0, df = n - 2, lower.tail = TRUE), pt(t0, df = n - 2, lower.tail = FALSE))
# резултат
c("t" = t0, "pvalue" = pval0)
## t pvalue
## 1.461817e+01 2.305746e-26
# Параметър под нулева хипотеза
hypothetical_beta1 <- 0
# тест статистика
t1 <- (beta1_estimate - hypothetical_beta1) / beta1_sd_est
# pvalue за тест статистиката
pval1 <- 2 * min(pt(t1, df = n - 2, lower.tail = TRUE), pt(t1, df = n - 2, lower.tail = FALSE))
# резултат
c("t" = t1, "pvalue" = pval1)
## t pvalue
## 1.793808e+01 1.009070e-32
Отново, резултатът го има чрез функцията summary
lm(sales ~ tv, advertisement) %>%
summary() %>%
.$coefficients
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 111.6637544 7.63869509 14.61817 2.305746e-26
## tv 0.8243548 0.04595558 17.93808 1.009070e-32
Всъщност, въпросът дали \(\beta_1=0\) може да се преведе в това дали \(X\) има ефект върху \(Y\) и дали участва в обясняването на \(Y\).
Основен въпрос, след като имаме изграден модел, е това да направим прогноза върху ненаблюдавана досега точка \(x_0\). В нашия случай, колко очакваме да спечелим, ако инвестираме 144лв в реклама?
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
## `geom_smooth()` using formula 'y ~ x'
Използвайки досега напаснатия модел, оценката за очакването на y върху определена точка \(x_0\) е
\[ \hat{y}_{x_0} := \hat{E}[Y|X = x_0] := \hat{\beta}_0 + \hat{\beta}_1 x_0 \]
Като точкова оценка, то притежава свойството неизместеност, защото
\[ Е[\hat{y}_{x_0} - y_{x_0}] = E[\hat{\beta}_0 + \hat{\beta}_1 x_0 - \beta_0 - \beta_1x_0] =\\ = E[\hat{\beta}_0] + E[\hat{\beta}_1 x_0] - \beta_0 - \beta_1x_0 =\\ = \beta_0 + \beta_1x_0 - \beta_0 - \beta_1x_0 = 0 \]
Дисперсията на тази оценка е сумата от дисперсиите на оценките на коефициентите
\[ Var[\hat{y}_{x_0}] = Var[\hat{\beta}_0 + \hat{\beta}_1 x_0] = \\ = Var[\hat{\beta}_0] + Var[\hat{\beta}_1 x_0] + 2Cov[\hat{\beta}_0, \hat{\beta}_1 x_0] =\\ =\frac{\sigma^2}{n}+\frac{\bar{x}^2\sigma^2}{S_{xx}} + \frac{x_0^2\sigma^2}{S_{xx}} - 2\frac{x_0\bar{x}\sigma^2}{S_{xx}} = \\ = \sigma^2(\frac{1}{n} + \frac{(\bar{x}-x_0)^2}{S_{xx}}) \]
където, за леснота сме положили \(S_{xx} := \sum_{i=1}^n{(x_i-\bar{x})^2}\).
Ако правим оценка за дисперсията на \(\hat{y}_{x_0}\), необходимо е в горната формула просто да заместим дисперсията \(\sigma^2\) с оценката за дисперсията \(\hat{\sigma}^2\).
\[ \hat{Var}[\hat{y}_{x_0}] = \hat{\sigma}^2(\frac{1}{n} + \frac{(\bar{x}-x_0)^2}{S_{xx}}) \]
Oсвен точкова оценка за очакваната стойност в \(x_0\), можем да изградим и интервална такава посредстом следната \(T_{x_0}\)-статистика
\[ Т_{x_0} := \frac{\hat{y}_{x_0} - E[y|x_0]}{\sqrt{\hat{Var}[\hat{y}_{x_0}]}} \sim \mathcal{T}(n - 2) \]
# Точка която да прогнозираме
x0 <- 300
# Оценка за очакването в тази точка
fit_at_x0 <- beta0_estimate + beta1_estimate * x0
Sxx <- sum((x - mean(x))^2)
# Дисперсия и стандартно отклонение на у0
y0_sigma_sq_estimate <- var_estimate * ((1 / n) + ((x0 - mean(x))^2 / Sxx))
y0_sigma_estimate <- sqrt(y0_sigma_sq_estimate)
# смятане на квантил от Т-разпределение с цел да сметнем доверителен интервал
q <- qt(0.975, df = n - 2)
# оценка и 95% доверителен интервал
c(
"оценка" = fit_at_x0,
"долен край" = fit_at_x0 - q * y0_sigma_estimate,
"горен край" = fit_at_x0 + q * y0_sigma_estimate
)
## оценка долен край горен край
## 358.9702 342.9216 375.0188
Което може да стане накратко така
predict.lm(
lm(sales ~ tv, advertisement),
data.frame(tv = c(300)),
interval = "confidence",
level = 0.95
)
## fit lwr upr
## 1 358.9702 342.9216 375.0188
След като сме отхвърлили хипотезата, че \(\beta_1 = 0\), тоест това че \(x\) няма ефект върху \(y\), бихме могли да попитаме каква е разликата между напаснатия модел \(\hat{Y}\) и вектора \(Y\), тоест
\[ RSE := \sqrt{\frac{\hat{RSS}}{n-2}} \]
sd_estimate
## [1] 37.80484
summary(lm(sales ~ tv, data = advertisement))
##
## Call:
## lm(formula = sales ~ tv, data = advertisement)
##
## Residuals:
## Min 1Q Median 3Q Max
## -89.730 -22.101 0.514 26.104 83.086
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 111.66375 7.63870 14.62 <2e-16 ***
## tv 0.82435 0.04596 17.94 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 37.8 on 98 degrees of freedom
## Multiple R-squared: 0.7665, Adjusted R-squared: 0.7642
## F-statistic: 321.8 on 1 and 98 DF, p-value: < 2.2e-16
Това дали наблюдаваното \(RSE\) е допустима грешка зависи от мащаба на y. Ако разделим \(RSE\) на \(\bar{y}\)
sd_estimate / mean(y)
## [1] 0.1638493
Тоест, правим около 16% грешка. RSE e оценка за липса на напасване на модела спрямо данните.
\[ R^2 := \frac{TSS - RSS}{TSS} = 1 - \frac{RSS}{TSS} := 1 - \frac{\rho(Y, \hat{Y})^2}{\rho(Y, \bar{Y})^2}=\\= 1 - \frac{||Y - \hat{Y}||^2_2}{||Y - \bar{Y}||^2_2} = 1-\frac{\sum_{i=1}^n(y_i-\hat{\beta}_0-\hat{\beta}_1 x_i)^2}{\sum_{i=1}^n(y_i-\bar{y})^2} \]
1 - sum((y - y_fitted)^2) / sum((y - mean(y))^2)
## [1] 0.7665414
Виждаме, че колкото по-добре е напаснат модела спрямо \(Y\), толкова повече \(R^2\) ще приближава 1, защото и толкова по малко ще е разстоянието между векторите \(Y\) и \(\hat{Y}\).
Простата линейна регресия е полезен подход при интерпретиране на връзка между променливи и прогнозиране на ненаблюдавани точки, но повечето случаи обаче, ни се налага да обясним Y като комбинация на повече от една независима променлива.
Примерно, да разширим горния случай с обясняване на печалбите не само с реклами в телевизия, но и с реклами в радио, вестници, тн. В този случай нашия модел за Y e
\[ y_i = \beta_0 + \beta_1 x_{i1} + ... + \beta_p x_{ip} + \epsilon_i \]
където i варира от 1 до n (брой наблюдения), \(\epsilon_i\) са независими наблюдения от нормално разпределена случайна грешка \(\epsilon \sim \mathcal N(0, \sigma^2)\), a \(\beta_j\) e връзката между \(Y\) и независимата променлива \(Х_j\). Интерпретираме \(\beta_j\) като средния ефект върху \(Y\) при една единица промяна в \(X_j\), държейки другите променливи фиксирани.
Целта на задачата се измества от това да оценим \(\beta_0, \beta_1\) и \(\sigma^2\), към това да оценим \(\beta_0, ..., \beta_p\) и \(\sigma^2\).
Отново, функцията на минимизиране е
\[ RSS = \sum_{i=1}^n(y_i-\hat{y_i})^2 = \sum_{i=1}^n(y_i-\beta_0 - \beta_1x_{i1} - ... - \beta_px_{ip})^2 \]
При \(p = 2\) целта е да напаснем вместо линия, цяла равнина, която да е максимално близо до наблюдаваните точки \(Y\).
Когато броя на независимите променливи \(p > 2\) имаме хипер-равнина която да напаснем и визуализацията би била по-трудна.
При прилагане на Линейна регресия едни от въпросите които ни интересуват са следните
В простата линейна регресия, за да проверим дали \(X\) има ефект върху \(Y\), беше необходимо просто да проверим хипотезата дали \(\beta_1 = 0\). Когато имаме повече променливи, въпросът се променя в това да проверим хипотезата дали \(H_0 := \beta_1 = \beta_2 = ... = \beta_p = 0\) срещу алтернативата \(H_1 := \exists j : \beta_j \neq 0\).
Нека първо дефинираме няколко помощни метрики
Където \[ TSS := \rho(Y, \bar{Y})^2 = ||Y - \bar{Y}||_2^2 = \sum_{i=1}^n(y_i-\bar{y})^2\\ RSS := \rho(Y, \hat{Y})^2 = ||Y - \hat{Y}||_2^2 = \sum_{i=1}^n(y_i-\hat{y})^2\\ SSR := \rho(\hat{Y}, \bar{Y})^2 = ||\hat{Y} - \bar{Y}||_2^2 = \sum_{i=1}^n(\hat{y_i}-\bar{y})^2 \]
Може да се наблюдава следното правило
\[ TSS = RSS + SSR \] Нека дефинираме следната F-статистика
\[ F = \frac{(TSS - RSS) / p}{RSS / (n - p - 1)} = \frac{(SSR) / p}{RSS / (n - p - 1)} = \frac{[\sum_{i=1}^n(y_i-\bar{y})^2 - \sum_{i=1}^n(y_i-\hat{y_i})^2] / p}{\sum_{i=1}^n(y_i-\hat{y_i})^2 / (n - p - 1)} \]
Така, ако нулевата хипотеза, че \(\beta_1 = \beta_2 = ... = \beta_p = 0\), би трябвало да имаме \(F\)-статистика близка до единица, защото вариацията обяснена от модела не би трябвало да се различава особено от тази която не е обяснена от модела (модела не носи стойност и \(\beta_1 = \beta_2 = ... = \beta_p = 0\)).
Също така, може да се покаже, че ако предположенията на линейната регресия са верни,
\[ Е[RSS / (n - p - 1)] = \sigma^2 \\ Е[SSR / p] = \sigma^2 \] което отново показва, че ако нулевата хипотеза е вярна, \(F\)-статистиката би била близка до 1.
Освен това, \((TSS - RSS)/\sigma^2 \sim \chi^2_{p}\) и \(RSS/\sigma^2 \sim \chi^2_{n-p-1}\), откъдето виждаме, че \(F\)-статистиката е деление на две нормирани Хи-квадрат разпраделени случайни величини. Полученото разпределение за \(F\) се нарича \(\mathcal{F}\)-разпределение с параметри \(df_1\) и \(df_2\) които са степените на свобода на хи-квадрат разпределените случайни величини в знаменател и числител.
По този начин, можем да измерим вероятността да наблюдаваме определена \(F\)-статистика (или по-крайна) с функцията pf(q, df1, df2). Ако съответната вероятност е прекалено малка (примерно по-малка от \(\alpha := 0.05\)), можем да отхвърлим нулевата хипотеза \(H_0 := \beta_1 = \beta_2 = ... = \beta_p = 0\) и да примем алтернативата, че съществува променлива \(X_j\) която подобрява модела.
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
## Warning: Removed 1134 rows containing non-finite values (stat_density).
# изграждане на модел с много променливи
multiple_model <- lm(sales ~ tv + radio + newspaper + facebook, data = advertisement2)
# напаснати данни
y_fitted <- fitted(multiple_model)
# истински данни
y <- advertisement2$sales
# брой елементи
n <- 100
# брой предиктори
p <- 4
# Total sum of squares (TSS)
tss <- sum((y - mean(y))^2)
# Residual sum of squares (RSS)
rss <- sum((y_fitted - y)^2)
# изчисление на F-статистика
f_statistic <- ((tss - rss) / p) / (rss / (n - p - 1))
# изчисление на pvalue за F-статистиката
pvalue <- pf(f_statistic, p, n - p - 1, lower.tail = FALSE)
# резултат
c("f_statistic" = f_statistic, "pvalue" = pvalue, "df1" = p, "df2" = n - p - 1)
## f_statistic pvalue df1 df2
## 3.023998e+02 4.076768e-53 4.000000e+00 9.500000e+01
Или просто със summary
multiple_model %>%
# обобщение на модела
summary() %>%
# взимане на f-статистиката от обобщението
.$fstatistic
## value numdf dendf
## 302.3998 4.0000 95.0000
Един начин за намиране на важни и обясняващи \(Y\) променливи \(Х_1, ..., Х_п\) e първо да пробваме с празен модел (само с единичен вектор умножен по \(\beta_0\))
\[ Y = \beta_0 + \epsilon \] и след това да напаснем p на брой линейни модела за всяка променлива \(X_p\)
\[ Y = \beta_0 + \beta_1 X_j + \epsilon \] И да изберем \(X_j\) такова, че \(R^2\) да увеличи максимално (или RSЕ да се намали максимално). Повтаряме процеса, като вече добавяме недобавяна досега променлива към модела \(Y = \beta_0 + \beta_1 X_j + \epsilon\), тоест \[ Y = \beta_0 + \beta_1 X_j + \beta_1 X_k +\epsilon \] Продължаваме докато се изпълни някакво зададено от нас терминално условие.
Ако тестваме линейна регресия без независима променлива \(X\), тоест \(Y = \beta_0 + \epsilon\), забелязваме че \[ \hat{\beta}_0 = \bar{y} \] а това да тестваме дали \(\beta_0 = 0\), се транслира до \[ T := \frac{\hat{\beta}_0 - 0}{\hat{sd}(\hat{\beta_0})} = \frac{\bar{y} - 0}{\hat{\sigma}/\sqrt{n}} \sim \mathcal{T}(n-1) \]
Така виждаме, че всъщност тестването на хипотезата дали \(\mu = 0\) в една нормално разпределена популация, е всъщност частен случай на линейна регресия без променливи (само с единичен вектор).
# общ брой елементи
n <- 100
# генериране на извадка със средно 0.4
y <- rnorm(n, mean = 0.4)
# изпълняване на т-тест с нулева хипотеза Но := µ = 0
t.test(y, mu = 0)
##
## One Sample t-test
##
## data: y
## t = 4.7652, df = 99, p-value = 6.476e-06
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 0.2786152 0.6761941
## sample estimates:
## mean of x
## 0.4774047
Или същото с линеен модел
# линеен модел без променливи х (оценява само средното на у)
lm(y ~ 1) %>%
# извикване на обобщение
summary() %>%
# взимане на т-статистиката и нейното pvalue за хипотезата, че ß0 = 0
{.$coefficients[, c(3, 4)]}
## t value Pr(>|t|)
## 4.765215e+00 6.475705e-06
Ако искаме да тестваме за произволно средно, трябва просто да извадим това средно от данните
# линеен модел без променливи х (оценява само средното на у с изместване единица)
lm(y - 1 ~ 1) %>%
# обобщение
summary() %>%
# взимане на т-статистиката и нейното pvalue за хипотезата, че ß0 = 0 (което е дали средното е 1 като вземем предвид изместването)
{.$coefficients[, c(3, 4)]}
## t value Pr(>|t|)
## -5.216286e+00 1.003722e-06
Или с t.test
t.test(y, mu = 1)
##
## One Sample t-test
##
## data: y
## t = -5.2163, df = 99, p-value = 1.004e-06
## alternative hypothesis: true mean is not equal to 1
## 95 percent confidence interval:
## 0.2786152 0.6761941
## sample estimates:
## mean of x
## 0.4774047
Но какво правим, когато имаме две нормални извадки, всяка с размер n и искаме да направим тест дали идват от популации с еднакви средни?
Ако разгледаме следния модел
\[ Y = \beta_0 + \beta_1X + \epsilon \]
където Y e конкатенация на двете извадки, а \(X = \unicode{x1D7D9}_{Y \in \text{извадка 2}}\), тоест \(x_i = 0\) за \(i = 1,..., n\) и \(x_i = 1\) за \(i = n + 1, ...., 2n\)
В горното уравнение на линия, отново \(\beta_1\) представлява наклона който имаме. В този смисъл \[ \beta_1 = E[\frac{\Delta y}{\Delta x}] = E[\frac{\Delta y}{1}] = E[\Delta y] \]
{ height: 100px; width: 100px; }
Така, ако теглиме от първата извадка, оценката за \(Y\) става \(\hat{Y} = \hat{\beta}_0 = \bar{Y}_{\text{извадка 1}}\), а ако теглим от втората извадка \(\hat{Y} = \hat{\beta}_0 + \hat{\beta}_11 = \hat{\beta}_0 + \hat{\beta}_1\) и така \(\hat{\beta}_1\) e оценка за разликата в средните. Ако тестваме дали \(\beta_1 = 0\), реално тестваме дали има разлика в средните на популациите от които произлизат двете извадки.
Оценката за \(\beta_1\) в случая ще бъде
\[ \hat{\beta_1} = \frac{\sum_{i=1}^{2n}(x_i-\bar{x})(y_i-\bar{y})}{\sum_{i=1}^{2n}(x_i-\bar{x})^2} = \\ = \frac{\sum_{i=1}^{n}(0 - 0.5)(y_i-\bar{y}) + \sum_{i=n+1}^{2n}(1 - 0.5)(y_i-\bar{y})}{\sum_{i=1}^{2n}(0.5)^2} = \\ = \frac{0.5(\sum_{i=n+1}^{2n}y_i - \sum_{i=1}^{n}y_i)}{2n(0.5)^2} = \\ \frac{\sum_{i=n+1}^{2n}y_i - \sum_{i=1}^{n}y_i}{n} = \bar{y}_{\text{извадка 1}} - \bar{y}_{\text{извадка 2}} \]
Виждаме че всъщност, оценката \(\hat{\beta}_1\) за \(\beta_1\) е разликата в средните между двете извадки.
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Така, ако тестваме дали \(\beta_1 = 0\), получаваме следната T-статистика
\[ Т := \frac{\bar{y}_{\text{извадка 1}} - \bar{y}_{\text{извадка 2}}}{\hat{sd}(\hat{\beta}_1)} \]
# генериране на извадка 1
y1 <- rnorm(50, mean = 10)
# генериране на извадка 2
y2 <- rnorm(50, mean = 15)
# конкатениране на цялостния вектор
y <- c(y1, y2)
# индикаторна х променлива
x <- rep(c(0, 1), each = 50)
# може да се дефинира и така
x <- 0 + (1:100 > 50)
# изпълнение на модела обясняващ y срямо индикаторна променлива
lm(y ~ x) %>%
# обобщение
summary() %>%
# Взимане на Т-статистиката и нейното pvalue за коефициента ß1
{.$coefficients[2, c(3, 4)]}
## t value Pr(>|t|)
## 2.316026e+01 1.567575e-41
Което е същото като да направим Т-тест за това дали двете извадки са с еднакво средно.
t.test(y2, y1)
##
## Welch Two Sample t-test
##
## data: y2 and y1
## t = 23.16, df = 97.837, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 4.398213 5.222580
## sample estimates:
## mean of x mean of y
## 14.82267 10.01228
В горния пример, бихме могли да тестваме по още един начин, дали променливата Х (тоест дали двете извадки се различават значително) има ефект върху модела. Ако изпълниме F-тест, той на практика би проверил точно това - дали \(\beta_1 = 0\), тоест дали втората извадка статистически значително променя цялостното средно (има статистически значима разлика между двете средни).
\[ H_0 := \{ \beta_1 = 0 \iff \bar{Y} = \beta_0 \iff \text{Извадка 2 e същата като Извадка 1 спрямо математическото очакване} \} \\ H_1 := \{ \beta_1 \neq 0 \iff \text{Извадка 2 се различава значително от Извадка 1 спрямо средното} \} \]
# изпълнение на модела обясняващ y срямо индикаторна променлива
lm(y ~ x) %>%
# обобщение от което да рагледаме F-статистиката и нейното pvalue
summary()
##
## Call:
## lm(formula = y ~ x)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.8880 -0.7973 -0.1254 0.6250 2.3124
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 10.0123 0.1469 68.17 <2e-16 ***
## x 4.8104 0.2077 23.16 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.039 on 98 degrees of freedom
## Multiple R-squared: 0.8455, Adjusted R-squared: 0.8439
## F-statistic: 536.4 on 1 and 98 DF, p-value: < 2.2e-16
Ако разширим модела си с повече от две извадки, изпълнявайки \(F\)-тест, всъщност ще питаме дали има извадка чиято популация драстично се различава от тази на другите спрямо средните.
\[ H_0 := \{ \beta_1 = \beta_2 = ... = \beta_p = 0 \iff Y = \beta_0 \iff \text{Всички извадки идват от една и съща популация} \} \\ H_1 := \{ \exists j : \beta_j \neq 0 \iff \text{Има извадка чието разпределение драстично се различава от останалите} \} \]
# общ брой елементи
n <- 250
# дисперсия (трябва да е обща спрямо модела)
sigma <- 6
# петте различни извадки
y1 <- rnorm(n, mean = 13, sd = sigma)
y2 <- rnorm(n, mean = 16, sd = sigma)
y3 <- rnorm(n, mean = 9, sd = sigma)
y4 <- rnorm(n, mean = 6, sd = sigma)
y5 <- rnorm(n, mean = 13, sd = sigma)
# конкатениране на y променливите в eдно y
y <- c(y1, y2, y3, y4, y5)
# индикаторни променливи които ни казват в коя извадка сме
x1 <- rep(c(0, 1, 0, 0, 0), each = n) # извадка 2
x2 <- rep(c(0, 0, 1, 0, 0), each = n) # извадка 3
x3 <- rep(c(0, 0, 0, 1, 0), each = n) # извадка 4
x4 <- rep(c(0, 0, 0, 0, 1), each = n) # извадка 5
x <- rep(1:5, each = n)
groups_data <- data.frame(
y = y,
x1, x2, x3, x4,
sample = as.factor(rep(paste0("Извадка ", 1:5), each = n))
)
## Warning: Font 'Pacifico' isn't in the extrafont font list (but it may still
## work). If recently installed, you can try running `extrafont::font_import()`.
Ако го разглеждаме от гледна точка на линейна регресия с много променливи (индикатори за съответните групи), оценките за \(\beta_1, .., \beta_p\) ще са разликите между средните на групи 2,3,…, р и първата група (визуално това са наклони в отделни линии). В долната графика, пресечната линия е средното на първата група (оценката за _0).
За да изпълним ANOVA тест който проверява дали някоя от групите значително се различава от останалите (нейния коефициент значително обяснява модела), пускаме линейна регресия обясняваща y спрямо съответните индикаторни променливи \(x_1, ..., x_4\).
lm(y ~ x1 + x2 + x3 + x4, data = groups_data) %>%
summary()
##
## Call:
## lm(formula = y ~ x1 + x2 + x3 + x4, data = groups_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -20.0861 -3.9651 0.2251 3.9667 18.0560
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 13.2239 0.3676 35.975 < 2e-16 ***
## x1 2.6733 0.5198 5.142 3.15e-07 ***
## x2 -4.0030 0.5198 -7.700 2.75e-14 ***
## x3 -7.3097 0.5198 -14.061 < 2e-16 ***
## x4 -0.5039 0.5198 -0.969 0.333
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5.812 on 1245 degrees of freedom
## Multiple R-squared: 0.2633, Adjusted R-squared: 0.261
## F-statistic: 111.3 on 4 and 1245 DF, p-value: < 2.2e-16
# Проверка за коефициентите и нашите разсъждения
c(
"beta0" = mean(y1),
"beta1" = mean(y2 - y1),
"beta2" = mean(y3 - y1),
"beta3" = mean(y4 - y1),
"beta4" = mean(y5 - y1)
)
## beta0 beta1 beta2 beta3 beta4
## 13.2238764 2.6732943 -4.0029761 -7.3096923 -0.5038667
Предположенията на ANOVA теста си остават същите като при линейна регресия и Т-тест - данни с нормално разпределение и еднаква дисперсия между групите.
Бихме могли да изпълним теста и така
# Функцията stack създава помощна факторна променлива и конкатенира y променливите в една
anova_df <- stack(data.frame(y1, y2, y3, y4, y5))
anova_df %>%
# Линеен модел
lm(values ~ ind, data = .) %>%
# подаваме линейния модел на anova функцията
anova()
## Analysis of Variance Table
##
## Response: values
## Df Sum Sq Mean Sq F value Pr(>F)
## ind 4 15034 3758.5 111.27 < 2.2e-16 ***
## Residuals 1245 42056 33.8
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Можем и с функцията oneway.test
oneway.test(values ~ ind, anova_df, var.equal = TRUE)
##
## One-way analysis of means
##
## data: values and ind
## F = 111.27, num df = 4, denom df = 1245, p-value < 2.2e-16
Така получения тест бихме могли да използваме за да проверим дали определен фактор (група) променя значително цялата съвкупност.
Често се налага обаче да проверим дали факторите (групите) имат ефект върху не една променлива, a две променливи. Пример за това би бил въпроса дали различни видове лекарства имат значителен ефект както върху хемоглобина, така и върху хематокрита.
Изпълнението на MANOVA теста става с функцията manova, като като аргумент подаваме матрица от двата отклика manova(cbind(y1, y2) ~ x, data = some_data)
two_response_groups_data %>%
# изпълняваме функцията manova със Y = cbind(y1, y2)
manova(cbind(y1, y2) ~ x, data = .) %>%
# обобщение на модела
summary()
## Df Pillai approx F num Df den Df Pr(>F)
## x 4 1.1047 384.06 8 2490 < 2.2e-16 ***
## Residuals 1245
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Виждаме, че F-статистиката е далеч над 1 и pvalue-то е изключително малко, откъдето отсъждаме, че определено различните групи имат ефект върху двата отклика.
За да проверим, колко точно групите афектират двата отклика \(y_1\) и \(y_2\), можем да използваме функцията summary.aov за да изпълним поединична ANOVA
two_response_groups_data %>%
# изпълняваме функцията manova със Y = cbind(y1, y2)
manova(cbind(y1, y2) ~ x, data = .) %>%
# обобщение на модела експлицитно за двата отклика
summary.aov()
## Response y1 :
## Df Sum Sq Mean Sq F value Pr(>F)
## x 4 15034 3758.5 111.27 < 2.2e-16 ***
## Residuals 1245 42056 33.8
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Response y2 :
## Df Sum Sq Mean Sq F value Pr(>F)
## x 4 22993.3 5748.3 5946.2 < 2.2e-16 ***
## Residuals 1245 1203.6 1.0
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
При ANOVA с корелирани извадки, отново тестваме за това дали извадките са еднакви или се различават по тяхното средно, но този път разглеждаме случая когато бихме могли да имаме зависимост между отделните групи.
Пример за това би бил тестване за времето на действие на различни лекарства върху няколко различни пациенти.
patients_df <- data.frame(
patient = as.factor(rep(1:5, each = 4)),
drug = as.factor(rep(1:4, times = 5)),
response_time = c(
41, 39, 27, 45,
25, 29, 21, 33,
35, 31, 29, 41,
49, 45, 31, 55,
37, 39, 25, 41
)
)
patients_df
## patient drug response_time
## 1 1 1 41
## 2 1 2 39
## 3 1 3 27
## 4 1 4 45
## 5 2 1 25
## 6 2 2 29
## 7 2 3 21
## 8 2 4 33
## 9 3 1 35
## 10 3 2 31
## 11 3 3 29
## 12 3 4 41
## 13 4 1 49
## 14 4 2 45
## 15 4 3 31
## 16 4 4 55
## 17 5 1 37
## 18 5 2 39
## 19 5 3 25
## 20 5 4 41
# Error(patients) задава променливата върху която гледаме двустранно
# преди и слсед лекарството
# У drug
aov(response_time ~ drug + Error(patient), data = patients_df) %>%
# Обобщение на модела
summary()
##
## Error: patient
## Df Sum Sq Mean Sq F value Pr(>F)
## Residuals 4 680.8 170.2
##
## Error: Within
## Df Sum Sq Mean Sq F value Pr(>F)
## drug 3 698.2 232.7 24.76 1.99e-05 ***
## Residuals 12 112.8 9.4
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1