#set document(title: "16.3 Box-Cox", author: "OpenStax") #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")) == 16.3#h(0.6em)Box-Cox #notebox("Note", rgb("#8a94a6"), rgb("#556666"), rgb("#f7f8fa"))[ #emph[Prerequisites] This section assumes a higher level of mathematics background than most other sections of this work. Additional Measures of Central Tendency (Geometric Mean), Bivariate Data, Pearson Correlation, Logarithms, Tukey Ladder of Powers #linebreak() #linebreak() ] George Box and Sir David Cox collaborated on one paper (Box, 1964). The story is that while Cox was visiting Box at Wisconsin, they decided they should write a paper together because of the similarity of their names (and that both are British). In fact, Professor Box is married to the daughter of Sir Ronald Fisher. The Box-Cox transformation of the variable x is also indexed by λ, and is defined as #math.equation(block: true, alt: "x sub λ to the power ′ equals the fraction x to the power λ minus 1 over λ")[$x_(λ)^(′) = frac(x^(λ) − 1, λ)$]  (Equation 1) At first glance, although the formula in Equation (1) is a scaled version of the Tukey transformation x#super[λ], this transformation does not appear to be the same as the Tukey formula in Equation (2). However, a closer look shows that when λ \< 0, both x#sub[λ] and x′#sub[λ] change the sign of x#super[λ] to preserve the ordering. Of more interest is the fact that when λ = 0, then the Box-Cox variable is the indeterminate form 0/0. Rewriting the Box-Cox formula as #math.equation(block: true, alt: "x sub λ to the power ′ equals the fraction e to the power λ log open parenthesis x close parenthesis minus 1 over λ approximately equals the fraction open parenthesis 1 plus λ log open parenthesis x close parenthesis plus the fraction 1 over 2 λ squared log open parenthesis x close parenthesis squared plus ⋯ close parenthesis minus 1 over λ → log open parenthesis x close parenthesis")[$x_(λ)^(′) = frac(e^(λ log ( x )) − 1, λ) ≈ frac(( 1 + λ log ( x ) + frac(1, 2) λ^(2) log ( x )^(2) + ⋯ ) − 1, λ) → log ( x )$] as λ → 0. This same result may also be obtained using l'Hôpital's rule from your calculus course. This gives a rigorous explanation for Tukey's suggestion that the log transformation (which is not an example of a polynomial transformation) may be inserted at the value λ = 0. Notice with this definition of #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] that x = 1 always maps to the point #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] = 0 for all values of λ. To see how the transformation works, look at the examples in Figure 1. In the top row, the choice λ = 1 simply shifts x to the value x−1, which is a straight line. In the bottom row (on a semi-logarithmic scale), the choice λ = 0 corresponds to a logarithmic transformation, which is now a straight line. We superimpose a larger collection of transformations on a semi-logarithmic scale in Figure 2. #figure(figph[Six plots of the Box-Cox transformation of x for lambda = -1, 0 and 1, with a red point at (1, 0) in each. The top row plots the transformed value against x from 0.5 to 2: lambda = -1 is concave, lambda = 0 is gently concave, and lambda = 1 is exactly a straight line (x shifted to x - 1). The bottom row plots the same against log(x): now lambda = 0 is the straight line, lambda = -1 is concave and lambda = 1 is convex.], alt: "Six plots of the Box-Cox transformation of x for lambda = -1, 0 and 1, with a red point at (1, 0) in each. The top row plots the transformed value against x from 0.5 to 2: lambda = -1 is concave, lambda = 0 is gently concave, and lambda = 1 is exactly a straight line (x shifted to x - 1). The bottom row plots the same against log(x): now lambda = 0 is the straight line, lambda = -1 is concave and lambda = 1 is convex.", caption: [Figure 1. Examples of the Box-Cox transformation #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] versus x for λ = −1, 0, 1. In the second row, #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] is plotted against log(x). The red point is at (1, 0).]) #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] #figure(figph[Family of Box-Cox transformation curves plotted against x from 0.5 to 2 on a semi-logarithmic scale, one coloured curve for each lambda from 3 down to -2 in steps of 0.5, with a legend at the upper left. Every curve passes through the red point at (1, 0); above x = 1 they fan upward in order, the lambda = 3 curve highest at about 2.3 at x = 2 and the lambda = -2 curve lowest, and the order reverses below x = 1.], alt: "Family of Box-Cox transformation curves plotted against x from 0.5 to 2 on a semi-logarithmic scale, one coloured curve for each lambda from 3 down to -2 in steps of 0.5, with a legend at the upper left. Every curve passes through the red point at (1, 0); above x = 1 they fan upward in order, the lambda = 3 curve highest at about 2.3 at x = 2 and the lambda = -2 curve lowest, and the order reverses below x = 1.", caption: [Figure 2. Examples of the Box-Cox transformation #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] versus log(x) for −2 \< λ \< 3. The bottom curve corresponds to λ = −2 and the upper to λ = 3.]) #math.equation(block: false, alt: "x sub λ to the power ′")[$x_(λ)^(′)$] === Transformation to Normality Another important use of variable transformation is to eliminate skewness and other distributional features that complicate analysis. Often the goal is to find a simple transformation that leads to normality. In the article on q-q plots, we discuss how to assess the normality of a set of data, x#sub[1],x#sub[2],...,x#sub[n]. Data that are normal lead to a straight line on the q-q plot. Since the correlation coefficient is maximized when a scatter diagram is linear, we can use the same approach above to find the most normal transformation. Specifically, we form the n pairs #math.equation(block: true, alt: "open parenthesis Φ to the power minus 1 open parenthesis the fraction i minus 0.5 over n close parenthesis , x sub open parenthesis i close parenthesis close parenthesis , for i equals 1 , 2 , … , n")[$( Φ^(− 1) thin ( frac(i − 0.5, n) ) , #h(0.167em) x_(( i )) ) , #h(1em) "for " i = 1 , 2 , … , n$] where Φ#super[−1] is the inverse CDF of the normal density and x#sub[(i)] denotes the i#super[th] sorted value of the data set. As an example, consider a large sample of British household incomes taken in 1973, normalized to have mean equal to one (n = 7125). Such data are often strongly skewed, as is clear from Figure 3. The data were sorted and paired with the 7125 normal quantiles. The value of λ that gave the greatest correlation (r = 0.9944) was λ = 0.21. #figure(figph[Two panels for the 1973 British household income data (n = 7125, normalised to mean 1). Left: a kernel density plot of Density against Income from 0 to 12, with a tall narrow peak of about 0.75 just below Income = 1 and a long thin right tail out past 10 — strongly positively skewed. Right: the correlation coefficient of the normal q-q pairs against lambda from -2 to 3, a smooth hump reaching almost 1.0 just to the right of the dashed line at lambda = 0; the best value is lambda = 0.21 with r = 0.9944.], alt: "Two panels for the 1973 British household income data (n = 7125, normalised to mean 1). Left: a kernel density plot of Density against Income from 0 to 12, with a tall narrow peak of about 0.75 just below Income = 1 and a long thin right tail out past 10 — strongly positively skewed. Right: the correlation coefficient of the normal q-q pairs against lambda from -2 to 3, a smooth hump reaching almost 1.0 just to the right of the dashed line at lambda = 0; the best value is lambda = 0.21 with r = 0.9944.", caption: [Figure 3. (L) Density plot of the 1973 British income data. (R) The best value of λ is 0.21.]) The kernel density plot of the optimally transformed data is shown in the left frame of Figure 4. While this figure is much less skewed than in Figure 3, there is clearly an extra "component" in the distribution that might reflect the poor. Economists often analyze the logarithm of income corresponding to λ = 0; see Figure 4. The correlation is only r = 0.9901 in this case, but for convenience, the log-transform probably will be preferred. #figure(figph[Two kernel density plots of the transformed 1973 British income data. Left: transformed with the optimal lambda = 0.21, on an Income axis from -3 to 3 — a near-symmetric peak of about 0.72 at 0 with a small shoulder near -1. Right: the log transform, lambda = 0, on an axis from -4 to 2 — a similar peak but with a slightly longer left tail (r = 0.9901). Both are far less skewed than the raw data, and both retain the extra low-income shoulder.], alt: "Two kernel density plots of the transformed 1973 British income data. Left: transformed with the optimal lambda = 0.21, on an Income axis from -3 to 3 — a near-symmetric peak of about 0.72 at 0 with a small shoulder near -1. Right: the log transform, lambda = 0, on an axis from -4 to 2 — a similar peak but with a slightly longer left tail (r = 0.9901). Both are far less skewed than the raw data, and both retain the extra low-income shoulder.", caption: [Figure 4. (L) Density plot of the 1973 British income data transformed with λ = 0.21. (R) The log-transform with λ = 0.]) === Other Applications Regression analysis is another application where variable transformation is frequently applied. For the model #math.equation(block: true, alt: "y equals β sub 0 plus β sub 1 x sub 1 plus β sub 2 x sub 2 plus ⋯ plus β sub p x sub p plus ϵ")[$y = β_(0) + β_(1) x_(1) + β_(2) x_(2) + ⋯ + β_(p) x_(p) + ϵ$] and fitted model #math.equation(block: true, alt: "y hat equals b sub 0 plus b sub 1 x sub 1 plus b sub 2 x sub 2 plus ⋯ plus b sub p x sub p")[$hat(y) = b_(0) + b_(1) x_(1) + b_(2) x_(2) + ⋯ + b_(p) x_(p)$] each of the predictor variables x#sub[j] can be transformed. The usual criterion is the variance of the residuals, given by #math.equation(block: true, alt: "the fraction 1 over n ∑ sub i equals 1 to the power n open parenthesis y hat sub i minus y sub i close parenthesis squared")[$frac(1, n) ∑_(i = 1)^(n) ( hat(y)_(i) − y_(i) )^(2)$] Occasionally, the response variable y may be transformed. In this case, care must be taken because the variance of the residuals is not comparable as λ varies. Let #math.equation(block: false, alt: "g bar sub y")[$overline(g)_(y)$]represent the geometric mean of the response variables. #math.equation(block: true, alt: "g bar sub y equals open parenthesis ∏ sub i equals 1 to the power n y sub i close parenthesis to the power 1 / n")[$overline(g)_(y) = attach(( ∏_(i = 1)^(n) y_(i) ), t: 1 / n)$] Then the transformed response is defined as #math.equation(block: true, alt: "y sub λ to the power ′ equals the fraction y to the power λ minus 1 over λ times g bar sub y to the power λ minus 1")[$y_(λ)^(′) = frac(y^(λ) − 1, λ · overline(g)_(y)^(λ − 1))$] When λ = 0 (the logarithmic case), #math.equation(block: true, alt: "y sub 0 to the power ′ equals g bar sub y times log open parenthesis y close parenthesis")[$y_(0)^(′) = overline(g)_(y) · log ( y )$] For more examples and discussions, see Kutner, Nachtsheim, Neter, and Li (2004). #linebreak() === References Box, G. E. P. and Cox, D. R. (1964). An analysis of transformations, #emph[Journal of the Royal Statistical Society], Series B, #emph[26], 211-252. Kutner, M., Nachtsheim, C., Neter, J., and Li, W. (2004). #emph[Applied Linear Statistical Models], McGraw-Hill/Irwin, Homewood, IL.