#set document(title: "4.4 Analysis of Variance (ANOVA)", author: "OpenStax / XYZ Homework") #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")) == 4.4#h(0.6em)Analysis of Variance (ANOVA) === Learning Outcomes By the end of this section, you should be able to: - Set up and apply one-way analysis of variance hypothesis test. - Use Python to conduct one-way analysis of variance. In Testing Claims Based on One Sample, we reviewed methods to conduct hypothesis testing for two means; however, there are scenarios where a researcher might want to compare three or more means to determine if any of the means are different from one another. For example, a medical researcher might want to compare three different pain relief medications to compare the average time to provide relief from a migraine headache. #strong[Analysis of variance (ANOVA)] is a statistical method that allows a researcher to compare three or more means and determine if the means are all statistically the same or if at least one mean is different from the others. The #strong[one-way ANOVA] focuses on one independent variable. For two independent variables, a method called “two-way ANOVA” is applicable, but this method is beyond the scope of this text. We explore the one-way ANOVA next. === One-Way ANOVA To compare three or more means, the sample sizes for each group can be different sample sizes (samples sizes do not need to be identical). For one-way ANOVA hypothesis testing, we will follow the same general outline of steps for hypothesis testing that was discussed in Hypothesis Testing. The first step will be to write the null and alternative hypotheses. For one-way ANOVA, the null and alternative hypotheses are always stated as the following: #math.equation(block: false, alt: "H sub 0")[$H_(0)$]: All population means are equal: #math.equation(block: false, alt: "µ sub 1 equals µ sub 2 equals µ sub 3 equals and so on")[$µ_(1) = µ_(2) = µ_(3) = …$] #math.equation(block: false, alt: "H sub a")[$H_(a)$]: At least one population mean is different from the others. Here are the requirements to use this procedure: + The samples are random and selected from approximately normal distributions. + The samples are independent of one another. + The population variances are approximately equal. In this discussion, we assume that the population variances are not equal. When these requirements are met, the #emph[F]-distribution is used as the basis for conducting the hypothesis test. The #strong[#emph[F]-distribution] is a skewed distribution (skewed to the right), and the shape of the distribution depends on two different degrees of freedom, referred to as degrees of freedom for the numerator and degrees of freedom for the denominator. shows the typical shape of the F-distribution: #figure(figph[A graph showing a nonsymmetrical F distribution curve. The horizontal axis extends from 0 to 4.5 and the vertical axis ranges from 0 to 1. The curve is skewed to the right.], alt: "A graph showing a nonsymmetrical F distribution curve. The horizontal axis extends from 0 to 4.5 and the vertical axis ranges from 0 to 1. The curve is skewed to the right.", caption: [Shape of the #emph[F]-Distribution]) The test statistic for this hypothesis test will be the ratio of two variances, namely the ratio of the variance between samples to the ratio of the variances within the samples. #math.equation(block: true, alt: "Test Statistic equals the fraction Variance between samples over Variance within samples")[$"Test Statistic" #h(0.2em) = frac("Variance between samples", "Variance within samples")$] The numerator of the test statistic (variance between samples) is sometimes referred to as variation due to treatment or explained variation. The denominator of the test statistic (variance within samples) is sometimes referred to as variation due to error, or unexplained variation. The details for a manual calculation of the test statistic are provided next; however, it is very common to use software for ANOVA analysis. For the purposes of this discussion, we will assume we are comparing three means, but keep in mind the ANOVA method can be applied to three or more means. + Find the mean for each of the three samples. Label these means as #math.equation(block: false, alt: "x minus sub 1 , x minus sub 2 , x minus sub 3")[$limits(x)^(−)_(1) , limits(x)^(−)_(2) , limits(x)^(−)_(3)$]. Find the variance for each of the three samples. Label these variances as #math.equation(block: false, alt: "s 1 2 , s 2 2 , s 3 2")[$s_(1)^(2) , s_(2)^(2) , s_(3)^(2)$]. + Find the grand mean (label this as #math.equation(block: false, alt: "x =")[$limits(x)^("=")$]). This is the sum of all the data values from the three samples, divided by the overall sample size. + Calculate the quantity called “sum of squares between (SSB)” according to the following formula: #linebreak() #math.equation(block: true, alt: "S S B equals n sub 1 open parenthesis x minus sub 1 minus x = close parenthesis squared plus n sub 2 open parenthesis x minus sub 2 minus x = close parenthesis squared plus n sub 3 open parenthesis x minus sub 3 minus x = close parenthesis squared")[$S S B = n_(1) attach(( limits(x)^(−)_(1) − limits(x)^("=") ), t: 2) + n_(2) attach(( limits(x)^(−)_(2) − limits(x)^("=") ), t: 2) + n_(3) attach(( limits(x)^(−)_(3) − limits(x)^("=") ), t: 2)$] + Calculate the quantity called “sum of squares within (SSW)” according to the following formula: #linebreak() #math.equation(block: true, alt: "S S W equals open parenthesis n sub 1 minus 1 close parenthesis s 1 2 plus open parenthesis n sub 2 minus 1 close parenthesis s 2 2 plus open parenthesis n sub 3 minus 1 close parenthesis s 3 2")[$S S W = ( n_(1) − 1 ) s_(1)^(2) + ( n_(2) − 1 ) s_(2)^(2) + ( n_(3) − 1 ) s_(3)^(2)$] + Calculate the degrees of freedom for the numerator (#math.equation(block: false, alt: "d f sub n")[$attach(d f, b: n)$]) and degrees of freedom for the denominator (#math.equation(block: false, alt: "d f sub d")[$attach(d f, b: d)$]). #linebreak() For degrees of freedom for the numerator, this is calculated as the number of groups minus 1. For example, if a medical researcher is comparing three different pain relief medications to compare the average time to provide relief from a migraine headache, there are three groups, and thus the degrees of freedom for the numerator would be #math.equation(block: false, alt: "3 minus 1 equals 2")[$3 − 1 = 2$]. #linebreak() For degrees of freedom for the denominator, this is calculated as the total of the sample sizes minus the number of groups. + Calculate the quantity called “mean square between (MSB)” according to the following formula: #linebreak() #math.equation(block: true, alt: "M S B equals the fraction S S B over d f sub n")[$M S B = frac(S S B, attach(d f, b: n))$] + Calculate the quantity called “mean square within (MSW)” according to the following formula: #linebreak() #math.equation(block: true, alt: "M S W equals the fraction S S W over d f sub d")[$M S W = frac(S S W, attach(d f, b: d))$] + Calculate the test statistic (#math.equation(block: false, alt: "F")[$F$]), according to the following formula: #linebreak() #math.equation(block: true, alt: "F equals the fraction M S B over M S W")[$F = frac(M S B, M S W)$] Once the test statistic is obtained, the #emph[p]-value is calculated as the area to the right of the test statistic under the #math.equation(block: false, alt: "F")[$F$]-distribution curve (note that the ANOVA hypothesis test is always considered a “right-tail” test). Usually, the results of these computations are organized in an ANOVA summary table like . #figure(table( columns: 6, align: left, inset: 6pt, [#strong[Variation]], [#strong[Sum of Squares]], [#strong[Degrees of Freedom]], [#strong[Mean Squares]], [#strong[#math.equation(block: false, alt: "F")[$F$] Test Statistic]], [#strong[#emph[p]-value]], [Between], [SSB], [#math.equation(block: false, alt: "d f sub n")[$attach(d f, b: n)$]], [MSB], [#math.equation(block: false, alt: "the fraction M S B over M S W")[$frac(M S B, M S W)$]], [Area to the right of the F test statistic], [Within], [SSW], [#math.equation(block: false, alt: "d f sub d")[$attach(d f, b: d)$]], [MSW], [N/A], [], )) === Using Python for One-Way ANOVA As mentioned earlier, due to the complexity of these calculations, technology is typically used to calculate the test statistic and #emph[p]-value. Using Python, the #strong[f\_oneway()] function is provided as part of the #strong[scipy library], and this function provides both the test statistic and #emph[p]-value for a one-way ANOVA hypothesis test. The syntax is to call the function with the data arrays as arguments, as in: f\_oneway(Array1, Array2, Array3, …) The function returns both the F test statistic and the #emph[p]-value for the one-way ANOVA hypothesis test. The details of this Python function are shown in Example 1. Here is a step-by-step example to illustrate this ANOVA hypothesis testing process. #examplebox("Example 1")[][ An airline manager claims that the average arrival delays for flights from Boston to Dallas are the same for three airlines: Airlines A, B, and C. The following arrival delay data (in minutes) is collected on samples of flights for the three airlines : #figure(table( columns: 3, align: left, inset: 6pt, table.header([#strong[Airline A]], [#strong[Airline B]], [#strong[Airline C]]), [8], [13], [11], [12], [0], [15], [7], [2], [9], [9], [7], [11], [11], [6], [12], [4], [5], [N/A], )) Use this sample data to test the claim that the average arrival delays are the same for three airlines: Airlines A, B, and C. Use a level of significance of 0.05 for this analysis. Assume the samples are independent and taken from approximately normal distributions and each population has approximately the same variance. #solutionbox[ The first step in the hypothesis testing procedure is to write the null and alternative hypothesis based on the claim. For an ANOVA hypothesis test, the setup of the null and alternative hypotheses is shown here. Notice that the claim mentions “the average arrival delays are the same for three airlines,” which corresponds to the null hypothesis. #math.equation(block: false, alt: "H sub 0")[$H_(0)$]: All three population means are equal: #math.equation(block: false, alt: "µ sub A equals µ sub B equals µ sub C")[$µ_(A) = µ_(B) = µ_(C)$] \[Claim\] #math.equation(block: false, alt: "H sub a")[$H_(a)$]: At least one population mean is different from the others. The following Python program generates the corresponding F test statistic and #emph[p]-value for this ANOVA analysis: #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ \# import libraries import numpy as np from scipy.stats  import f\_oneway   \# enter airline arrival data AirlineA = np.array(\[8, 12, 7, 9, 11, 4\]) AirlineB = np.array(\[13, 0, 2, 7, 6, 5\]) AirlineC = np.array(\[11, 15, 9, 11, 12\]) \#f\_oneway function returns both the test statistic and p-value f\_oneway(AirlineA, AirlineB, AirlineC) The resulting output will look like this: F\_onewayResult(statistic=4.388264306955828, pvalue=0.03314999857295516) From this Python output, the test statistic is #math.equation(block: false, alt: "F equals 4.388")[$F = 4.388$] and the #emph[p]-value is 0.033. ] The final step in the hypothesis testing procedure is to come to a final decision regarding the null hypothesis. This is accomplished by comparing the #emph[p]-value with the level of significance. In this example, the #emph[p]-value is 0.033 and the level of significance is 0.05: since the #emph[p]-value #math.equation(block: false, alt: "less than")[$<$] level of significance, the decision is to “reject the null hypothesis.” Conclusion: The decision is to reject the null hypothesis. The claim corresponds to the null hypothesis. This scenario corresponds to the first row in and thus the conclusion is: There is enough evidence to reject the claim that the average arrival delays are the same for three airlines. This implies that at least one of the means is different from the others. Note: The ANOVA test method does not specify which mean is different from the others. Further statistical analysis is needed to make this determination. ] ] ==== Project A: Confidence Intervals Conduct a survey of students in your class or at your school to collect data on the number of hours worked per week by one or two predefined sociodemographic characteristics, such as gender, age, geographic neighborhood of residence, first-generation college student, etc. As a group, create 90% confidence intervals for the average number of hours worked for each category of students. Compare the confidence intervals and come to any relevant conclusions for the average number of hours worked by each category of students. ==== Project B: Hypothesis Testing As a group, develop a hypothesis for the proportion of white cars in your city. To collect sample data, go to your school parking lot or a nearby parking lot of some kind and determine the sample proportion of white cars. Then, use this data to conduct a hypothesis test for your original hypothesis. ==== Project C: Correlation and Regression Analysis For each student, collect data on shoe length and person’s height. Create a scatterplot of this #math.equation(block: false, alt: "open parenthesis x , y close parenthesis")[$( x , y )$] data and calculate the correlation coefficient. Test the correlation coefficient for significance. If the correlation is significant, develop a linear regression model to predict a person’s height based on shoe length. As a second assignment on the same subject, students should research a certain model car, such as Honda Accord or Toyota Camry. Search websites for used car prices for the selected model and record #math.equation(block: false, alt: "open parenthesis x , y close parenthesis")[$( x , y )$] data where #math.equation(block: false, alt: "x")[$x$] is the age of the car and #math.equation(block: false, alt: "y")[$y$] is the price of the car. Create a scatterplot of this #math.equation(block: false, alt: "open parenthesis x , y close parenthesis")[$( x , y )$] data and calculate the correlation coefficient. Test the correlation coefficient for significance. If the correlation is significant, develop a linear regression model to predict a car’s price based on age of the vehicle.