#set document(title: "12.10 Conclusion - Simple Linear Regression", author: "Rachel Webb") #set page(width: 8.5in, height: auto, margin: 1in) #import "@preview/cetz:0.5.2" #set text(font: ("STIX Two Text", "Libertinus Serif", "New Computer Modern"), size: 10.5pt, lang: "en") #show math.equation: set text(font: ("STIX Two Math", "New Computer Modern Math")) #set par(justify: true, leading: 0.62em, spacing: 0.9em) #set enum(spacing: 1.1em) // room between list items so tall inline fractions don't collide #set list(spacing: 1.1em) #set table(stroke: 0.5pt + rgb("#c7ccd3")) #let BLUE = rgb("#183B6F") // brand navy — section bars + example/solution labels (white on navy 11.09:1) #let ORANGE = rgb("#A94509") // brand primary-700 — AA-safe deep orange for TEXT (5.93:1 on white; raw brand #F37021 is 2.94:1 and must never carry text) #let RED = rgb("#DC2626") // brand error-600 #let GREEN = rgb("#059669") // brand success-600 (decoration only; small green text uses green-text #007942) #show heading.where(level: 1): it => block(width: 100%, above: 0pt, below: 16pt, fill: gradient.linear(BLUE, rgb("#2C5AA0")), inset: (x: 14pt, y: 12pt), radius: 3pt, text(fill: white, weight: "bold", size: 19pt, it.body)) #show heading.where(level: 2): it => block(width: 100%, above: 18pt, below: 10pt, fill: BLUE, inset: (x: 10pt, y: 6pt), radius: 2pt, text(fill: white, weight: "bold", size: 12pt, it.body)) #show heading.where(level: 3): it => text(fill: ORANGE, weight: "bold", size: 12.5pt, it.body) #show heading.where(level: 4): it => text(fill: BLUE, weight: "bold", size: 10.5pt, it.body) #let examplebox(label, title, body) = block(width: 100%, breakable: true, fill: rgb("#EFF1F5"), stroke: 0.5pt + rgb("#CFDDF0"), radius: 4pt, inset: 10pt, above: 12pt, below: 12pt)[ #block(below: 6pt)[#box(fill: BLUE, inset: (x: 6pt, y: 2pt), radius: 2pt, text(fill: white, weight: "bold", size: 8.5pt, label)) #h(0.4em) #strong[#title]] #body] // rail = decorative left rule (raw brand token); labelcolor = AA-safe label text shade #let notebox(label, rail, labelcolor, tint, body) = block(width: 100%, breakable: true, fill: tint, stroke: (left: 3pt + rail), inset: (left: 10pt, rest: 8pt), radius: (right: 4pt), above: 11pt, below: 11pt)[ #text(fill: labelcolor, weight: "bold", size: 7.5pt, tracking: 0.5pt)[#upper(label)] #linebreak() #body] #let solutionbox(body) = block(above: 4pt, below: 8pt)[ #text(fill: BLUE, weight: "bold", size: 8.5pt)[Solution] #linebreak() #body] #let figph(msg) = block(width: 100%, height: 60pt, fill: rgb("#f6f7f9"), stroke: (paint: rgb("#c7ccd3"), dash: "dashed"), radius: 4pt, inset: 10pt)[ #align(center + horizon, text(fill: rgb("#889"), style: "italic", size: 9pt, msg))] // Standardize inlined figure sizes: measure the natural CeTZ canvas, then scale to a // consistent envelope (aspect-aware; see build_typst.py FIG_* constants). Unlike the // print preamble, dimensions are FLOORED: in an editor a user can trim a figure to a // degenerate 1-D shape (a bare line), and w/h or tw/w would then divide by zero. #let _STD_W = 3.5 #let _WIDE_W = 5.6 #let _MAX_H = 3.4 #let _ASPECT_WIDE = 2.2 #let _UPSCALE_MAX = 1.15 #let stdfig(body) = context { let m = measure(body) let w = calc.max(m.width / 1in, 0.01) let h = calc.max(m.height / 1in, 0.01) let tw = if w / h > _ASPECT_WIDE { _WIDE_W } else { _STD_W } let s = calc.min(tw / w, _MAX_H / h, _UPSCALE_MAX) align(center, box(scale(x: s * 100%, y: s * 100%, reflow: true, body))) } #show figure: set block(breakable: false) #set figure(gap: 8pt) #show figure.caption: set text(size: 8.5pt, fill: rgb("#555")) == 12.10#h(0.6em)Conclusion - Simple Linear Regression A #strong[lurking variable] is a variable other than the independent or dependent variables that may influence the regression line. For instance, the highly correlated ice cream sales and home burglary rates probably have to do with the season. Hence, linear regression does not imply cause and effect. Two variables are #strong[confounded] when their effects on the dependent variable cannot be distinguished from each other. For instance, if we are looking at diet predicting weight, a confounding variable would be age. As a person gets older, they can gain more weight with fewer calories compared to when they were younger. Another example would be predicting someone’s midterm score from hours studied for the exam. Some confounding variables would be GPA, IQ score, and teacher’s difficultly level. === Assumptions for Linear Regression There are assumptions that need to be met when running simple linear regression. If these assumptions are not met, then one should use more advanced regression techniques. The assumptions for simple linear regression are: - The data need to follow a linear pattern. - The observations of the dependent variable y are independent of one another. - Residuals are approximately normally distributed. - The variance of the residuals is constant. Most software packages will plot the residuals for each #math.equation(block: false, alt: "x")[$x$] on the #math.equation(block: false, alt: "y")[$y$]-axis against either the #math.equation(block: false, alt: "x")[$x$]-variable or #math.equation(block: false, alt: "y hat")[$hat(y)$] along the #math.equation(block: false, alt: "x")[$x$]-axis. This plot is called a residual plot. Residual plots help determine some of these assumptions. #examplebox("Example 1")[][ Use technology to compute the residuals and make a residual plot for the hours studied and exam grade data. Hours Studied for Exam 20 16 20 18 17 16 15 17 15 16 15 17 16 17 14 Grade on Exam 89 72 93 84 81 75 70 82 69 83 80 83 81 84 76 #solutionbox[ Plot the residuals. #strong[TI-84:] Find the least-squares regression line as described in the previous section. Press \[Y=\] and clear any equations that are in the #math.equation(block: false, alt: "y")[$y$]-editor. Press \[2nd\] then \[STAT PLOT\] then press 1 or hit \[ENTER\] to select #strong[Plot1]. Select #strong[On] and press \[ENTER\] to activate plot 1. For “Type” select the first graph that looks like a scatterplot and press \[ENTER\]. For “Xlist” enter whichever list where your explanatory variable data is stored. For our example, enter L#sub[1]. For “Ylist” press \[2nd\] \[LIST\] then scroll down to RESID and press \[ENTER\]. The calculator automatically computes the residuals and stores them in a list called #strong[RESID]. Press \[ZOOM\] then press 9 or scroll down to #strong[ZoomStat] and press \[ENTER\]. #figure(figph[Using the TI-84 to activate Plot 1, select ZoomStat from the Zoom menu, and view the plotted residuals.], alt: "Using the TI-84 to activate Plot 1, select ZoomStat from the Zoom menu, and view the plotted residuals.", caption: none) #strong[TI-89:] Find the least-squares regression line as described in the previous section. Press \[♦\] then \[F1\] (Y=) and clear any equations that are in the #math.equation(block: false, alt: "y")[$y$]-editor. In the #strong[Stats/List Editor] select F2 for the #strong[Plots] menu. Use cursor keys to highlight #strong[1:Plot Setup]. Make sure that the other graphs are turned off by pressing F4 button to remove the check marks. Under “Plot 2” press F1 for the #strong[Define] menu. In the “Plot Type” menu select “Scatter.” In the “x” space type in the name of your list with the x variable without space, for our example “list1.” In the “y” space press \[2ND\] \[-\] for the #strong[VAR-LINK] menu. Scroll down the list and find “resid” in the “STATVARS” menu. Press \[ENTER\] twice and you will be returned to the #strong[Plot Setup] menu. Press F5 #strong[ZoomData] to display the graph. Press F3 #strong[Trace] and use the arrow keys to scroll along the different points. #figure(figph[Using the TI-89 calculator to enter the PlotSetup menu and select Plot 2 to plot the residuals. Viewing the plotted residuals.], alt: "Using the TI-89 calculator to enter the PlotSetup menu and select Plot 2 to plot the residuals. Viewing the plotted residuals.", caption: none) #strong[Excel:] Run the regression the same as in the last section when testing to see if there is a significant correlation. Type the data into two columns in Excel. Select the Data tab, then Data Analysis, then choose Regression and select OK. #figure(figph[Entering the given data in two adjacent columns in Excel, and selecting the "Regression" option from the Data Analysis menu.], alt: "Entering the given data in two adjacent columns in Excel, and selecting the \"Regression\" option from the Data Analysis menu.", caption: none) Be careful here, the second column is the #math.equation(block: false, alt: "y")[$y$] range, and the first column is the #math.equation(block: false, alt: "x")[$x$] range. Only check the Labels box if you highlight the labels in the input range. The output range is one cell reference where you want the output to start. Check the residuals, residual plots and normal probability plots, then select OK. #figure(figph[Regression pop-up window in Excel, with an input Y range of B1 to B16, an input X range of A1 to A16, the Labels option checked, and the Residuals, Residual Plots, and Normal Probability Plots options checked.], alt: "Regression pop-up window in Excel, with an input Y range of B1 to B16, an input X range of A1 to A16, the Labels option checked, and the Residuals, Residual Plots, and Normal Probability Plots options checked.", caption: none) Figure 12-21 shows the Excel Output. #figure(figph[Excel-generated output for the regression, consisting of a regression statistics table, ANOVA table, and a table of coefficients, standard error, the t-statistic, and the P-value for the intercept and the hours studied for the exam.], alt: "Excel-generated output for the regression, consisting of a regression statistics table, ANOVA table, and a table of coefficients, standard error, the t-statistic, and the P-value for the intercept and the hours studied for the exam.", caption: [Figure 12-21: Output for running a regression in Excel.]) Additional output from Excel gives the residuals, residual plot, and normal probability plot; see below. #figure(figph[Excel-generated Residual Output table, consisting of columns for observation, predicted grade on exam, and residuals.], alt: "Excel-generated Residual Output table, consisting of columns for observation, predicted grade on exam, and residuals.", caption: none) #figure(figph[Excel-generated scatterplot of residuals vs hours studied for the exam, and the normal probability plot for the given data.], alt: "Excel-generated scatterplot of residuals vs hours studied for the exam, and the normal probability plot for the given data.", caption: none) With this additional output, you can check the assumptions about the residuals. The residual plot is random and the normal probability plot forms an approximately straight line. ] ] === Putting It All Together #examplebox("Example 2")[][ High levels of hydrogen sulfide #math.equation(block: false, alt: "open parenthesis H sub 2 S close parenthesis")[$( H_(2) S )$] in the ocean can be harmful to animal life. It is expensive to run tests to detect these levels. A scientist would like to see if there is a relationship between sulfate #math.equation(block: false, alt: "open parenthesis S O sub 4 close parenthesis")[$( attach(upright(S) upright(O), b: 4) )$] and #math.equation(block: false, alt: "H sub 2 S")[$H_(2) S$] levels, since #math.equation(block: false, alt: "S O sub 4")[$attach(upright(S) upright(O), b: 4)$] is much easier and less expensive to test in ocean water. A sample of #math.equation(block: false, alt: "S O sub 4")[$attach(upright(S) upright(O), b: 4)$] and #math.equation(block: false, alt: "H sub 2 S")[$H_(2) S$] were recorded together at different depths in the ocean. The sample is reported below in millimolar (mM). If there were a significant relationship, the scientist would like to predict the #math.equation(block: false, alt: "H sub 2 S")[$H_(2) S$] level when the ocean has an #math.equation(block: false, alt: "S O sub 4")[$attach(upright(S) upright(O), b: 4)$] level of 25 mM. Run a complete regression analysis and check the assumptions. If the model is significant, then find the 95% prediction interval to predict the sulfide level in the ocean when the sulfate level is 25 mM. #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Run the capstone regression end to end] The first link preloads the sulfate/sulfide ocean data - read the negative-slope equation y-hat = 2.4359 - 0.077x and r. The second shades the F(1, 8) tail above the test statistic 14.228 for the book's p-value 0.00545; the third is the invT read (df 8) that gives the 2.306 multiplier in the 95% prediction interval. - Sulfate vs sulfide: y-hat = 2.4359 - 0.077x - p-value: P(F \> 14.228) = 0.00545 - invT(0.975, df 8) = 2.306 ] Sulfate 22.5 27.5 24.6 27.3 23.1 24 24.5 28.4 25.1 24.4 Sulfide 0.6 0.3 0.6 0.4 0.7 0.5 0.7 0.2 0.3 0.7 #solutionbox[ Start with a scatterplot to see if a linear relation exists. #figure(figph[Scatterplot of the given data, with sulfide level in millimolar on the y-axis and sulfate level in millimolar on the x-axis.], alt: "Scatterplot of the given data, with sulfide level in millimolar on the y-axis and sulfate level in millimolar on the x-axis.", caption: [Figure 12-22: Scatterplot of sulfide and sulfate level data.]) The scatterplot in Figure 12-22 shows a negative linear relationship. Test to see if the linear relationship is statistically significant. Use #math.equation(block: false, alt: "α")[$α$] = 0.05. You could use an F- or a t-test. I would recommend the t-test if you are using a TI calculator and an F-test if you are using a computer program like Excel or SPSS. We will do the F-test for the following example. The hypotheses are: #math.equation(block: true, alt: "H sub 0 : β sub 1 equals 0")[$H_(0) : β_(1) = 0$] #linebreak() #math.equation(block: true, alt: "H sub 1 : β sub 1 not equal to 0")[$H_(1) : β_(1) ≠ 0$] Compute the sum of squares. #math.equation(block: true, alt: "S S sub x x equals open parenthesis n minus 1 close parenthesis s sub x squared equals open parenthesis 10 minus 1 close parenthesis 1.959138 squared equals 34.544")[$S S_(x x) = ( n − 1 ) s_(x)^(2) = ( 10 − 1 ) 1.959138^(2) = 34.544$] #linebreak() #math.equation(block: true, alt: "S S sub y y equals open parenthesis n minus 1 close parenthesis s sub y squared equals open parenthesis 10 minus 1 close parenthesis 0.188561 squared equals 0.32")[$S S_(y y) = ( n − 1 ) s_(y)^(2) = ( 10 − 1 ) 0.188561^(2) = 0.32$] #linebreak() #math.equation(block: true, alt: "S S sub x y equals ∑ open parenthesis x y close parenthesis minus n times x bar times y bar equals 123.04 minus 10 times 25.14 times times 0.5 equals minus 2.66")[$S S_(x y) = ∑ ( x y ) − n · overline(x) · overline(y) = 123.04 − 10 · 25.14 · · 0.5 = − 2.66$] Next, compute the test statistic. #math.equation(block: true, alt: "S S R equals the fraction open parenthesis S S sub x y close parenthesis squared over S S sub x x equals the fraction minus 2.66 squared over 34.544 equals 0.2048286 S S T equals S S sub y y equals 0.32; S S E equals S S T minus S S R equals 0.32 minus 0.2048286 equals 0.1151714; d f sub T equals n minus 1 equals 9 d f sub E equals n minus p minus 1 equals 10 minus 1 minus 1 equals 8; M S R equals the fraction S S R over p equals the fraction 0.24829 over 1 equals equals 0.204829 S E equals the fraction S S E over n minus p minus 1 equals the fraction 0.115171 over 8 equals 0.014396; F equals the fraction M S R over M S E equals the fraction 0.204829 over 0.014396 equals 14.228")[$S S R = frac(attach(( S S_(x y) ), t: 2), S S_(x x)) = frac(− 2.66^(2), 34.544) = 0.2048286 #h(1em) #h(1em) #h(1em) #h(1em) S S T = S S_(y y) = 0.32 \ S S E = S S T − S S R = 0.32 − 0.2048286 = 0.1151714 \ d f_(T) = n − 1 = 9 d f_(E) = n − p − 1 = 10 − 1 − 1 = 8 \ M S R = frac(S S R, p) = frac(0.24829, 1) = = 0.204829 S E = frac(S S E, n − p − 1) = frac(0.115171, 8) = 0.014396 \ F = frac(M S R, M S E) = frac(0.204829, 0.014396) = 14.228$] #figure(figph[ANOVA table filled in with the values calculated above.], alt: "ANOVA table filled in with the values calculated above.", caption: none) Compute the p-value. This is a right-tailed F-test with #math.equation(block: false, alt: "d f equals 1 , 8")[$d f = 1 , 8$], which gives a p-value of =F.DIST.RT(14.2277,1,8) = 0.00545. We could also use Excel to generate the p-value. #figure(figph[Excel-generated ANOVA table for the given data, showing a p-value of 0.00545.], alt: "Excel-generated ANOVA table for the given data, showing a p-value of 0.00545.", caption: none) The p-value = 0.00545 \< #math.equation(block: false, alt: "α")[$α$] = 0.05; therefore, reject #math.equation(block: false, alt: "H sub 0")[$H_(0)$]. There is a statistically significant linear relationship between hydrogen sulfide and sulfate levels in the ocean. From the linear regression, check the assumptions and make sure there are no outliers. The standardized residuals are between #math.equation(block: false, alt: "minus 2")[$− 2$] and #math.equation(block: false, alt: "2")[$2$], and the scatterplot does not indicate any outliers. #figure(figph[Excel-generated table of standard residuals for the data, showing values ranging from -1.79521 to 1.332336.], alt: "Excel-generated table of standard residuals for the data, showing values ranging from -1.79521 to 1.332336.", caption: none) The Normal Probability Plot in Figure 12-23 forms an approximately straight line. This indicates that the residuals are approximately normally distributed. #figure(figph[Excel-generated normal probability plot for the given data, which takes a roughly linear form.], alt: "Excel-generated normal probability plot for the given data, which takes a roughly linear form.", caption: [Figure 12-23: Normal probability plot.]) The residual plot in Figure 12-24 has no unusual pattern. This indicates that a linear model would work well for this data. #figure(figph[Excel-generated sulfate residual plot. Points are clustered around x=25, with y-values ranging from 0.15 to -0.2.], alt: "Excel-generated sulfate residual plot. Points are clustered around x=25, with y-values ranging from 0.15 to -0.2.", caption: [Figure 12-24: Sulfate residual plot.]) Now find and use the regression equation to calculate the 95% prediction interval to predict the sulfide level in the ocean when the sulfate level is 25 mM. \# Capstone in four lines: sulfate (x) predicting sulfide (y) in ocean water sulfate \<- c(22.5,27.5,24.6,27.3,23.1,24,24.5,28.4,25.1,24.4) sulfide \<- c(0.6,0.3,0.6,0.4,0.7,0.5,0.7,0.2,0.3,0.7) fit \<- lm(sulfide ~ sulfate) summary(fit) \# F = 14.23 (df 1, 8), p = 0.00545; y-hat = 2.4359 - 0.077x; s = 0.11998 predict(fit, data.frame(sulfate = 25), interval = "prediction") \# 0.5108 with 95% PI \[0.2205, 0.8010\] Find the regression equation. Calculate the slope: #math.equation(block: false, alt: "b sub 1 equals the fraction S S sub x y over S S sub x x equals the fraction minus 2.66 over 34.544 equals minus 0.077")[$b_(1) = frac(S S_(x y), S S_(x x)) = frac(− 2.66, 34.544) = − 0.077$]. Then calculate the #math.equation(block: false, alt: "y")[$y$]-intercept: #math.equation(block: false, alt: "b sub 0 equals y bar minus b sub 1 times x bar equals 0.5 minus open parenthesis minus 0.077 close parenthesis times 25.14 equals 2.43586")[$b_(0) = overline(y) − b_(1) · overline(x) = 0.5 − ( − 0.077 ) · 25.14 = 2.43586$]. Put the numbers back into the regression equation and write your answer as: #math.equation(block: false, alt: "y hat equals 2.4359 plus open parenthesis minus 0.077 close parenthesis x")[$hat(y) = 2.4359 + ( − 0.077 ) x$] or as #math.equation(block: false, alt: "y hat equals 2.4359 minus 0.077 x")[$hat(y) = 2.4359 − 0.077 x$]. We can use technology to get the regression equation. Coefficients are found in the first column in the computer output. #figure(figph[Excel-generated regression analysis table.], alt: "Excel-generated regression analysis table.", caption: none) We would expect variation in our predicted value every time a new sample is used. Find the 95% prediction interval to estimate the sulfide level when the sulfate level is 25 mM. Use the prediction interval equation #math.equation(block: false, alt: "y hat ± t sub α / 2 times s the square root of open parenthesis 1 plus the fraction 1 over n plus the fraction open parenthesis x minus x bar close parenthesis squared over S S sub x x close parenthesis")[$hat(y) ± t_(α / 2) · s sqrt(( 1 + frac(1, n) + frac(attach(( x − overline(x) ), t: 2), S S_(x x)) ))$]. Substitute #math.equation(block: false, alt: "x equals 25")[$x = 25$] into the equation to get #math.equation(block: false, alt: "y hat equals 2.43586 minus 0.0770032 times 25 equals 0.51078")[$hat(y) = 2.43586 − 0.0770032 · 25 = 0.51078$]. To find #math.equation(block: false, alt: "t sub α / 2")[$t_(α / 2)$] use your calculator's invT with #math.equation(block: false, alt: "d f sub E equals n minus 2 equals 8")[$d f_(E) = n − 2 = 8$] and left-tail area #math.equation(block: false, alt: "the fraction α over 2 equals the fraction 0.05 over 2 equals 0.025")[$frac(α, 2) = frac(0.05, 2) = 0.025$], gives #math.equation(block: false, alt: "t sub 0.025 equals ± 2.306004")[$t_(0.025) = ± 2.306004$]. #figure(figph[Finding the linear regression t-interval using a TI-89 calculator.], alt: "Finding the linear regression t-interval using a TI-89 calculator.", caption: none) The standard error of estimate #math.equation(block: false, alt: "s equals the square root of M S E equals the square root of 0.014396 equals 0.11998")[$s = sqrt(M S E) = sqrt(0.014396) = 0.11998$], which can also be found using technology. #figure(figph[Excel-generated table of regression statistics for the given data, including standard error of 0.119985.], alt: "Excel-generated table of regression statistics for the given data, including standard error of 0.119985.", caption: none) From the earlier descriptive statistics, we have #math.equation(block: false, alt: "n equals 10")[$n = 10$], #math.equation(block: false, alt: "x bar equals 25.14")[$overline(x) = 25.14$], #math.equation(block: false, alt: "S S sub x x equals 34.544")[$S S_(x x) = 34.544$]. Substitute each of these values into the prediction interval to get the following: #math.equation(block: true, alt: "0.51078 ± 2.306004 times 0.119985 the square root of open parenthesis 1 plus the fraction 1 over 10 plus the fraction open parenthesis 25 minus 25.14 close parenthesis squared over 34.544 close parenthesis")[$0.51078 ± 2.306004 · 0.119985 sqrt(( 1 + frac(1, 10) + frac(( 25 − 25.14 )^(2), 34.544) ))$] #math.equation(block: true, alt: "0.51078 ± 0.290265")[$0.51078 ± 0.290265$] #math.equation(block: true, alt: "0.2205 less than y less than 0.8010")[$0.2205 < y < 0.8010$] We can be 95% confident that the true sulfide level in the ocean will be between 0.2205 and 0.801 mM when the sulfate level is 25 mM. ] ] === Summary A simple linear regression should only be performed if you observe visually that there is a linear pattern in the scatterplot and that there is a statistically significant correlation between the independent and dependent variables. Use technology to find the numeric values for the #math.equation(block: false, alt: "y")[$y$]-intercept = #math.equation(block: false, alt: "a equals b sub 0")[$a = b_(0)$] and slope = #math.equation(block: false, alt: "b equals b sub 1")[$b = b_(1)$], then make sure to use the correct notation when substituting your numbers back in the regression equation #math.equation(block: false, alt: "y hat equals b sub 0 plus b sub 1 x")[$hat(y) = b_(0) + b_(1) x$]. Another measure of how well the line fits the data is called the coefficient of determination #math.equation(block: false, alt: "R squared")[$R^(2)$]. When #math.equation(block: false, alt: "R squared")[$R^(2)$] is close to 1 (or 100%), then the line fits the data very closely. The advantage over using #math.equation(block: false, alt: "R squared")[$R^(2)$] over #math.equation(block: false, alt: "r")[$r$] is that we can use #math.equation(block: false, alt: "R squared")[$R^(2)$] for nonlinear regression, whereas #math.equation(block: false, alt: "r")[$r$] is only for linear regression. One should always check the assumptions for regression before using the regression equation for prediction. Make sure that the residual plots have a completely random horizontal band around zero. There should be no patterns in the residual plots such as a sideways V that may indicate a non-constant variance. A pattern like a slanted line, a U, or an upside-down U shape would suggest a non-linear model. Check that the residuals are normally distributed; this is not the same as the population being normally distributed. Check to make sure that there are no outliers. Be careful with lurking and confounding variables.