W tej części kursu będziemy zajmować się korelacją oraz regresją. Na początek kilka uwag wstępnych. W statystyce zasadniczo odróżnia się te dwa pojęcia na poziomie konceptualnym. Rozróżnienie to nie jest konsekwentnie przez wszystkich stosowane, warto jednak je znać (dla spokoju ducha!).
Regresja - metoda pozwalająca na zbadanie związku pomiędzy zmiennymi i wykorzystanie tej wiedzy do przewidywania nieznanych wartości jednych wielkości na podstawie znajomości wartości innych. Poszukuje się zwązku między jedną (lub więcej) zmienną objaśniającą lub niezależną \(X\) a zmienną objaśnianą lub zależną \(Y\).
W regresji zmienna \(X\) (objaśniająca) jest w pełni kontrolowana przez eksperymentatora i pozbawiona elementu losowości.
W korelacji obie zmienne sa zmiennymi losowymi.
W praktyce, tak jak wspomnieliśmy, różnica ta jest trochę zatarta, ale warto o niej pamiętać.
Na początek przyjrzyjmy się sposobowi wizualizacji relacji między dwiema zmiennymi. Nie zdziwi Państwa informacja, że znany i (przynajmniej przez niektórych) lubiany wykres punktowy (zwany takze wykresem rozrzutu) świetnie nadaje się do ilustrowania tego typu danych. Przypomnijmy więc sobie, w jaki sposób w R możemy narysować wykres punktowy.
Domyślnie, jeżeli wywołamy funkcje plot
i przekażemy jej
jako argumenty dwa wektory typu numeric
, to R narysuje
wykres punktowy. W tym przypadku reprodukujemy wykresy znajdujące się w
rozdziale 9 podręcznika Howella. Każdy z punktów na wykresie
reprezentuje jeden kraj. Pierwszy wykres przedstawia relację między
liczbą lekarzy (zmienna objaśniająca) a śmiertelnością noworodków
(zmienna objaśniana), drugi między wydatkami na służbę zdrowia (zmienna
objaśniająca) a oczekiwaną długością życia (zmienna objaśniana), trzeci
zaś między promieniowaniem słonecznym (zmienna objaśniająca) a
zachorowaniem na nowotwory (zmienna objaśniana).
par(mfrow = c(1,3))
d1 <- read.table('Fig9-1a.dat', header = TRUE)
plot(d1$Physicians, d1$InfMort)
d2 <- read.table('Fig9-1b.dat', header = TRUE)
plot(d2$Expend, d2$LifeExp)
d3 <- read.table('Fig9-1c.dat', header = TRUE)
plot(d3$Radiation, d3$Cancer)
Datasaurus (czyli dinozaur ułożony z punków stworzony przez badaczy z firmy Autocad; więcej informacji na: https://www.autodeskresearch.com/publications/samestats) jest dowodem na to, że zawsze powinniśmy wizualizować nasze dane przed przeprowadzeniem analiz statystycznych. Poniżej znajduje się ilustracja 13 rozkładów, które mają takie same: - średnie X - średnie Y - odchylenie standardowe X - odchylenie standardowe Y - współczynnik korelacji między X a Y - współczynnik kowariancji między X a Y
A mimo to są diametralnie różnymi rozkładami! Gdybyśmy patrzyli wyłącznie na gołe statystyki liczbowe, to nigdy byśmy nie zobaczyli, że te zbiory danych są diametralnie różne.
Oto wykresy:
options(repr.plot.width=15, repr.plot.height=15)
library(ggplot2)
ggplot(data = datasauRus::datasaurus_dozen) +
geom_point(aes(x = x, y = y)) +
facet_wrap(~dataset, ncol=4)
A tutaj znajdą Państwo statystyki deskryptywne!
library(dplyr)
group_by(datasauRus::datasaurus_dozen, dataset) %>%
summarise(
"Korelacja" = cor(x, y),
"Kowariancja" = cov(x, y),
"Średnia X" = mean(x),
"Średnia Y" = mean(y),
"Odchylenie standardowe X" = sd(x),
"Odchylenie standardowe Y" = sd(y),
)
## # A tibble: 13 × 7
## dataset Korelacja Kowariancja `Średnia X` `Średnia Y` Odchylenie…¹ Odchy…²
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 away -0.0641 -29.0 54.3 47.8 16.8 26.9
## 2 bullseye -0.0686 -31.0 54.3 47.8 16.8 26.9
## 3 circle -0.0683 -30.8 54.3 47.8 16.8 26.9
## 4 dino -0.0645 -29.1 54.3 47.8 16.8 26.9
## 5 dots -0.0603 -27.2 54.3 47.8 16.8 26.9
## 6 h_lines -0.0617 -27.9 54.3 47.8 16.8 26.9
## 7 high_lines -0.0685 -30.9 54.3 47.8 16.8 26.9
## 8 slant_down -0.0690 -31.2 54.3 47.8 16.8 26.9
## 9 slant_up -0.0686 -31.0 54.3 47.8 16.8 26.9
## 10 star -0.0630 -28.4 54.3 47.8 16.8 26.9
## 11 v_lines -0.0694 -31.4 54.3 47.8 16.8 26.9
## 12 wide_lines -0.0666 -30.1 54.3 47.8 16.8 26.9
## 13 x_shape -0.0656 -29.6 54.3 47.8 16.8 26.9
## # … with abbreviated variable names ¹`Odchylenie standardowe X`,
## # ²`Odchylenie standardowe Y`
Regresje przeprowadzamy w R za pomocą funkcji lm
.
Funkcja ta zwraca obiekt, którego metoda print
wyświetla
wyraz wolny regresji, współczynnik kierunkowy oraz informacje o
wywołaniu funkcji. Jeżeli chcemy się dowiedzieć czegoś więcej, musimy
obiekt ten przekazać funkcji summary
.
lm
Wywołanie funkcji lm
na danych zwraca nam obiekt klasy
lm
. Możemy fo przypisać do zmiennej (często spotykaną w R
konwencją jest nazwa fit
dla modelu) albo po prostu
wyświetlić.
# Wywołanie funkcji `lm` zwraca nam odpowiednio dopasowany model.
lm(d1$Physicians ~ d1$InfMort)
##
## Call:
## lm(formula = d1$Physicians ~ d1$InfMort)
##
## Coefficients:
## (Intercept) d1$InfMort
## 15.0346 0.4868
summary
na obiekcie zwracanym przez
lm
Tak, jak powiedzieliśmy sobie wczesniej, funkcja summary
wywołana na obiekcie zwróconym przez funkcję lm
pozwala nam
się dowiedzieć więcej o stworzonym przez nas modelu. W szczególności zaś
pozwala nam poznać różne jego parametry oraz przeprowadza szereg testów
statystycznych (na istotność poszczególnych współczynników w regresji
oraz na dopasowanie całego modelu).
summary(lm(d1$Physicians ~ d1$InfMort))
##
## Call:
## lm(formula = d1$Physicians ~ d1$InfMort)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.3176 -0.6836 -0.2450 0.9065 2.1561
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 15.03459 0.29866 50.340 < 2e-16 ***
## d1$InfMort 0.48681 0.07072 6.884 3.68e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.264 on 16 degrees of freedom
## Multiple R-squared: 0.7476, Adjusted R-squared: 0.7318
## F-statistic: 47.39 on 1 and 16 DF, p-value: 3.675e-06
Moglibyśmy ręcznie ,,wydobyć’’ wartości niezbędne do dodania linii
regresji (są w końcu drukowane przez R!), ale możemy skorzystać z faktu,
że nasz model stworzony za pomocą funkcji lm
możemy
bezpośrednio przekazać jako argument do funkcji abline
.
Funkcja ta zaś automatycznie dorysuje do istniejącego wykresu linię
regresji. Należy jednak pamiętać o tym, żeby tworząc wykres punktowy
używać składni formuły (z ~
). Na chwile obecną należy
pamiętać, że formuły wyglądają mniej więcej tak: Y ~ X
.
# Ustawiamy parametry graficzne R tak, aby narysować trójpanelowy wykres
par(mfrow = c(1,3))
# Tworzymy pierwszy wykres za pomocą składni formuły (tzn. składni z tyldą: Y ~ X)
plot(d1$Physicians ~ d1$InfMort)
# Przypisujemy model do zmiennej `fit`
fit <- lm(d1$Physicians ~ d1$InfMort)
# Model można przekazać jako argument dla funkcji `abline` i ona będzie wiedziała, co i gdzie narysować
abline(fit)
# Pozostałę dwa przypadki analogicznie
plot(d2$LifeExp ~ d2$Expend)
abline(lm(d2$LifeExp ~ d2$Expend))
plot(d3$Radiation ~ d3$Cancer)
abline(lm(d3$Radiation ~ d3$Cancer))
Wzór na współczynnik kowariancji między dwiema zmiennymi wygląda następująco:
\[ Cov(X,Y) = E[(X-E(X)) (Y-E(Y))] \]
Problem z kowariancją jest taki, że jej wielkość zależy od tego, jakie jednostki mają nasze zmienne oraz w szczególności od tego, jakie mają odchylenie standardowe. Może to utrudnić porównania i interpretacje takiej wartości. Obliczenie współczynnika korelacji jest sposobem na poradzenie sobie z tym problem. Można o nim myśleć jako o “wystandaryzowanym” współczynniku kowiariancji. Wzór na korelację w populacji (\(\rho\)) wygląda tak:
\[ \rho = \frac{Cov(X,Y)}{\sqrt{Var(X)Var(Y)}} \]
\[ r = \frac{\sum_{i=1}^{n} (X_i - \bar{X})(Y_i - \bar{Y})}{\sqrt{\sum_{i=1}^{n}(X_i - \bar{X})^2 (Y_i - \bar{Y})^2 }}\]
albo prościej:
\[r = \frac{cov_{XY}}{s_x s_y}\]
Spróbujmy sprawdzić teraz, czy R oblicza oba współczynniki zgodnie ze wzorami! Zaczniemy od kowariancji:
print('Kowariancja')
## [1] "Kowariancja"
sum((d1$Physicians - mean(d1$Physicians)) * (d1$InfMort - mean(d1$InfMort)))/
(nrow(d1)-1) # wzór kowariancji wpisany ręcznie
## [1] 9.14598
cov(d1$Physicians, d1$InfMort) # funkcja wbudowana w R
## [1] 9.14598
A teraz sprawdzimy to samo dla korelacji:
print('Korelacja')
## [1] "Korelacja"
cor(d1$Physicians, d1$InfMort) # funkcja wbudowana w R
## [1] 0.8646336
(sum((d1$Physicians - mean(d1$Physicians))*(d1$InfMort - mean(d1$InfMort)))/
(nrow(d1)-1))/(sd(d1$Physicians)*sd(d1$InfMort))
## [1] 0.8646336
Interpretując współczynnik korelacji Pearsona musimy pamiętać, że właściwa interpretacja będzie zależeć od tego, w jakiej dziedzinie się aktualnie znajdujemy. Dla fizyka inny współczynnik korelacji będzie uznany za “duży” niż dla psychologa społecznego. Poniżej znajdują się jednak pewne “zasady kciuka” dotyczące interpretacji współczynnika \(r\) w naukach psychologicznych:
Czasami mamy do czynienia z więcej niż dwiema zmiennymi. W takim przypadkach zdarza się, że chcielibyśmy zbadać korelacje między wszystkimi kombinacjami dwóch zmiennych jednoczesnie. W tym celu możemy stworzyć macierz korelacyjną (tak samo tworzy się macierz kowariancji - przyda się Państwu na Statystyce II przy PCA). Tutaj zrobimy to (może nieco nudno) na losowych danych pochodzacych z rozkładu normalnego.
# Wylosujemy 350 obserwacji z rozkładu normalnego a następnie podzielimy je na 10 kolumn
# W ten sposób zasymulujemy sytuacje zbioru danych z 10 zmiennymi
m <- matrix(rnorm(350), 35, 10)
# Przekształcamy macierz w ramkę danych
m <- as.data.frame(m)
# Tworzymy macierz korelacyjną, dla kowariancji będzie to `cov`
cor(m)
## V1 V2 V3 V4 V5 V6
## V1 1.00000000 0.04062120 -0.036984500 -0.25295770 -0.097177764 0.18067413
## V2 0.04062120 1.00000000 -0.015804097 -0.06317957 0.039304352 -0.03114212
## V3 -0.03698450 -0.01580410 1.000000000 -0.15793518 -0.003286826 -0.31354048
## V4 -0.25295770 -0.06317957 -0.157935179 1.00000000 -0.233346118 0.17580306
## V5 -0.09717776 0.03930435 -0.003286826 -0.23334612 1.000000000 0.26220227
## V6 0.18067413 -0.03114212 -0.313540476 0.17580306 0.262202268 1.00000000
## V7 0.01597727 0.07800419 0.075989799 -0.17368893 0.101311487 -0.14165139
## V8 0.22477827 0.07774400 -0.015036001 -0.26234123 -0.379162806 0.07409068
## V9 0.07069459 0.02600111 0.155060365 -0.14104357 0.131381708 -0.08694760
## V10 -0.06416852 -0.00382242 -0.022665832 0.06000429 -0.140496349 -0.10811156
## V7 V8 V9 V10
## V1 0.01597727 0.224778272 0.07069459 -0.064168516
## V2 0.07800419 0.077743996 0.02600111 -0.003822420
## V3 0.07598980 -0.015036001 0.15506036 -0.022665832
## V4 -0.17368893 -0.262341231 -0.14104357 0.060004295
## V5 0.10131149 -0.379162806 0.13138171 -0.140496349
## V6 -0.14165139 0.074090675 -0.08694760 -0.108111556
## V7 1.00000000 -0.165550739 -0.07654318 -0.350118834
## V8 -0.16555074 1.000000000 -0.07801072 0.002704097
## V9 -0.07654318 -0.078010717 1.00000000 0.412052784
## V10 -0.35011883 0.002704097 0.41205278 1.000000000
Jednym ze sposobów wizualizacji takich danych jest “mapa cieplna”, w której intensywność koloru (albo jakiś jego inny parametr) oznacza siłę korelacji (tutaj - im jaśniejszy tym wyższy współczynnik korelacji, im ciemniejszy tym niższy).
library('viridis')
## Ładowanie wymaganego pakietu: viridisLite
heatmap(cor(m), symm = TRUE, Rowv = NA, col=viridis(256))
Wersja podstawowa produkowana przez funkcję heatmap
wygląda w tym przypadku tak.
heatmap(cor(m)) # wersja z klastrami, ale one nam są niepotrzebne
Pewną ciekawą odmianą mapy cieplnej jest wykres z elipsami, na którym widać siłę (jak bardzo spłaszczona jest elipsa) oraz kierunek (w którą stronę ,,kopnięta’’ jest elipsa) korelacji między zmiennymi.
library(ellipse)
##
## Dołączanie pakietu: 'ellipse'
## Następujący obiekt został zakryty z 'package:graphics':
##
## pairs
# `type` mówi o tym, czy chcemy umieszczać na wykresie całą macierz czy tylko jej część
# `diag` mówi, czy rysować przekątną (na przekątnej r = 1, więc nie jest za bardzo ciekawa...)
plotcorr(cor(m), type = 'lower',
diag = TRUE)
W przypadku wylosowanych obserwacji może być trudno zrozumieć, jak
działać mają rysowane prez plotcorr
elipsy. Być może lepiej
widać to na znanym Państwu już zbiorze dotyczącym irysów
(iris
).
plotcorr(cor(iris[,1:4]), type = 'lower', diag = TRUE)
Ostatnim sposobem generowania ładnie wyglądających wizualizacji
korelacji między wieloma zmiennymi, który omówimy, są funkcje
corrplot
i corrplot.mixed
z pakietu (!)
corrplot
. Funkcje ta ma bardzo wiele możliwości
dostosowania wyglądu wykresu - zachęcam do samodzielnej eksploracji!
library(corrplot)
## corrplot 0.92 loaded
corrplot.mixed(cor(iris[,1:4]),
lower = "ellipse",
upper = "number")
Jeśli będziemy w przyszłości pracować z danymi, to warto nabyć pewną intuicję dotyczącą tego, jaki wizualny “rozrzut” punktów odpowiada jakiemu współczynnikowi korelacji. Dobrym ćwiczeniem jest dostępna tutaj gra, w której możemy przetestować i “poprawić” swoją intuicję.
http://guessthecorrelation.com/
Możemy podobną grę przeprowadzić za pomocą R. Dobrym punktem wyjścia
jest funkcja rmvnorm
z pakietu mvtnorm
, która
pozwala nam losować skorelowane ze sobą zmienne.
library(mvtnorm)
sym <- rmvnorm(100, mean = c(1,1), sigma = matrix(c(1,1,1,1),2,2))
plot(sym)
cov(sym)
## [,1] [,2]
## [1,] 1.513458 1.513458
## [2,] 1.513458 1.513458
cor(sym)
## [,1] [,2]
## [1,] 1 1
## [2,] 1 1
sym <- rmvnorm(100, mean = c(1,1), sigma = matrix(c(3,2,2,3),2,2))
plot(sym)
cov(sym)
## [,1] [,2]
## [1,] 2.859280 1.529785
## [2,] 1.529785 2.447827
cor(sym)
## [,1] [,2]
## [1,] 1.0000000 0.5782448
## [2,] 0.5782448 1.0000000
Na koniec powróćmy do regresji liniowej. Jak powszechnie wiadomo, równanie prostej dopasowywanej do danych w regresji liniowej ma postać:
\[\hat{Y} = bX + a\]
gdzie:
Wagner, Compas i Howell (1988) badali związek między stresem a zdrowiem psychicznym wśród studentów pierwszego roku koledżu. Używając opracowanego przez siebie narzędzia do mierzenia częstotliwości, odczuwanej wagi i pożądaności niedawnych wydarzeń życiowych, stworzyli miarę negatywnych zdarzeń w życiu. Miara ta służyła do pomiaru środowiskowego i społecznego stresu odczuwanego przez badanych. Oprócz tego poprosili swoich badanych (studentów), aby wypełnili Hopkins Symptom Checklist, która to służy do pomiaru występowania lub brak występowania 57 psychologicznych symptomów zaburzeń zdrowia psychicznego.
Rozpoczniemy od wczytania oraz wizualizacji danych. Za pomocą funkcji
abline
dodamy do wykresu punktowego linię regresji.
df <- read.table('Tab9-2.dat', header = TRUE)
head(df)
## ID Stress Symptoms lnSymptoms
## 1 1 30 99 4.595120
## 2 2 27 94 4.543295
## 3 3 9 80 4.382027
## 4 4 20 70 4.248495
## 5 5 3 100 4.605170
## 6 6 15 109 4.691348
plot(lnSymptoms ~ Stress, data = df)
abline(lm(lnSymptoms ~ Stress, data = df))
Następnie przyjrzymy się bliżej stworzonemu przez nas modelowi.
summary(lm(lnSymptoms ~ Stress, data = df))
##
## Call:
## lm(formula = lnSymptoms ~ Stress, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.42889 -0.13568 0.00478 0.09672 0.40726
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.300537 0.033088 129.974 < 2e-16 ***
## Stress 0.008565 0.001342 6.382 4.83e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1726 on 105 degrees of freedom
## Multiple R-squared: 0.2795, Adjusted R-squared: 0.2726
## F-statistic: 40.73 on 1 and 105 DF, p-value: 4.827e-09
(Dygresja: w pakiecie rms
znajduje się funkcja do
przeprowadzania regresji liniowej zwracająca nieco inne informacje
niz ta domyślnie wbudowana w R. Można ją przetestować po wczytaniu
pakietu rms
(library(rms)
) wywołując polecenie
ols(lnSymptoms ~ Stress, data = df)
)
lm.beta
z pakietu
QuantPsyc
, ale równie dobrze możemy zrobić to sami mnożąc
przez iloraz wariancjiNajczęściej będziemy sprawdzać czy zmienne \(X\) i \(Y\) są skorelowane. W takim wypadku nasze hipotezy będą przestawiać się w następujący sposób. Zaczniemy od hipotezy alternatywnej.
\[ H_A: \rho \neq 0 \]
To znaczy, że hipoteza alternatywna głosi, że korelacja w populacji (\(\rho\)) jest różna od zera. Hipoteza zerowa (tę będziemy obalać!) głosi więc, że korelacja w populacji wynosi 0:
\[ H_0: \rho = 0 \]
Statystyka testowa wygląda w takim przypadku tak:
\[T = \frac{r}{\sqrt{1-r^2}}\sqrt{n-2}\]
która ma przy prawdziwości \(H_0\) rozkład \(t\) o n-2 stopniach swobody.
Możemy to z łatwością sprawdzić za pomocą prostego eksperymentu symulacyjnego.
n <- 35
t_stat = replicate(10000, {
r = cor(rnorm(n), rnorm(n))
(r/sqrt(1-r^2))*sqrt(n-2)})
hist(t_stat, freq = FALSE)
curve(dt(x,n-2), add = TRUE)
Zróbmy proste ćwiczenie. Na początek stwórzmy macierz z losowymi liczbami pochodzącymi z rozkładu normalnego (10 kolumn po 35 liczb) a następnie obliczmy statystykę testową \(t\) dla korelacji między nimi.
# Generujemy zbiór danych
m <- matrix(rnorm(350), 35, 10)
# Tworzymy macierz korealcji
c_m <- cor(m)
# Tworzymy macierz statystyk t
t_m <- (c_m/sqrt(1-c_m^2)) * (sqrt(35-2))
t_m
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] Inf 0.4767474 -1.3747638 0.2458121 -0.68358328 0.18532167
## [2,] 0.4767474 Inf 1.7388401 0.4920464 0.52800892 -2.08382616
## [3,] -1.3747638 1.7388401 Inf 1.1050806 -0.76478314 0.39807438
## [4,] 0.2458121 0.4920464 1.1050806 Inf 0.41576114 -1.65725848
## [5,] -0.6835833 0.5280089 -0.7647831 0.4157611 Inf 0.06271464
## [6,] 0.1853217 -2.0838262 0.3980744 -1.6572585 0.06271464 Inf
## [7,] 1.2256305 0.8030565 -0.5564082 -0.6443222 -1.62451271 0.86812765
## [8,] -0.2402786 -0.7878750 -0.7009782 0.3111047 -0.61975232 0.16176696
## [9,] 0.1035575 -0.8595539 0.2053817 -1.9638383 -0.17924864 1.88127077
## [10,] 0.8617244 0.3213913 -0.1234837 1.5663281 -0.22120038 -0.11961685
## [,7] [,8] [,9] [,10]
## [1,] 1.2256305 -0.2402786 0.1035575 0.8617244
## [2,] 0.8030565 -0.7878750 -0.8595539 0.3213913
## [3,] -0.5564082 -0.7009782 0.2053817 -0.1234837
## [4,] -0.6443222 0.3111047 -1.9638383 1.5663281
## [5,] -1.6245127 -0.6197523 -0.1792486 -0.2212004
## [6,] 0.8681276 0.1617670 1.8812708 -0.1196169
## [7,] Inf -0.3365868 -0.4554974 -0.1809003
## [8,] -0.3365868 Inf -0.9527716 0.5192744
## [9,] -0.4554974 -0.9527716 Inf -1.1924755
## [10,] -0.1809003 0.5192744 -1.1924755 Inf
Mając taką macierz jesteśmy w stanie dla każdej komórki (= dla każdej kombinacji dwóch zmiennych) ocenić, czy odrzucamy hipotezę zerową czy nie. Wystarczy posłużyć się odpowiednim rozkładem \(t\) o \(n-2\) stopniach swobody. Za pomocą funkcji poniżej możemy łatwo stwierdzic, które hipotezy zerowe odrzucamy.
t_m <= qt(0.025, 33) | t_m >= qt(0.975, 33)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
## [3,] FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [5,] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
## [6,] FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
## [7,] FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
## [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
## [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
A nawet policzyć, ile razy odrzuciliśmy hipotezę zerową!
print('Liczba statystycznie istotnych korelacji między wygenerowanymi próbami')
## [1] "Liczba statystycznie istotnych korelacji między wygenerowanymi próbami"
sum(c_m <= qt(0.025, 33) | c_m >= qt(0.975, 33))
## [1] 0
(Uwaga! Test statystyczny dla współczynnika korelacji możemy również
wykonać za pomocą wbudowanej w R funkcji cor.test
. Funkcja
ta jednak przyjmuje tylko dwa wektory!
cor.test(m[1,], m[2,])
##
## Pearson's product-moment correlation
##
## data: m[1, ] and m[2, ]
## t = -0.78619, df = 8, p-value = 0.4544
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## -0.7679439 0.4352023
## sample estimates:
## cor
## -0.2678071
)
Poniżej widzą Państwo wykres ilustrujący nasz eksperyment z losowaniem. Jak widzimy nasza procedura pokazała, że 6 współczynników korelacji, które nie leżą na przekątnej (tzn. nie jest to korelacja zmiennej z samą sobą) przekroczyło próg statystycznej istotności. Wokół jakiej liczby oscylowałaby ta wartość, gdybyśmy powtarzali nasz eksperyment? Dlaczego?
m <- matrix(rnorm(350), 35, 10)
c_m <- cor(m)
t_m <- (c_m/sqrt(1-c_m^2)) * (sqrt(35-2))
reject <- (t_m <= qt(0.025, 33) | t_m >= qt(0.975, 33))
heatmap(matrix(as.numeric(reject), 10,10), Rowv = NA, Colv = NA, col = viridis(2))
print(sum(reject) - 10) # 10 leży na przekątnej
## [1] 4