-
Notifications
You must be signed in to change notification settings - Fork 176
/
Copy pathmodel-slr.qmd
1834 lines (1511 loc) · 78.7 KB
/
model-slr.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Linear regression with a single predictor {#sec-model-slr}
```{r}
#| include: false
source("_common.R")
```
\vspace{-5mm}
::: {.chapterintro data-latex=""}
Linear regression is a very powerful statistical technique.
Many people have some familiarity with regression models just from reading the news, where straight lines are overlaid on scatterplots.
Linear models can be used for prediction or to describe the relationship between two numerical variables, assuming there is a linear relationship between them.
:::
## Fitting a line, residuals, and correlation {#sec-fit-line-res-cor}
When considering linear regression, it's helpful to think deeply about the line fitting process.
In this section, we define the form of a linear model, explore criteria for what makes a good fit, and introduce a new statistic called *correlation*.
### Fitting a line to data
@fig-perfLinearModel shows two variables whose relationship can be modeled perfectly with a straight line.
The equation for the line is $y = 5 + 64.96 x.$ Consider what a perfect linear relationship means: we know the exact value of $y$ just by knowing the value of $x.$ A perfect linear relationship is unrealistic in almost any natural process.
For example, if we took family income $(x),$ this value would provide some useful information about how much financial support a college may offer a prospective student $(y.)$
However, the prediction would be far from perfect, since other factors play a role in financial support beyond a family's finances.
\vspace{-5mm}
```{r}
#| label: fig-perfLinearModel
#| fig-cap: |
#| Requests from twelve separate buyers were simultaneously placed with a
#| trading company to purchase Target Corporation stock (ticker TGT, December
#| 28th, 2018), and the total cost of the shares were reported. Because the
#| cost is computed using a linear formula, the linear fit is perfect.
#| fig-alt: |
#| A scatterplot showing a perfect linear relationship between number of
#| stocks to purchase on the x-axis and total cost of the share purchase
#| on the y-axis.
#| fig-asp: 0.4
target <- simulated_scatter |>
filter(group == 4)
ggplot(target, aes(x = x, y = y)) +
geom_smooth(method = "lm") +
geom_point(size = 3) +
scale_y_continuous(labels = label_dollar(scale = 0.001, suffix = "K", accuracy = 1), breaks = c(0, 1000, 2000)) +
labs(
x = "Number of Target Corporation stocks to purchase",
y = "Total cost of the\nshare purchase"
)
```
\clearpage
Linear regression is the statistical method for fitting a line to data where the relationship between two variables, $x$ and $y,$ can be modeled by a straight line with some error:
$$
y = b_0 + b_1 \ x + e
$$
The values $b_0$ and $b_1$ represent the model's intercept and slope, respectively, and the error is represented by $e.$
These values are calculated based on the data, i.e., they are sample statistics.
If the observed data is a random sample from a target population that we are interested in making inferences about, these values are considered to be point estimates for the population parameters $\beta_0$ and $\beta_1.$
We will discuss how to make inferences about parameters of a linear model based on sample statistics in @sec-inf-model-slr.
::: {.content-visible when-format="html"}
::: {.pronunciation data-latex=""}
The Greek letter $\beta$ is pronounced *beta*, listen to the pronunciation [here](https://youtu.be/PStgY5AcEIw?t=7).
:::
:::
::: {.content-visible when-format="pdf"}
::: {.pronunciation data-latex=""}
The Greek letter $\beta$ is pronounced *beta*.
:::
:::
When we use $x$ to predict $y,$ we usually call $x$ the **predictor**\index{variable!predictor}\index{predictor variable} variable and we call $y$ the **outcome**\index{variable!outcome}\index{outcome variable}.
We also often drop the $e$ term when writing down the model since our main focus is often on the prediction of the average outcome.
```{r}
#| include: false
terms_chp_07 <- c("predictor", "outcome")
```
It is rare for all of the data to fall perfectly on a straight line.
Instead, it's more common for data to appear as a *cloud of points*, such as those examples shown in @fig-imperfLinearModel.
In each case, the data fall around a straight line, even if none of the observations fall exactly on the line.
The first plot shows a relatively strong downward linear trend, where the remaining variability in the data around the line is minor relative to the strength of the relationship between $x$ and $y.$ The second plot shows an upward trend that, while evident, is not as strong as the first.
The last plot shows a very weak downward trend in the data, so slight we can hardly notice it.
In each of these examples, we will have some uncertainty regarding our estimates of the model parameters, $\beta_0$ and $\beta_1.$ For instance, we might wonder, should we move the line up or down a little, or should we tilt it more or less?
As we move forward in this chapter, we will learn about criteria for line-fitting, and we will also learn about the uncertainty associated with estimates of model parameters.
```{r}
#| label: fig-imperfLinearModel
#| fig-cap: |
#| Three datasets where a linear model may be useful even though the data do
#| not all fall exactly on the line.
#| fig-alt: |
#| Three scatterplots with fabricated data. The first panel shows a
#| strong negative linear relationship. The second panel shows a moderate
#| positive linear relationship. The last panel shows no relationship
#| between the x and y variables.
#| out-width: 100%
#| fig-asp: 0.25
neg <- simulated_scatter |> filter(group == 1)
pos <- simulated_scatter |> filter(group == 2)
ran <- simulated_scatter |> filter(group == 3)
p_neg <- ggplot(neg, aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.7) +
geom_smooth(method = "lm", se = FALSE) +
labs(x = NULL, y = NULL)
p_pos <- ggplot(pos, aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.7) +
geom_smooth(method = "lm", se = FALSE) +
labs(x = NULL, y = NULL)
p_ran <- ggplot(ran, aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.7) +
geom_smooth(method = "lm", se = FALSE) +
labs(x = NULL, y = NULL)
p_neg + p_pos + p_ran
```
\vspace{-5mm}
There are also cases where fitting a straight line to the data, even if there is a clear relationship between the variables, is not helpful.
One such case is shown in @fig-notGoodAtAllForALinearModel where there is a very clear relationship between the variables even though the trend is not linear.
We discuss nonlinear trends in this chapter and the next, but details of fitting nonlinear models are saved for a later course.
```{r}
#| label: fig-notGoodAtAllForALinearModel
#| fig-cap: |
#| The best fitting line for these data is flat, which is not a useful way
#| to describe the non-linear relationship. These data are from a physics
#| experiment.
#| fig-alt: |
#| A scatterplot showing a perfect quadratic relationship between angle of
#| incline on the x-axis and distance traveled on the y-axis. The line of
#| best fit is superimposed as a perfectly horizontal line. That is to say,
#| the variables are clearly related, but they do not have a linear
#| relationship.
#| fig-asp: 0.25
bad <- simulated_scatter |> filter(group == 5)
ggplot(bad, aes(x = x, y = y)) +
geom_point(size = 2.5) +
geom_smooth(method = "lm", se = FALSE) +
labs(
x = "Angle of Incline (Degrees)",
y = "Distance Traveled (m)"
)
```
\clearpage
### Using linear regression to predict possum head lengths
Brushtail possums are marsupials that live in Australia, and a photo of one is shown in @fig-brushtail-possum.
Researchers captured 104 of these animals and took body measurements before releasing the animals back into the wild.
We consider two of these measurements: the total length of each possum, from head to tail, and the length of each possum's head.
```{r}
#| label: fig-brushtail-possum
#| fig-alt: Photograph of a common brushtail possum of Australia.
#| fig-cap: |
#| The common brushtail possum of Australia. Photo by Greg Schecter,
#| [flic.kr/p/9BAFbR](https://flic.kr/p/9BAFbR), CC BY 2.0 license.
#| out-width: 50%
knitr::include_graphics("images/brushtail-possum/brushtail-possum.jpg")
```
::: {.data data-latex=""}
The [`possum`](http://openintrostat.github.io/openintro/reference/possum.html) data can be found in the [**openintro**](http://openintrostat.github.io/openintro) R package.
:::
@fig-scattHeadLTotalL shows a scatterplot for the head length (mm) and total length (cm) of the possums.
Each point represents a single possum from the data.
The head and total length variables are associated: possums with an above average total length also tend to have above average head lengths.
While the relationship is not perfectly linear, it could be helpful to partially explain the connection between these variables with a straight line.
```{r}
#| label: fig-scattHeadLTotalL
#| fig-cap: |
#| A scatterplot showing head length against total length for 104 brushtail
#| possums. A point representing a possum with head length 86.7 mm and total
#| length 84 cm is highlighted.
#| fig-alt: |
#| A scatterplot with total length on the x-axis and head length on the
#| y-axis. The variables show a moderately strong positive linear
#| relationship. A single observation is circled in red with coordinates
#| of approximately 84cm of total length and 87mm of head length.
#| fig-asp: 0.5
ggplot(possum, aes(x = total_l, y = head_l)) +
geom_point(alpha = 0.7, size = 2) +
labs(
x = "Total Length (cm)",
y = "Head Length (mm)"
) +
geom_point(
data = tibble(x = 84, y = 86.7),
aes(x = x, y = y),
color = IMSCOL["red", "full"],
size = 5, shape = "circle open", stroke = 2
)
```
We want to describe the relationship between head and total length of possum's with a line.
In this example, we will use the total length as the predictor variable, $x,$ to predict a possum's head length, $y.$ We could fit the linear relationship by eye, as in @fig-scattHeadLTotalLLine.
\clearpage
```{r}
#| label: fig-scattHeadLTotalLLine
#| fig-cap: |
#| A reasonable linear model was fit to represent the relationship between
#| head length and total length.
#| fig-alt: |
#| A scatterplot with total length on the x-axis and head length on the
#| y-axis. The variables show a moderately strong positive linear relationship.
#| A least squares line is superimposed.
#| fig-asp: 0.5
ggplot(possum, aes(x = total_l, y = head_l)) +
geom_point(alpha = 0.7, size = 2) +
labs(
x = "Total Length (cm)",
y = "Head Length (mm)"
) +
geom_smooth(method = "lm", se = FALSE)
```
The equation for this line is
\vspace{-5mm}
$$
\hat{y} = 41 + 0.59x
$$
A "hat" on $y$ is used to signify that this is an estimate.
We can use this line to discuss properties of possums.
For instance, the equation predicts a possum with a total length of 80 cm will have a head length of
\vspace{-5mm}
$$
\hat{y} = 41 + 0.59 \times 80 = 88.2
$$
The estimate may be viewed as an average: the equation predicts that possums with a total length of 80 cm will have an average head length of 88.2 mm.
Absent further information about an 80 cm possum, the prediction for head length that uses the average is a reasonable estimate.
There may be other variables that could help us predict the head length of a possum besides its length.
Perhaps the relationship would be a little different for male possums than female possums, or perhaps it would differ for possums from one region of Australia versus another region.
@fig-scattHeadLTotalL-sex-age-1 shows the relationship between total length and head length of brushtail possums, taking into consideration their sex.
Male possums (represented by blue triangles) seem to be larger in terms of total length and head length than female possums (represented by red circles).
@fig-scattHeadLTotalL-sex-age-2 shows the same relationship, taking into consideration their age.
It's harder to tell if age changes the relationship between total length and head length for these possums.
```{r}
#| label: fig-scattHeadLTotalL-sex-age
#| fig-cap: |
#| Relationship between total length and head length of brushtail possums,
#| taking into consideration their sex or age.
#| fig-subcap:
#| - By sex
#| - By age
#| fig-alt: |
#| Two scatterplots, both with total length on the x-axis and head
#| length on the y-axis. The top plot colors the points by sex where the female
#| possums seem slightly longer with slightly smaller head lengths. The bottom
#| plot is colored by age with no obvious trends between age and lengths.
#| layout-ncol: 2
#| fig-width: 5
#| out-width: 100%
p_sex <- ggplot(possum, aes(x = total_l, y = head_l, shape = sex, color = sex)) +
geom_point(alpha = 0.8, size = 2) +
scale_color_manual(values = c(IMSCOL["red", "full"], IMSCOL["blue", "full"])) +
labs(
x = "Total Length (cm)",
y = "Head Length (mm)",
color = "Sex", shape = "Sex"
)
p_age <- ggplot(possum, aes(x = total_l, y = head_l, color = age)) +
geom_point(size = 2) +
labs(
x = "Total Length (cm)",
y = "Head Length (mm)",
color = "Age"
) +
scale_color_gradient(
low = IMSCOL["green", "f4"],
high = IMSCOL["green", "full"]
)
p_sex
p_age
```
In @sec-model-mlr, we'll learn about how we can include more than one predictor in our model.
Before we get there, we first need to better understand how to best build a linear model with one predictor.
\clearpage
### Residuals {#sec-resids}
**Residuals**\index{residuals} are the leftover variation in the data after accounting for the model fit:
$$
\text{Data} = \text{Fit} + \text{Residual}
$$
Each observation will have a residual, and three of the residuals for the linear model we fit for the possum data are shown in @fig-scattHeadLTotalLLine-highlighted.
If an observation is above the regression line, then its residual, the vertical distance from the observation to the line, is positive.
Observations below the line have negative residuals.
One goal in picking the right linear model is for residuals to be as small as possible.
```{r}
#| include: false
terms_chp_07 <- c(terms_chp_07, "residuals")
```
@fig-scattHeadLTotalLLine-highlighted is almost a replica of @fig-scattHeadLTotalLLine, with three points from the data highlighted.
The observation marked by a red circle has a small, negative residual of about -1; the observation marked by a gray diamond has a large positive residual of about +7; and the observation marked by a pink triangle has a moderate negative residual of about -4.
The size of a residual is usually discussed in terms of its absolute value.
For example, the residual for the observation marked by a pink triangle is larger than that of the observation marked by a red circle because $|-4|$ is larger than $|-1|.$
```{r}
#| label: fig-scattHeadLTotalLLine-highlighted
#| fig-cap: |
#| A reasonable linear model was fit to represent the relationship between
#| head length and total length, with three points highlighted.
#| fig-alt: |
#| A scatterplot with total length on the x-axis and head length on the
#| y-axis. A least squares line is superimposed onto the scatterplot.
#| Three individual observations are circled to indicate their vertical
#| distance from the least square line.
mod <- lm(head_l ~ total_l, data = possum)
preds <- predict(mod, data.frame(total_l = c(76, 85, 95.5)))
obs <- c(85.1, 98.6, 94)
ggplot(possum, aes(x = total_l, y = head_l)) +
geom_point(alpha = 0.8, size = 2) +
labs(
x = "Total Length (cm)",
y = "Head Length (mm)"
) +
geom_smooth(method = "lm", se = FALSE) +
geom_point(
data = possum |> filter(total_l == 76),
shape = "circle open", stroke = 2,
size = 4, color = IMSCOL["red", "full"]
) +
geom_segment(aes(x = 76, y = preds[1], xend = 76, yend = obs[1] + 0.4),
color = IMSCOL["red", "full"], inherit.aes = FALSE
) +
geom_point(
data = possum |> filter(total_l == 85, head_l == 98.6),
shape = "diamond open", stroke = 2, size = 5,
color = IMSCOL["gray", "full"]
) +
geom_segment(aes(x = 85, y = preds[2], xend = 85, yend = obs[2] - 0.5),
color = IMSCOL["gray", "full"], inherit.aes = FALSE
) +
geom_point(
data = possum |> filter(total_l == 95.5, head_l == 94),
shape = "triangle open", stroke = 2, size = 5,
color = IMSCOL["pink", "full"]
) +
geom_segment(aes(x = 95.5, y = preds[3], xend = 95.5, yend = obs[3] + 0.5),
color = IMSCOL["pink", "full"], inherit.aes = FALSE
)
```
::: {.important data-latex=""}
**Residual: Difference between observed and expected.**
The residual of the $i^{th}$ observation $(x_i, y_i)$ is the difference of the observed outcome $(y_i)$ and the outcome we would predict based on the model fit $(\hat{y}_i):$
$$
e_i = y_i - \hat{y}_i
$$
We typically identify $\hat{y}_i$ by plugging $x_i$ into the model.
:::
::: {.workedexample data-latex=""}
The linear fit shown in @fig-scattHeadLTotalLLine-highlighted is given as $\hat{y} = 41 + 0.59x.$ Based on this line, compute the residual of the observation $(76.0, 85.1).$ This observation is marked by a red circle in @fig-scattHeadLTotalLLine-highlighted.
Check it against the earlier visual estimate, -1.
------------------------------------------------------------------------
We first compute the predicted value of the observation marked by a red circle based on the model: $\hat{y} = 41+0.59x = 41+0.59\times 76.0 = 85.84$.
Next we compute the difference of the actual head length and the predicted head length: $e = y - \hat{y} = 85.1 - 85.84 = -0.74$.
The model's error is $e = -0.74$ mm, which is very close to the visual estimate of -1 mm.
The negative residual indicates that the linear model overpredicted head length for this possum.
:::
::: {.guidedpractice data-latex=""}
If a model underestimates an observation, will the residual be positive or negative?
What about if it overestimates the observation?[^07-model-slr-1]
:::
[^07-model-slr-1]: If a model underestimates an observation, then the model estimate is below the actual.
The residual, which is the actual observation value minus the model estimate, must then be positive.
The opposite is true when the model overestimates the observation: the residual is negative.
::: {.guidedpractice data-latex=""}
Compute the residuals for the observation marked by a blue diamond, $(85.0, 98.6),$ and the observation marked by a pink triangle, $(95.5, 94.0),$ in the figure using the linear relationship $\hat{y} = 41 + 0.59x.$[^07-model-slr-2]
:::
[^07-model-slr-2]: Gray diamond: $\hat{y} = 41+0.59x = 41+0.59\times 85.0 = 91.15 \rightarrow e = y - \hat{y} = 98.6-91.15=7.45.$ This is close to the earlier estimate of 7.
pink triangle: $\hat{y} = 41+0.59x = 97.3 \rightarrow e = -3.3.$ This is also close to the estimate of -4.
Residuals are helpful in evaluating how well a linear model fits a dataset.
We often display them in a scatterplot such as the one shown in @fig-scattHeadLTotalLResidualPlot for the regression line in @fig-scattHeadLTotalLLine-highlighted.
The residuals are plotted with their predicted outcome variable value as the horizontal coordinate, and the vertical coordinate as the residual.
For instance, the point $(85.0, 98.6)$ (marked by the blue diamond) had a predicted value of 91.4 mm and had a residual of 7.45 mm, so in the residual plot it is placed at $(91.4, 7.45).$ Creating a residual plot is sort of like tipping the scatterplot over so the regression line is horizontal, as indicated by the dashed line.
```{r}
#| label: fig-scattHeadLTotalLResidualPlot
#| fig-cap: |
#| Residual plot for the model predicting head length from total length for
#| brushtail possums.
#| fig-alt: |
#| A residual plot based on @fig-scattHeadLTotalLLine-highlighted
#| displaying predicted values on the x-axis and residual values on the y-axis.
#| The same three points that were circled in
#| @fig-scattHeadLTotalLLine-highlighted are still circled, demonstrating the
#| vertical distance from the least squares line is the residual.
m_head_total <- lm(head_l ~ total_l, data = possum)
m_head_total_aug <- augment(m_head_total)
ggplot(m_head_total_aug, aes(x = .fitted, y = .resid)) +
geom_point(alpha = 0.8, size = 2) +
labs(
x = "Predicted values of head length (mm)",
y = "Residuals"
) +
geom_hline(yintercept = 0, linetype = "dashed") +
geom_point(
data = m_head_total_aug |>
filter(total_l == 76),
shape = "circle open", stroke = 2, size = 4,
color = IMSCOL["red", "full"]
) +
geom_segment(
aes(
x = preds[1], y = obs[1] - preds[1] + 0.2,
xend = preds[1], yend = 0
),
color = IMSCOL["red", "full"], inherit.aes = FALSE
) +
geom_point(
data = m_head_total_aug |>
filter(total_l == 85, head_l == 98.6),
shape = "diamond open", stroke = 2, size = 5,
color = IMSCOL["gray", "full"]
) +
geom_segment(
aes(
x = preds[2], y = obs[2] - preds[2] - 0.3,
xend = preds[2], yend = 0
),
color = IMSCOL["gray", "full"], inherit.aes = FALSE
) +
geom_point(
data = m_head_total_aug |>
filter(total_l == 95.5, head_l == 94),
shape = "triangle open", stroke = 2, size = 5,
color = IMSCOL["pink", "full"]
) +
geom_segment(
aes(
x = preds[3], y = obs[3] - preds[3] + 0.3,
xend = preds[3], yend = 0
),
color = IMSCOL["pink", "full"], inherit.aes = FALSE
)
```
\clearpage
::: {.workedexample data-latex=""}
One purpose of residual plots is to identify characteristics or patterns still apparent in data after fitting a model.
The figure below shows three scatterplots with linear models in the first row and residual plots in the second row.
Can you identify any patterns in the residuals?
```{r}
#| label: sampleLinesAndResPlots
#| fig-alt: |
#| A grid of 2 by 3 scatterplots with fabricated data. The top row of
#| plots contains original x-y data plots with a least squares regression line.
#| The bottom row of plots is a series of residual plot with predicted value on
#| the x-axis and residual on the y-axis. The first column of plots gives an
#| example of points that are well described by a linear model. The second
#| column of plots gives an example where the correct model seems to be quadratic
#| insead of linear. The third column of points gives an example where there is
#| no visual relationship between x and y.
#| fig-align: center
#| fig-asp: 0.5
neg_lin <- simulated_scatter |> filter(group == 6)
neg_cur <- simulated_scatter |> filter(group == 7)
random <- simulated_scatter |> filter(group == 8)
neg_lin_mod <- augment(lm(y ~ x, data = neg_lin))
neg_cur_mod <- augment(lm(y ~ x, data = neg_cur))
random_mod <- augment(lm(y ~ x, data = random))
p_neg_lin <- ggplot(neg_lin, aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = FALSE) +
theme_void() +
theme(panel.border = element_rect(colour = "gray", fill = NA, size = 1)) +
labs(title = "Dataset 1")
p_neg_cur <- ggplot(neg_cur, aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = FALSE) +
theme_void() +
theme(panel.border = element_rect(colour = "gray", fill = NA, size = 1))+
labs(title = "Dataset 2")
p_random <- ggplot(random, aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = FALSE) +
theme_void() +
theme(panel.border = element_rect(colour = "gray", fill = NA, size = 1)) +
labs(title = "Dataset 3")
p_neg_lin_res <- ggplot(neg_lin_mod, aes(x = .fitted, y = .resid)) +
geom_point(size = 2, alpha = 0.8) +
geom_hline(yintercept = 0, linetype = "dashed") +
theme_void() +
theme(panel.border = element_rect(colour = "gray", fill = NA, size = 1))
p_neg_cur_res <- ggplot(neg_cur_mod, aes(x = .fitted, y = .resid)) +
geom_point(size = 2, alpha = 0.8) +
geom_hline(yintercept = 0, linetype = "dashed") +
theme_void() +
theme(panel.border = element_rect(colour = "gray", fill = NA, size = 1))
p_random_res <- ggplot(random_mod, aes(x = .fitted, y = .resid)) +
geom_point(size = 2, alpha = 0.8) +
geom_hline(yintercept = 0, linetype = "dashed") +
theme_void() +
theme(panel.border = element_rect(colour = "gray", fill = NA, size = 1))
p_neg_lin + theme(plot.margin = unit(c(0, 10, 5, 0), "pt")) +
p_neg_cur + theme(plot.margin = unit(c(0, 10, 5, 0), "pt")) + p_random +
p_neg_lin_res + theme(plot.margin = unit(c(0, 10, 5, 0), "pt")) +
p_neg_cur_res + theme(plot.margin = unit(c(0, 10, 5, 0), "pt")) + p_random_res +
plot_layout(ncol = 3, heights = c(2, 1))
```
------------------------------------------------------------------------
Dataset 1: the residuals show no obvious patterns.
The residuals are scattered randomly around 0, represented by the dashed line.
Dataset 2: The second dataset shows a pattern in the residuals.
There is some curvature in the scatterplot, which is more obvious in the residual plot.
We should not use a straight line to model these data.
Instead, a more advanced technique should be used to model the curved relationship, such as the variable transformations discussed in @sec-transforming-data.
Dataset 3: The last plot shows very little upwards trend, and the residuals also show no obvious patterns.
It is reasonable to try to fit a linear model to the data.
However, it is unclear whether there is evidence that the slope parameter is different from zero.
The point estimate of the slope parameter is not zero, but we might wonder if this could just be due to chance.
We will address this scenario in @sec-inf-model-slr.
:::
### Describing linear relationships with correlation
We've seen plots with strong linear relationships and others with very weak linear relationships.
It would be useful if we could quantify the strength of these linear relationships with a statistic.
::: {.important data-latex=""}
**Correlation: strength of a linear relationship.**
**Correlation**\index{correlation} which always takes values between -1 and 1, describes the strength and direction of the linear relationship between two variables.
We denote the correlation by $r.$
The correlation value has no units and will not be affected by a linear change in the units (e.g., going from inches to centimeters).
:::
```{r}
#| include: false
terms_chp_07 <- c(terms_chp_07, "correlation")
```
We can compute the correlation using a formula, just as we did with the sample mean and standard deviation.
The formula for correlation, however, is rather complex[^07-model-slr-3], and like with other statistics, we generally perform the calculations on a computer or calculator.
[^07-model-slr-3]: Formally, we can compute the correlation for observations $(x_1, y_1),$ $(x_2, y_2),$ ..., $(x_n, y_n)$ using the formula
$$
r = \frac{1}{n-1} \sum_{i=1}^{n} \frac{x_i-\bar{x}}{s_x}\frac{y_i-\bar{y}}{s_y}
$$
where $\bar{x},$ $\bar{y},$ $s_x,$ and $s_y$ are the sample means and standard deviations for each variable.
\clearpage
@fig-posNegCorPlots shows eight plots and their corresponding correlations.
Only when the relationship is perfectly linear is the correlation either -1 or +1.
If the relationship is strong and positive, the correlation will be near +1.
If it is strong and negative, it will be near -1.
If there is no apparent linear relationship between the variables, then the correlation will be near zero.
```{r}
#| label: fig-posNegCorPlots
#| fig-cap: |
#| Sample scatterplots and their correlations. The first row shows variables
#| with a positive relationship, represented by the trend up and to the right.
#| The second row shows variables with a negative trend, where a large value
#| in one variable is associated with a lower value in the other.
#| fig-alt: |
#| Eight scatterplots on fabricated data. The first seven plots show
#| linear trends with correlations ranging from -1 to +1. The eighth plot shows
#| a quadratic relationship whih produces a correlation of -0.28.
#| fig-asp: 0.5
#| out-width: 100%
library(ggpubr) # Adding here instead of _common.R to avoid collision with ggimage
simulated_scatter |>
filter(group %in% c(9:12, 14:17)) |>
ggplot(aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.8) +
theme_void() +
facet_wrap(~group, nrow = 2, scales = "free") +
theme(
panel.border = element_rect(colour = "gray", fill = NA, linewidth = 1),
strip.background = element_blank(),
strip.text.x = element_blank()
) +
stat_cor(
aes(label = paste("r", ..r.., sep = "~`=`~")),
geom = "label"
)
```
The correlation is intended to quantify the strength of a linear trend.
Nonlinear trends, even when strong, sometimes produce correlations that do not reflect the strength of the relationship; see three such examples in @fig-corForNonLinearPlots.
```{r}
#| label: fig-corForNonLinearPlots
#| fig-cap: |
#| Sample scatterplots and their correlations. In each case, there is a strong
#| relationship between the variables. However, because the relationship is
#| not linear, the correlation is relatively weak.
#| fig-alt: |
#| Three scatterplots on fabricated data which demonstrate strong
#| patterns between the x and y variables. The first plot shows a
#| quadratic trend with a correlation of -0.23. The second plot shows a cyclic
#| trend (like a sin wave) with a correlation of 0.31. The third plot shows
#| a distinct relationship that is not obviously functional and has a
#| correlation of 0.5.
#| fig-asp: 0.25
#| out-width: 100%
simulated_scatter |>
filter(group %in% 17:19) |>
ggplot(aes(x = x, y = y)) +
geom_point(size = 2, alpha = 0.8) +
theme_void() +
facet_wrap(~group, nrow = 1, scales = "free") +
theme(
panel.border = element_rect(colour = "gray", fill = NA, size = 1),
strip.background = element_blank(),
strip.text.x = element_blank()
) +
stat_cor(
aes(label = paste("r", ..r.., sep = "~`=`~")),
geom = "label"
)
```
::: {.guidedpractice data-latex=""}
No straight line is a good fit for any of the datasets represented in @fig-corForNonLinearPlots.
Try drawing nonlinear curves on each plot.
Once you create a curve for each, describe what is important in your fit.[^07-model-slr-4]
:::
[^07-model-slr-4]: We'll leave it to you to draw the lines.
In general, the lines you draw should be close to most points and reflect overall trends in the data.
\clearpage
::: {.workedexample data-latex=""}
The plot below displays the relationships between various crop yields in countries.
In the plots, each point represents a different country.
The x and y variables represent the proportion of total yield in the last 50 years which is due to that crop type.
If a country did not produce a particular crop, it has been removed from the plot (so different plots may have different numbers of dots, each corresponding to one country).
Order the six scatterplots from strongest negative to strongest positive linear relationship.
```{r}
#| label: crop-yields-af-prep
# from tidytuesday: https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-09-01/key_crop_yields.csv
crops_country <- read_csv("data/key_crop_yields.csv")
crops_country <- crops_country |>
rename_with(tolower) |>
rename_with(str_remove, contains("tonnes"), " \\(tonnes per hectare\\)") |>
rename(cocoa = `cocoa beans`) |>
filter(!is.na(code)) |>
pivot_longer(
cols = wheat:bananas,
names_to = "crop",
values_to = "yield"
) |>
group_by(code, crop) |>
summarise(total = sum(yield, na.rm = TRUE), .groups = "drop_last") |>
mutate(prop = (total / sum(total)) * 100) |>
ungroup() |>
filter(prop > 0) |>
pivot_wider(
names_from = crop,
values_from = c(total, prop),
values_fill = NA
)
```
```{r}
#| label: crop-yields-af
#| fig-alt: |
#| From a real dataset, we display scatterplots of the relationship
#| between percent of crop which is each of the following -- bananas, potatoes,
#| cassava, soybeans, maize, cocoa, barley, peas, and wheat for each country. For
#| example, potatoes and bananas are negatively correlated and bananas and cocoa
#| do not seem correlated at all.
#| fig-asp: 0.8
#| out-width: 90%
#| fig-align: center
sb <- ggplot(crops_country) +
geom_point(aes(x = prop_soybeans, y = prop_bananas), alpha = 0.7) +
scale_x_continuous(
limits = c(0, 6),
labels = label_percent(scale = 1)
) +
scale_y_continuous(labels = label_percent(scale = 1)) +
labs(
x = "% Soybeans",
y = "% Bananas"
)
sc <- ggplot(crops_country) +
geom_point(aes(x = prop_soybeans, y = prop_cassava), alpha = 0.7) +
scale_x_continuous(
limits = c(0, 6),
labels = label_percent(scale = 1)
) +
scale_y_continuous(labels = label_percent(scale = 1)) +
labs(
x = "% Soybeans",
y = "% Cassava"
)
mc <- ggplot(crops_country) +
geom_point(aes(x = prop_maize, y = prop_cassava), alpha = 0.7) +
scale_x_continuous(
limits = c(0, 15),
labels = label_percent(scale = 1)
) +
scale_y_continuous(labels = label_percent(scale = 1)) +
labs(
x = "% Maize",
y = "% Cassava"
)
peb <- ggplot(crops_country) +
geom_point(aes(x = prop_potatoes, y = prop_bananas), alpha = 0.7) +
scale_x_continuous(
limits = c(0, 60),
labels = label_percent(scale = 1)
) +
scale_y_continuous(labels = label_percent(scale = 1)) +
labs(
x = "% Potatoes",
y = "% Bananas"
)
cb <- ggplot(crops_country) +
geom_point(aes(x = prop_cocoa, y = prop_bananas), alpha = 0.7) +
scale_x_continuous(labels = label_percent(scale = 1)) +
scale_y_continuous(labels = label_percent(scale = 1)) +
labs(
x = "% Cocoa",
y = "% Bananas"
)
wb <- ggplot(crops_country) +
geom_point(aes(x = prop_wheat, y = prop_barley), alpha = 0.7) +
scale_x_continuous(labels = label_percent(scale = 1)) +
scale_y_continuous(labels = label_percent(scale = 1)) +
labs(
x = "% Wheat",
y = "% Barley"
)
pob <- ggplot(crops_country) +
geom_point(aes(x = prop_peas, y = prop_barley), alpha = 0.7) +
scale_x_continuous(labels = label_percent(scale = 1)) +
scale_y_continuous(labels = label_percent(scale = 1)) +
labs(
x = "% Peas",
y = "% Barley"
)
peb + sc + mc + cb + pob + wb +
plot_layout(ncol = 2) +
plot_annotation(tag_levels = "A")
```
------------------------------------------------------------------------
The order of most negative correlation to most positive correlation is:
\vspace{-2mm}
$$
A \rightarrow D \rightarrow B \rightarrow C \rightarrow E \rightarrow F
$$
- Plot A - bananas vs. potatoes: `r round(cor(crops_country$prop_potatoes, crops_country$prop_bananas, use = "pairwise.complete.obs"), digits = 2)`
- Plot B - cassava vs. soybeans: `r round(cor(crops_country$prop_soybeans, crops_country$prop_cassava, use = "pairwise.complete.obs"), digits = 2)`
- Plot C - cassava vs. maize: `r round(cor(crops_country$prop_maize, crops_country$prop_cassava, use = "pairwise.complete.obs"), digits = 2)`
- Plot D - cocoa vs. bananas: `r round(cor(crops_country$prop_cocoa, crops_country$prop_bananas, use = "pairwise.complete.obs"), digits = 2)`
- Plot E - peas vs. barley: `r round(cor(crops_country$prop_peas, crops_country$prop_barley, use = "pairwise.complete.obs"), digits = 2)`
- Plot F - wheat vs. barley: `r round(cor(crops_country$prop_wheat, crops_country$prop_barley, use = "pairwise.complete.obs"), digits = 2)`
:::
\vspace{-3mm}
One important aspect of the correlation is that it's *unitless*.
That is, unlike a measurement of the slope of a line (see the next section) which provides an increase in the y-coordinate for a one unit increase in the x-coordinate (in units of the x and y variable), there are no units associated with the correlation of x and y.
@fig-bdims-units shows the relationship between weights and heights of 507 physically active individuals.
In @fig-bdims-units-1, weight is measured in kilograms (kg) and height in centimeters (cm).
In @fig-bdims-units-2, weight has been converted to pounds (lbs) and height to inches (in).
The correlation coefficient ($r = 0.72$) is also noted on both plots.
We can see that the shape of the relationship has not changed, and neither has the correlation coefficient.
The only visual change to the plot is the axis *labeling* of the points.
\clearpage
```{r}
#| label: fig-bdims-units
#| fig-cap: |
#| Two scatterplots, both displaying the relationship between weights and
#| heights of 507 physically healthy adults and the correlation coefficient,
#| $r = 0.72$.
#| fig-subcap:
#| - The units are kilograms and centimeters.
#| - The units are pounds and inches.
#| fig-alt: |
#| Two scatterplots, both displaying the relationship between weights and
#| heights of 507 physically healthy adults. In the first plot height is
#| measured in cm and weight is measured in kg. In the second plot height
#| is measured in inches and weight is measured in pounds. The images
#| look identical, except for the axes tick marks.
#| fig-asp: 0.5
p_1 <- ggplot(bdims, aes(x = hgt, y = wgt)) +
geom_point(alpha = 0.8) +
labs(x = "Height (cm)", y = "Weight (kg)") +
stat_cor(
aes(label = paste("r", ..r.., sep = "~`=`~")),
geom = "label"
)
p_2 <- bdims |>
mutate(
hgt = hgt * 0.393701,
wgt = wgt * 2.20462
) |>
ggplot(aes(x = hgt, y = wgt)) +
geom_point(alpha = 0.8) +
labs(x = "Height (in)", y = "Weight (lbs)") +
stat_cor(
aes(label = paste("r", ..r.., sep = "~`=`~")),
geom = "label"
)
p_1
p_2
```
## Least squares regression {#sec-least-squares-regression}
Fitting linear models by eye is open to criticism since it is based on an individual's preference.
In this section, we use *least squares regression* as a more rigorous approach to fitting a line to a scatterplot.
### Gift aid for first-year at Elmhurst College
This section considers a dataset on family income and gift aid data from a random sample of fifty students in the first-year class of Elmhurst College in Illinois.
Gift aid is financial aid that does not need to be paid back, as opposed to a loan.
A scatterplot of these data is shown in @fig-elmhurstScatterWLine along with a linear fit.
The line follows a negative trend in the data; students who have higher family incomes tended to have lower gift aid from the university.
::: {.guidedpractice data-latex=""}
Is the correlation positive or negative in @fig-elmhurstScatterWLine?[^07-model-slr-5]
:::
[^07-model-slr-5]: Larger family incomes are associated with lower amounts of aid, so the correlation will be negative.
Using a computer, the correlation can be computed: -0.499.
```{r}
#| label: fig-elmhurstScatterWLine
#| fig-cap: |
#| Gift aid and family income for a random sample of 50 first-year
#| students from Elmhurst College.
#| fig-alt: |
#| Scatterplot with family income on the x-axis and gift aid on the
#| y-axis. The relationship is moderate negative and linear.
#| fig-asp: 0.6
ggplot(elmhurst, aes(x = family_income, y = gift_aid)) +
geom_point(size = 2) +
geom_smooth(method = "lm", se = FALSE) +
scale_y_continuous(labels = label_dollar(scale = 1, suffix = "K", accuracy = 1)) +
scale_x_continuous(labels = label_dollar(scale = 1, suffix = "K", accuracy = 1)) +
labs(
x = "Family income",
y = "Gift aid from university"
)
```
\vspace{-5mm}
### An objective measure for finding the best line
We begin by thinking about what we mean by the "best" line.
Mathematically, we want a line that has small residuals.
But beyond the mathematical reasons, hopefully it also makes sense intuitively that whatever line we fit, the residuals should be small (i.e., the points should be close to the line).
The first option that may come to mind is to minimize the sum of the residual magnitudes:
$$
|e_1| + |e_2| + \dots + |e_n|
$$
which we could accomplish with a computer program.
The resulting dashed line shown in @fig-elmhurstScatterW2Lines demonstrates this fit can be quite reasonable.
```{r}
#| label: fig-elmhurstScatterW2Lines
#| fig-cap: |
#| Gift aid and family income for a random sample of 50 first-year Elmhurst
#| College students. The dashed line is the line that minimizes
#| the sum of the absolute value of residuals, the solid line is the
#| line that minimizes the sum of squared residuals, i.e., the least squares line.
#| fig-alt: |
#| Scatterplot with family income on the x-axis and gift aid on the
#| y-axis. The relationship is moderate negative and linear. Two lines are
#| superimposed on the scatterplot. One line is fit to the data by minimizing
#| the sum of squared residuals, i.e., the least squares line. The other line
#| is fit to the data by minimizing the sum of the abolute value of the residuals.
#| fig-asp: 0.6
ggplot(elmhurst, aes(x = family_income, y = gift_aid)) +
geom_point(alpha = 0.8) +
geom_smooth(method = "lm", se = FALSE) +
geom_smooth(method = quantreg::rq, formula = y ~ x, se = FALSE, linetype = "dashed") +
scale_y_continuous(labels = label_dollar(scale = 1, suffix = "K", accuracy = 1)) +
scale_x_continuous(labels = label_dollar(scale = 1, suffix = "K", accuracy = 1)) +
labs(
x = "Family income",
y = "Gift aid from university"
)
```
However, a more common practice is to choose the line that minimizes the sum of the squared residuals:
$$
e_{1}^2 + e_{2}^2 + \dots + e_{n}^2
$$
\clearpage
The line that minimizes this least squares criterion is represented as the solid line in @fig-elmhurstScatterW2Lines and is commonly called the **least squares line**\index{least squares line}.
The following are three possible reasons to choose the least squares option instead of trying to minimize the sum of residual magnitudes without any squaring:
```{r}
#| include: false
terms_chp_07 <- c(terms_chp_07, "least squares line")
```
1. It is the most commonly used method.
2. Computing the least squares line is widely supported in statistical software.
3. In many applications, a residual twice as large as another residual is more than twice as bad. For example, being off by 4 is usually more than twice as bad as being off by 2. Squaring the residuals accounts for this discrepancy.
4. The analyses which link the model to inference about a population are most straightforward when the line is fit through least squares.
The first two reasons are largely for tradition and convenience; the third and fourth reasons explain why the least squares criterion is typically most helpful when working with real data.[^07-model-slr-6]
[^07-model-slr-6]: There are applications where the sum of residual magnitudes may be more useful, and there are plenty of other criteria we might consider.
However, this book only applies the least squares criterion.