Foundations · The Valuation Engineer
"The Barrier to Human Understanding of MARS"
This is a supplement to the Foundations department, not a concept entry. Its title names a barrier the editor has come to recognize over years of indirect observation: appraisers who read a regression coefficient without difficulty stop at the list of hinge terms a MARS program prints, because nothing in that list looks like a rate. The four statistical entries that follow this supplement (Conditional Expectation, Omitted Variable Bias, Endogeneity and Parameter Identification) reason about the rate a regression assigns to a feature. The Journal’s own modeling uses multivariate adaptive regression splines (MARS; Friedman 1991)1, which report not one rate per feature but one per range, and the path from what a MARS program prints to the rate table an appraiser can defend has one step at which hand-built tables go wrong. This supplement gives the path, the step, and a program that walks it and checks its own work.
Formal definition
In a MARS model the fitted value is an intercept plus a sum of terms, each a coefficient times a product of hinge functions of the features. The fitted value is the model’s estimate of price. For one feature, with the others held fixed, it is a series of straight segments. The points where the segments meet are the knots. The graph of the feature’s value contribution over its range is the variable graph. Its slope in each range is the rate: the change in fitted value per unit of the feature in that range; the value contribution of a quantity of the feature is the sum of the model’s terms in that feature at that quantity; in the example all those terms are zero at 1,200 square feet, so the contribution is measured from there and is negative below it; a model need not have such a quantity, and only differences between contributions, which are adjustments, carry meaning; and the adjustment from a comparable to a subject is the amount added to the comparable’s contribution to make it equal to the subject’s, which is the sum, over the ranges between the two quantities, of rate times width. The rate so defined is the model’s; it is read as the rate the market pays only once the model has been accepted as a fair account of the sales, and the entries that follow this supplement are about when that acceptance is warranted.
Why this supplement exists
An appraiser who fits a MARS model, in earthUI (Craytor 2026) or directly in the R package earth (Milborrow 2024a), is handed a list of terms like these:
(Intercept) 1520000
h(1200-gla) -600
h(gla-1200) 1000
h(gla-2000) -250
h(gla-2800) -650
Nobody reports that. What goes into the sales grid is the adjustment: the subject’s value contribution less the comparable’s. The rates per square foot are discussed in the report, as a step in justifying the MARS model. The path from the printed terms to those numbers is short, but it has one step where hand-built tables go wrong, and the whole point of using a model is lost if the numbers it produces cannot be explained to a reviewer.
The plain version: four ranges, four rates
A linear regression that enters living area as one linear term gives one rate for it across the whole market; this is what regressions in traditional appraisal do, and it is what “ordinary regression” means in this supplement. MARS lets the rate change where the sales show it changing. In the coastal market of the example, living area may be worth $600 a square foot up to 1,200 square feet, $1,000 a square foot from 1,200 to 2,000, $750 from 2,000 to 2,800, and only $100 above that. That is the whole difference, and it is one an agent understands at once: the market pays most for the space that turns a small house into a family house, less for the next room, and almost nothing for space beyond what the neighborhood’s buyers want.
Given the rates, everything else is arithmetic an appraiser already does. A comparable with 1,800 square feet and a subject with 2,400 are 600 square feet apart, and the knot at 2,000 lies between them. The adjustment added to the comparable is the subject’s fitted value less the comparable’s, \(\$2{,}620{,}000 - \$2{,}120{,}000 = \$500{,}000\), which is also the subject’s living-area contribution less the comparable’s, \(\$1{,}100{,}000 - \$600{,}000\). The rates explain it: the move crosses 200 square feet at $1,000, then 400 square feet at $750, which is $500,000 in all. Figure 3 shows it, on a fitted value (the price the model gives a house with those features) that runs from $1,280,000 at 800 square feet, the smallest house in the data, to about $3 million at 3,500, the largest, most of the rise coming before 2,800.
The only rate a straight line through the two points could have used for that move is the one that connects them, $500,000 over 600 square feet, about $833 a square foot: the pair’s secant rate, the effective, or blended, rate for that one move: the average of the model’s rates weighted by the width of each range crossed. It is not one of the model’s rates, and it would be a different average for the next pair. An ordinary regression, with one rate for living area, has to serve every pair with that one number, so it cannot reproduce these pair-by-pair averages; that is what a single rate does: it averages over a change the model says the market makes.
A reader who stops here has the method: take the difference of the two contributions, then explain it by reading the rate on each range, walking the comparable to the subject at those rates, and adding. What follows is for the reader who wants to know why the rates are what they are, where the one trap lies, what changes when features interact, and how a program checks the arithmetic; the rate table and the adjustment do not change.
The refined version: hinges, and the sign that gets missed
Call the graph of a variable’s value contribution over its range the variable graph. It is not a curve in the everyday sense of something that bends smoothly; it is a segmented linear graph, straight between the knots and bending only at them. MARS builds it out of hinges; Friedman (1991) wrote them as truncated power functions, and “hinge” is the name the later literature settled on (Milborrow, n.d.); Hastie, Tibshirani and Friedman (2009, §9.4) call the two at one knot a “reflected pair”.
Definition (hinge). A hinge is a function of one variable \(x\) with a single break, called its knot \(t\), whose value is zero on one side of the knot and, on the other side, equal to the distance from the knot. There are two of them at any knot, one for each side, drawn in Figure 1: \[h(x-t) \;=\; \max(0,\; x - t) \;=\; \begin{cases} 0 & x \le t,\\ x - t & x > t, \end{cases} \qquad h(t-x) \;=\; \max(0,\; t - x) \;=\; \begin{cases} t - x & x < t,\\ 0 & x \ge t. \end{cases}\]
The first, \(h(x-t)\), is the right hinge: zero up to the knot and, beyond it, increasing from left to right. The second, \(h(t-x)\), is the reflected (or left) hinge: decreasing from left to right up to the knot, and zero at the knot and beyond it. Both are hinges in the same sense; they differ only in which side of the knot they are non-zero on. These directions describe the bare hinges, drawn from the \(x\) axis in Figure 1, and nothing more. In a model a hinge is multiplied by a coefficient, which may be negative, and added to other terms, so a term built on a right hinge can decrease from left to right and one built on a reflected hinge can increase, and the variable graph meets a knot at whatever height the other terms give it. Every direction stated in this supplement is read from left to right. Hinges are not used on their own. In a MARS model each hinge is multiplied by a coefficient and the terms are added, and it is from those coefficients, not from any single hinge, that the slopes of the model, the rates, are calculated: accumulatively, range by range, each range’s rate being the previous range’s rate adjusted by the coefficients of the hinges whose knot lies between them. The hinge is the only building block MARS has for a single variable; every bend in a variable graph is a knot of some hinge, and every straight stretch is a sum of terms that are either zero or linear there. The point to carry through everything that follows: the coefficient of a hinge is not a slope. It is an adjustment to the slope, the amount added, at that hinge’s knot, to the slope arriving from the left. Read from left to right, a variable graph starts at the rate of its first segment and each knot adjusts that rate by the coefficients sitting there. That is the whole reading rule, and Theorems 1 and 2 below are its proof. The model is the intercept plus each coefficient times its hinge, and the rate in any range is the slope of that sum.
Take the printed terms above; Figure 2 draws each of them with their sum and, beneath, the rate on each range, and Figure 3 shows how those rates explain the adjustment between a comparable and a subject. Knots at 1,200, 2,000 and 2,800 make four ranges. In each range, a right hinge is active if its knot lies at or to the left of the range, and a reflected hinge if its knot lies at or to the right of it — a right hinge acts in every range beyond its knot, a reflected hinge in every range before it. The rate is calculated from the coefficients of the active hinges: add the coefficients of the active right hinges and subtract the coefficients of the active reflected hinges. The table that results is the model’s rate on each range, the other features held at one set of values (the program uses the subject’s); in a model without interactions that qualification changes nothing, and in Case 2 below it changes everything:
| range (sf) | active hinges | rate ($/sf) |
|---|---|---|
| below 1,200 | \(h(1200-\mathrm{gla})\) only | \(-(-600) = \mathbf{+600}\) |
| 1,200 to 2,000 | \(h(\mathrm{gla}-1200)\) | \(\mathbf{1000}\) |
| 2,000 to 2,800 | \(h(\mathrm{gla}-1200)\), \(h(\mathrm{gla}-2000)\) | \(1000 - 250 = \mathbf{750}\) |
| above 2,800 | all three right hinges | \(1000 - 250 - 650 = \mathbf{100}\) |
The first row is the step that gets missed. A coefficient of \(-600\) on a reflected hinge is not a rate of \(-\$600\) a square foot. The hinge \(h(1200-\mathrm{gla})\) measures how far a house falls short of 1,200 square feet, and \(-600\) times that shortfall is a discount: $240,000 for an 800-square-foot house, shrinking to nothing at 1,200. Each added square foot removes $600 of the discount, so the rate is \(+\$600\). (With a positive coefficient the same hinge adds value for being smaller, and its rate is negative.) The rule, stated once: in a range, the rate is the sum of the coefficients of the active right hinges minus the sum of the coefficients of the active reflected hinges, plus the coefficient of a linear term (a feature entered as a straight line with no knot), if the model has one. One convention goes with it: exactly at a knot the rate is taken from the right, so that a right hinge counts from its knot onward and a reflected hinge only strictly below its knot; the rate at 1,200 square feet is therefore $1,000, the rate of the range that begins there, and the program reads it the same way.
The check that a table was built right is the fitted value at the knots. At 1,200 square feet every hinge is zero and the value is the intercept, $1,520,000; at 2,000 it is \(\$1{,}520{,}000 + 1{,}000 \times 800 = \$2{,}320{,}000\); at 2,800, \(\$2{,}320{,}000 + 750 \times 800 = \$2{,}920{,}000\); and at 800 square feet, the smallest house in the data, it is \(\$1{,}520{,}000 - 600 \times 400 = \$1{,}280{,}000\). From 800 to 1,200 the value rises $240,000, a rate of $600, which is the first row; a table that read the coefficient as the rate would have the value decreasing from left to right up to the knot at 1,200, and the values show it does not. Figure 2 draws the four hinges, their sum, and the rate in each range, with the coefficient \(-600\) marked where a reader might mistake it for the rate.
Two further complications the program handles and a hand table must:
Interactions. earth, in its forward pass (the stage that adds terms one at a time; Friedman 1991, §3), prints a product like \(h(\mathrm{gla}-1500)\times\mathrm{lot}\) when the rate for one feature depends on another: an interaction. The rate for lot then differs above and below 1,500 square feet of living area, and the rate table for one feature is always the table given the others, held at the subject’s values. The program takes a point, a value for every other feature, and computes every rate at it.
Level versus adjustment. The intercept and the terms in other features set the level the contribution is measured from; they cancel in every adjustment. The program reports contributions as the terms in the feature alone, so that two contributions differ by exactly the adjustment.
Two cases: models without and with interactions
The rule of the previous section can be stated as two theorems, proved below, and they give a clean answer to a question every reader of a MARS model asks sooner or later: how many of the printed terms does one rate actually depend on? The answer splits into two cases.
Case 1: no interactions
Setting. Let \(h(u) = \max(0, u)\) for real \(u\). A MARS model without interactions on the features \(x, z_1, \dots, z_q\) has fitted value
\[f(x, z_1, \dots, z_q) \;=\; \beta_0 + g(x) + \sum_{k=1}^{q} g_k(z_k),\]
where \(\beta_0\) is the intercept, each \(g_k\) is a function of \(z_k\) alone, and \(g\) collects every term in \(x\):
\[g(x) \;=\; c \cdot x \;+\; \sum_{j=1}^{K} a_j\, h(x - t_j) \;+\; \sum_{j=1}^{K} b_j\, h(t_j - x).\]
Here \(t_1 < t_2 < \cdots < t_K\) are the distinct knots of the hinges in \(x\); \(a_j\) is the coefficient of the right hinge at \(t_j\) and \(b_j\) that of the reflected hinge at \(t_j\), either being \(0\) when the model has no such term; and \(c\) is the coefficient of a bare linear term \(c \cdot x\), a feature entered as a straight line with no knot, which earth produces only for features named in linpreds or, for any feature, when Auto.linpreds is on (see the remark after Theorem 1); \(c = 0\) when there is no such term, as in every model of this supplement. Put \(t_0 = -\infty\) and \(t_{K+1} = +\infty\) and call \(S_i = (t_i, t_{i+1})\), for \(i = 0, 1, \dots, K\), the segments of \(x\); \(t_i\) is the left knot of \(S_i\) and \(t_{i+1}\) its right knot. On each \(S_i\) every summand of \(g\) is either identically zero or linear, so \(g\) is linear on \(S_i\); its slope there, which is also \(\partial f / \partial x\) on \(S_i\) because no other summand of \(f\) depends on \(x\), is the rate on \(S_i\) and is written \(r_i\). The rate table of \(x\) is the list \(r_0, r_1, \dots, r_K\). (If \(K = 0\) there is one segment, \((-\infty, +\infty)\), and the table is the single rate \(r_0 = c\).) At a knot itself \(g\) has no derivative: its left and right derivatives are \(r_{i-1}\) and \(r_i\), which differ by \(a_i + b_i\) (Theorem 2 below), so the value a rate table shows at \(t_i\) is a convention, taken here from the right, and not a value of \(g'\).
Theorem 1 (the rate on a segment). With the notation of the setting, for every \(i \in \{0, 1, \dots, K\}\), \[r_i \;=\; c \;+\; \sum_{j=1}^{i} a_j \;-\; \sum_{j=i+1}^{K} b_j ,\] an empty sum being \(0\). In particular \(r_i\) depends on at most \(K\) of the \(2K\) hinge coefficients, one per knot, together with \(c\).
Proof of Theorem 1. Fix \(i\) and a point \(x \in S_i\), so \(t_i < x < t_{i+1}\). Consider each summand of \(g\) on a neighborhood of \(x\) small enough to lie inside \(S_i\). The bare term \(c \cdot x\) has derivative \(c\). For the right hinge at \(t_j\): if \(j \le i\) then \(t_j \le t_i < x\), so \(h(x - t_j) = x - t_j\) on the neighborhood and its derivative is \(1\); if \(j \ge i+1\) then \(x < t_{i+1} \le t_j\), so \(h(x - t_j) = 0\) there and its derivative is \(0\). For the reflected hinge at \(t_j\): if \(j \ge i+1\) then \(x < t_j\), so \(h(t_j - x) = t_j - x\) and its derivative is \(-1\); if \(j \le i\) then \(t_j < x\), so \(h(t_j - x) = 0\) and its derivative is \(0\). A finite sum of functions differentiable at \(x\) is differentiable there with the sum of the derivatives, which gives \[g'(x) \;=\; c + \sum_{j \le i} a_j \cdot 1 + \sum_{j \ge i+1} a_j \cdot 0 + \sum_{j \le i} b_j \cdot 0 + \sum_{j \ge i+1} b_j \cdot (-1),\] the stated formula. For the count: the index sets \(\{j : j \le i\}\) and \(\{j : j \ge i+1\}\) are disjoint and together exhaust \(\{1, \dots, K\}\), so each knot \(t_j\) contributes exactly one of \(a_j\) and \(b_j\) and never both; hence at most \(K\) hinge coefficients enter, and \(r_i\) is the same at every point of \(S_i\). \(\blacksquare\)
The bound is attained: if \(b_j = 0\) for every \(j\), the rightmost segment \(S_K\) uses all \(K\) of the \(a_j\).
Remark (when \(c\) is not zero). earth can express a feature as a single straight line with no knot, the term \(c \cdot x\) of the setting, in two different ways, and the difference matters. linpreds, a list of named features such as linpreds = c("GLA"), forces each feature on the list to enter linearly, even when a fit with knots would be better; it is the analyst’s decision, and it can cost fit. Auto.linpreds, a single switch that is on by default, forces nothing: it only changes how earth writes a feature whose fit has turned out to be truly linear, a single hinge with its knot at the smallest observed value, by printing it as a coefficient and the variable name instead of as a hinge; the fit is the same. In either case earth prints the term as the bare variable name with its coefficient, 221.4 * GLA in earth’s summary form, as in the example below. Theorem 1 handles it through \(c\), which adds to the rate on every segment. For example, the call
mod_linear <- earth(
SalePrice ~ GLA + LotSize + BathrmCount + BedrmCount,
data = sales,
degree = 1,
linpreds = c("GLA", "LotSize", "BathrmCount", "BedrmCount")
)
enters every feature linearly (with degree = 1, so that no products of the linear terms are fitted either) and prints, in earth’s summary form (illustrative output, not a fitted model),
SalePrice =
179843
+ 221.4 * GLA
+ 11.8 * LotSize
+ 34872 * BathrmCount
+ 17641 * BedrmCount
For living area this is the setting with \(c = 221.4\) and no hinges, \(K = 0\): there is one segment, and Theorem 1 gives the single rate \(r_0 = c = \$221.40\) a square foot over the whole range of the data; lot size, bathrooms and bedrooms read the same way, at $11.80 a square foot of lot, $34,872 a bathroom and $17,641 a bedroom. Such a model is an ordinary regression in the sense of this supplement, one rate per feature. Over the data such a term is the same line as a single right hinge with its knot at the smallest observed value, and the Journal runs earth with Auto.linpreds = FALSE, so in its models a feature whose variable graph is straight over the data appears as that single hinge, h(gla-800) 700 for instance, the knot at the smallest house in the data, with \(c = 0\), \(K = 1\) and \(a_1 = 700\): the rate is \(0\) below the knot, on a stretch that holds no sales, and \(700\) above it, so the rate table over the data has one row. One corollary follows here; the change of rate at a knot is Theorem 2 below.
Corollary 1 (the reflected sign). A reflected hinge with coefficient \(b_j\) contributes \(-b_j\) to the rate on every segment to the left of \(t_j\) and \(0\) to the right. In the running example, \(b_1 = -600\) at \(t_1 = 1{,}200\) contributes \(+600\) to \(r_0\), which is the whole of the trap this supplement is built around.
Proof. Read off the second sum of Theorem 1. \(\blacksquare\)
A seven-knot example, and the assumption that defeats readers
The count matters because of an assumption almost everyone brings to a printed MARS model: that the coefficient printed beside a knot is the slope of the segment whose left knot it is. It is not. The coefficient of a hinge is an adjustment to the slope coming in from the left, not the slope itself, and the slope of a segment is therefore the slope of the first segment plus the running total of every such adjustment at its left knot and at every knot further left. A reader who holds the wrong assumption tries the arithmetic in their head, or in a small program or a spreadsheet formula, finds that the numbers do not reproduce the fitted values, and gives up, concluding that MARS is opaque. It is not opaque; it is cumulative.
Theorem 2 (the running total). With the notation of the setting of Case 1, for every \(i \in \{1, \dots, K\}\), \[r_i \;=\; r_{i-1} + a_i + b_i .\] Consequently \(r_i = r_0 + \sum_{j=1}^{i} (a_j + b_j)\) for every \(i\), where \(r_0 = c - \sum_{j=1}^{K} b_j\) is the rate on the leftmost segment and \(r_K = c + \sum_{j=1}^{K} a_j\) is the rate on the rightmost.
Proof of Theorem 2. Fix \(i \in \{1, \dots, K\}\). By Theorem 1, \[r_i = c + \sum_{j=1}^{i} a_j - \sum_{j=i+1}^{K} b_j \qquad\text{and}\qquad r_{i-1} = c + \sum_{j=1}^{i-1} a_j - \sum_{j=i}^{K} b_j .\] Subtracting, the \(c\) cancels; the two sums of \(a\)’s differ by the single term \(a_i\); and since \(\sum_{j=i}^{K} b_j = b_i + \sum_{j=i+1}^{K} b_j\), the two sums of \(b\)’s differ by the single term \(b_i\), which is subtracted in \(r_{i-1}\) and not in \(r_i\). Hence \(r_i - r_{i-1} = a_i + b_i\). Adding this identity for \(j = 1, \dots, i\) in place of \(i\), the left sides telescope: \((r_1 - r_0) + (r_2 - r_1) + \cdots + (r_i - r_{i-1}) = r_i - r_0\), which gives the sum formula. The values of \(r_0\) and \(r_K\) are Theorem 1 at \(i = 0\), where the sum of \(a\)’s is empty, and at \(i = K\), where the sum of \(b\)’s is empty. \(\blacksquare\)
Corollary 2 (the reading rule). In the setting of Case 1, for every \(i \in \{1, \dots, K\}\) the rate on the segment whose left knot is \(t_i\) is \(r_i = r_{i-1} + a_i + b_i\): the coefficients printed at a knot are added to the rate arriving from the left, and are not themselves the rate of the segment that begins there. The two coincide, \(r_i = a_i + b_i\), exactly when \(r_{i-1} = 0\); in particular, for a model whose only hinges are right hinges and which has no linear term, this happens at \(i = 1\) and, by Theorem 2, at no later knot unless the coefficients at the knots before it sum to zero.
Proof. The first equality is Theorem 2. \(r_i = a_i + b_i\) if and only if \(r_{i-1} = 0\) follows from it. If \(b_j = 0\) for all \(j\) and \(c = 0\), Theorem 2 gives \(r_0 = 0\), so \(r_1 = a_1\), and \(r_{i-1} = \sum_{j < i} a_j\), which is \(0\) only when those coefficients sum to zero. \(\blacksquare\)
Corollary 3 (the adjustment as an integral). In the setting of Case 1, \(g\) is continuous at every knot, because each hinge is, and so is \(f(\cdot, z)\) for every \(z\); that is what makes the value at a knot the same whether it is reached from the left or the right, and what lets the rates be walked from one quantity to another. Let \(x_c\) and \(x_s\) be the quantities of \(x\) for a comparable and a subject, with the other features held at the same values for both, so that \(g(x)\), the terms of \(f\) that involve \(x\), is the contribution of \(x\) at quantity \(x\). Write \(u_1 = \min(x_c, x_s)\) and \(u_2 = \max(x_c, x_s)\), and \(|I|\) for the length of an interval \(I\). Then the adjustment \(g(x_s) - g(x_c)\), the amount added to the comparable’s contribution to make it equal to the subject’s, is \[g(x_s) - g(x_c) \;=\; \int_{x_c}^{x_s} g'(u)\,du \;=\; \operatorname{sign}(x_s - x_c)\,\sum_{i=0}^{K} r_i \cdot \bigl|S_i \cap [u_1, u_2]\bigr| .\] In words: the adjustment is the integral of the rate between the two quantities, and because the rate is constant on each segment the integral is the sum, over the segments met on the way, of rate times width.
Proof. \(g\) is continuous and piecewise linear with finitely many pieces, hence absolutely continuous, so the fundamental theorem of calculus gives \(g(x_s) - g(x_c) = \int_{x_c}^{x_s} g'(u)\,du\), the derivative existing everywhere except at the knots, a finite set. On each \(S_i\) the integrand equals \(r_i\) by Theorem 1, so \(\int_{u_1}^{u_2} g'(u)\,du\) is the sum over \(i\) of \(r_i\) times the length of \(S_i \cap [u_1, u_2]\), segments not met contributing length \(0\); and \(\int_{x_c}^{x_s} = \operatorname{sign}(x_s - x_c)\int_{u_1}^{u_2}\) by the orientation of the integral. \(\blacksquare\)
The rate table is \(g'\); the adjustment, computed directly as \(g(x_s) - g(x_c)\), equals its integral between the two quantities; and Theorems 1 and 2 say what \(g'\) is made of. In practice the adjustment is always computed as that difference of contributions, which needs no rates at all; the corollary says why the rates, read range by range, reproduce it, which is what makes them an explanation of the adjustment and a check on it, not a way of computing it.
Take living area in a dataset whose smallest house has 800 square feet, with seven knots, at 1,200, 1,600, 2,000, 2,400, 2,800, 3,200 and 3,600 square feet, and nine terms in the model, two of them reflected hinges, each paired with a right hinge at the same knot: at 1,200 and at 2,400:
h(1200-gla) -500
h(gla-1200) 700
h(gla-1600) -100
h(gla-2000) 150
h(2400-gla) -200
h(gla-2400) -250
h(gla-2800) -300
h(gla-3200) -150
h(gla-3600) 50
Seven knots make eight segments. The rate on each is the sum of the coefficients of the active right hinges minus the sum of the coefficients of the active reflected hinges:
| segment (sf) | active terms | rate ($/sf) |
|---|---|---|
| 800 to 1,200 | \(h(1200-\mathrm{gla})\), \(h(2400-\mathrm{gla})\) | \(500 + 200 = 700\) |
| 1,200 to 1,600 | \(h(\mathrm{gla}-1200)\), \(h(2400-\mathrm{gla})\) | \(700 + 200 = 900\) |
| 1,600 to 2,000 | right hinges at 1,200, 1,600; \(h(2400-\mathrm{gla})\) | \(700 - 100 + 200 = 800\) |
| 2,000 to 2,400 | right hinges at 1,200 to 2,000; \(h(2400-\mathrm{gla})\) | \(700 - 100 + 150 + 200 = 950\) |
| 2,400 to 2,800 | right hinges at 1,200 to 2,400 | \(700 - 100 + 150 - 250 = 500\) |
| 2,800 to 3,200 | right hinges at 1,200 to 2,800 | \(500 - 300 = 200\) |
| 3,200 to 3,600 | right hinges at 1,200 to 3,200 | \(200 - 150 = 50\) |
| above 3,600 | all seven right hinges | \(50 + 50 = 100\) |
Three things to read off the table. The rightmost segment’s rate, \(700 - 100 + 150 - 250 - 300 - 150 + 50 = 100\), combines the coefficients of all seven right hinges, one per knot, which is the bound of Theorem 1 with \(K = 7\); the two reflected hinges play no part there, because a reflected hinge is flat to the right of its own knot and the rightmost segment lies to the right of every knot. The leftmost segment, from 800 up to its right knot at 1,200, is the mirror image: only the reflected hinges count, with their signs reversed, because every knot lies at or to the right of its right knot. And at each knot that carries a pair the step is the sum of the two coefficients: at 1,200, \(-500 + 700 = +200\), from 700 to 900; at 2,400 the rate drops from 950 to 500, a change of \(-450\), which is exactly the sum of the two coefficients at that knot, \(-250\) and \(-200\): crossing the knot switches the right hinge on and the reflected hinge off, and both changes push the same way.
The same rate on the rightmost segment can be reached by walking: start at 700 on the first segment, 800 to 1,200, and add, at each knot crossed, the sum of the coefficients sitting there, \(+200\), \(-100\), \(+150\), \(-450\), \(-300\), \(-150\), \(+50\). That route touches all eight segments and all nine terms and lands on the same 100. The direct sum is shorter and is what the program does; the walk is what a reader should do once, by hand, to see that the coefficient beside a knot is a step and not a level. The \(-450\) at 2,400 is two half-steps: crossing the knot leaves the reflected hinge \(h(2400-\mathrm{gla})\) behind, and with it the \(+\$200\) it added below the knot; and it brings in the right hinge \(h(\mathrm{gla}-2400)\), whose \(-250\) starts there. \(-200 - 250 = -450\), and the rate falls from $950 to $500.
Figure 4 draws the same lesson for a five-knot model, small enough to check by eye. The bars are the coefficients printed at the knots; the staircase is the rate on each segment; and the staircase starts at the first segment’s rate, $900, set by the reflected hinge, and each step is the sum of the bars at that knot. The rate on the rightmost segment, \(650 - 250 + 150 - 200 - 150 = 200\), uses all five right hinges; the reflected hinge at 1,200, printed as \(-900\), sets the first segment to \(+900\) and touches nothing else.
Two things about the shape of that graph are worth saying, because they are about houses rather than about MARS. First, the axis starts at 800 square feet and not at zero, and the graph starts at the axis: every graph of a fitted model in this supplement, like the plots the modeling software draws, runs from the smallest house in the data to the largest and draws nothing outside that range. Every market area has a smallest house, below which it holds no sales, and the variable graph shows nothing below it: not zero, but no value the sales support; the formula would still return a number there, and that number is extrapolation. The figures use a floor of 800 square feet, but the floor is a characteristic of the market area, not a constant: different market areas have different minimum sizes of properties that show up in the MLS, and the dataset, not the appraiser, says where it lies. Second, the shape varies from market to market: in the coastal example the steepest range is 1,200 to 2,000 square feet, and in Figure 4 it is the first segment. In a high-priced area such as Atherton or Hillsborough the steepest segment of the living area (GLA) curve may lie past 4,000 or 5,000 square feet, where the buyers are. And a neighborhood in which a builder put up houses of one size with problems in one period could show a sharp drop in the rate over an intermediate range, as the constructed graph does between 1,600 and 2,000. Over a larger market area the variable graphs are varied, and the rate table is how the appraiser reads what a particular one says. Figures 5 and 6 draw two of those shapes as earth would print them, so that a reader can build each rate table by the rule and check it against the staircase.
Case 2: interactions
An interaction term is a coefficient times a product of factors in different variables, each factor a hinge or the variable itself, for instance \(\gamma \cdot h(\mathrm{gla} - 1500) \cdot \mathrm{lot}\). Everything in Case 1 survives except one word: the rate on a segment is now a function of the other variables, not a constant. The statement and its proof follow, and then what it does to an appraiser’s arithmetic.
Setting. A MARS model with interactions on the features \(x, z_1, \dots, z_q\) has fitted value \[f(x, z) \;=\; \beta_0 + \sum_{m=1}^{M} \gamma_m \prod_{k \in F_m} B_{m,k}(z_k),\] where \(M\) is the number of terms other than the intercept, \(\beta_0\) is the intercept, and the model is the intercept plus the sum of its terms, term \(m\) being \(\gamma_m \prod_{k \in F_m} B_{m,k}(z_k)\): its coefficient \(\gamma_m\) times one factor for each feature in the term. Here \(z = (z_1, \dots, z_q)\) and, so that one index runs over every feature, \(z_0\) stands for \(x\). The features appearing in term \(m\) form the set \(F_m \subseteq \{0, 1, \dots, q\}\), no feature appears twice in one term, and each factor \(B_{m,k}\) is a function of the one feature \(z_k\), of one of three kinds: the feature itself, \(z_k\); a right hinge \(h(z_k - t)\); or a reflected hinge \(h(t - z_k)\). Let \(M_x = \{m : 0 \in F_m\}\) be the terms that contain \(x\). For \(m \in M_x\), \(B_{m,0}(x)\) is the term’s factor in \(x\), and the term’s other features, those \(z_k\) with \(k \in F_m\), \(k \ne 0\), are the partners of \(x\) in that term. Write \[P_m(z) \;=\; \prod_{k \in F_m,\; k \ne 0} B_{m,k}(z_k)\] for the product of the partner factors, an empty product being \(1\). In words: once the subject’s other features are filled in, the partners of a term multiply out to one ordinary number; that number times the printed coefficient is the coefficient of a plain living-area term, and the term reads as in Case 1. The partner product \(P_m(z)\) is what remains of term \(m\) when its factor in \(x\) is taken out: term \(m\) is \(\gamma_m\, B_{m,0}(x)\, P_m(z)\). At a given point \(z\) it is a number, so on a segment the term acts on \(x\) as a single hinge with coefficient \(\gamma_m P_m(z)\), and that product is how the partners enter the rate. A term with no partner has \(P_m(z) = 1\) and is a term of Case 1.
For example, in the term \(0.03\,h(\mathrm{gla}-1200)\,h(\mathrm{lot}-6000)\) of the worked example below, with \(x\) the living area, the factor in \(x\) is \(h(\mathrm{gla}-1200)\), the one partner is the lot, and \(P_m(z) = h(\mathrm{lot}-6000)\). At a 5,000 square foot lot \(P_m(z) = 0\) and the term adds nothing to the rate; at a 10,000 square foot lot \(P_m(z) = 4{,}000\) and the term acts as a hinge at 1,200 with coefficient \(0.03 \times 4{,}000 = 120\), adding $120 a square foot to the rate above 1,200 square feet. Nothing here limits how many features a term may contain; earth’s degree argument sets that maximum, and the theorems below hold for any degree. A term in \(d\) features has a graph in \(d + 1\) dimensions, which no one can draw once \(d\) exceeds two; the software shows only slices, one or two features at a time with the others held fixed, and Theorem 3 is the same slicing done at the subject’s own point. \(P_m(z)\) is where that slicing happens: however many partners a term has, at a point their product is one number. In the four-feature term \(\gamma\,h(\mathrm{gla}-1200)\,h(\mathrm{lot}-6000)\,h(\mathrm{age}-10)\,\mathrm{baths}\), with \(\gamma = 0.001\), whose graph has five dimensions, \(P_m(z) = h(\mathrm{lot}-6000)\,h(\mathrm{age}-10)\,\mathrm{baths}\); at a 10,000 square foot lot, an age of 20 years and 3 baths it is \(4{,}000 \times 10 \times 3 = 120{,}000\), and along living area the whole term is a hinge at 1,200 with coefficient \(\gamma \times 120{,}000 = 0.001 \times 120{,}000 = 120\), adding $120 a square foot: the same as the two-feature term above, from a coefficient thirty times smaller. That is why the coefficient of a high-degree term often prints as a very small number when its partners are measured in large units: it multiplies a product of several partner values. And if any partner is on the zero side of its knot, a lot under 6,000 square feet or an age under 10 years, then \(P_m(z) = 0\) and the term contributes nothing, whatever the other partners are; the higher the degree, the more ways a term can be switched off at a given property. The examples in this supplement use two-way interactions (degree = 2).
Let \(t_1 < \cdots < t_K\) be the distinct knots of those \(B_{m,0}\) that are hinges, with \(t_0 = -\infty\), \(t_{K+1} = +\infty\) and segments \(S_i = (t_i, t_{i+1})\) as in Case 1. For \(m \in M_x\) and \(i \in \{0, \dots, K\}\) define \[s_{m,i} \;=\; \begin{cases} +1 & \text{if } B_{m,0} \text{ is the feature } x \text{ itself, or a right hinge } h(x - t_j) \text{ with } t_j \le t_i,\\ -1 & \text{if } B_{m,0} \text{ is a reflected hinge } h(t_j - x) \text{ with } t_j \ge t_{i+1},\\ 0 & \text{otherwise.} \end{cases}\] A point is a value \(z\) of the other features. Since every \(B_{m,0}\) is linear or identically zero on \(S_i\), \(f\) is linear in \(x\) on \(S_i\) for fixed \(z\); its slope there is the rate on \(S_i\) at the point \(z\), written \(r_i(z) = \partial f/\partial x\) for \(x \in S_i\).
To see every symbol at once, take the model of the worked example below as earth prints it: intercept 900,000, \(600\,h(\mathrm{gla}-1200)\), \(-350\,h(\mathrm{gla}-2400)\), \(0.03\,h(\mathrm{gla}-1200)\,h(\mathrm{lot}-6000)\) and \(15\,\mathrm{lot}\). Its features are living area, \(x = z_0 = \mathrm{gla}\), and lot size, \(z_1 = \mathrm{lot}\), so \(q = 1\); the intercept is \(\beta_0 = 900{,}000\) and there are \(M = 4\) terms. At a property with 2,000 square feet of living area on a 10,000 square foot lot:
| \(m\) | \(\gamma_m\) | \(F_m\) | \(B_{m,0}(x)\) | \(B_{m,1}(z_1)\) | \(P_m(z)\) | term at the property |
|---|---|---|---|---|---|---|
| 1 | \(600\) | \(\{0\}\) | \(h(\mathrm{gla}-1200)\) | none | \(1\) | \(600 \times 800 = 480{,}000\) |
| 2 | \(-350\) | \(\{0\}\) | \(h(\mathrm{gla}-2400)\) | none | \(1\) | \(-350 \times 0 = 0\) |
| 3 | \(0.03\) | \(\{0, 1\}\) | \(h(\mathrm{gla}-1200)\) | \(h(\mathrm{lot}-6000)\) | \(h(\mathrm{lot}-6000)\) | \(0.03 \times 800 \times 4{,}000 = 96{,}000\) |
| 4 | \(15\) | \(\{1\}\) | none | \(\mathrm{lot}\) | (not in \(M_x\)) | \(15 \times 10{,}000 = 150{,}000\) |
So \(M_x = \{1, 2, 3\}\): term 4 has no factor in \(x\), adds the same amount whatever the living area, and does not enter the rate of \(x\). The fitted value is \(f = 900{,}000 + 480{,}000 + 0 + 96{,}000 + 150{,}000 = \$1{,}626{,}000\). Terms 1 and 2 have no partner, so \(P_1(z) = P_2(z) = 1\); term 3 has one, and \(P_3(z) = h(10{,}000 - 6{,}000) = 4{,}000\), the multiplier of the example above. Theorem 3, which follows, turns these into the rate. Living area has knots \(t_1 = 1{,}200\) and \(t_2 = 2{,}400\), and the property is on the segment \(S_1\) between them, where terms 1 and 3 are active and term 2 is not (\(s_{1,1} = s_{3,1} = 1\), \(s_{2,1} = 0\)); so \(r_1(z) = 600 \times 1 + 0.03 \times 4{,}000 = 720\), the rate at a 10,000 square foot lot in the worked example’s table.
Theorem 3 (the rate on a segment, with interactions). With this notation, for every \(i\) and every point \(z\), \[r_i(z) \;=\; \sum_{m \in M_x} \gamma_m \, s_{m,i} \, P_m(z).\]
Proof of Theorem 3. Fix \(i\), a point \(z\), and \(x \in S_i\). A term with \(m \notin M_x\) contains no factor in \(x\) and is constant in \(x\); its derivative in \(x\) is \(0\). A term with \(m \in M_x\) equals \(\gamma_m\, B_{m,0}(x)\, P_m(z)\), in which \(P_m(z)\) does not depend on \(x\). By the case analysis in the proof of Theorem 1, applied to the single factor \(B_{m,0}\), the derivative of \(B_{m,0}\) at \(x\) is \(1\) for the feature itself, \(1\) or \(0\) for a right hinge according as its knot is at or left of \(t_i\) or at or right of \(t_{i+1}\), and \(-1\) or \(0\) for a reflected hinge according as its knot is at or right of \(t_{i+1}\) or at or left of \(t_i\); that is, it equals \(s_{m,i}\). So the derivative of the term is \(\gamma_m\, s_{m,i}\, P_m(z)\), and the derivative of \(f\), a finite sum, is the sum of these. The value does not depend on which \(x \in S_i\) was chosen. \(\blacksquare\)
Theorem 1 is the special case in which no term in \(M_x\) has a partner, so that every \(P_m(z) = 1\); grouping the terms of the sum by their knot gives the formula proved there. Three corollaries say what the partners change; the last of them is the failure of the one-per-knot bound, and the “term can vanish” case that the worked example below shows.
Corollary 4 (the rate is a number only at a point). In the setting of Case 2, for each \(i\) the rate \(r_i\) is a function of the point \(z\). It is constant in \(z\) whenever every term \(m \in M_x\) with \(s_{m,i} \ne 0\) has no partner. When some term with \(s_{m,i} \ne 0\) has a partner, \(r_i(z)\) is the function \(z \mapsto \sum_{m} \gamma_m s_{m,i} P_m(z)\), which changes with the partners’ values except where the terms cancel exactly; two properties with the same \(x\) on the same segment then have different rates for \(x\) whenever their partner products differ and the differences do not cancel. This is why the program takes a point, and why no rate table for one feature exists on its own.
Proof. By Theorem 3, \(r_i(z) = \sum_{m \in M_x} \gamma_m s_{m,i} P_m(z)\). If every term with \(s_{m,i} \ne 0\) has no partner, each such \(P_m\) is the empty product \(1\) and the sum is a constant. Otherwise the sum contains at least one summand \(\gamma_m s_{m,i} P_m(z)\) with \(\gamma_m s_{m,i} \ne 0\) and \(P_m\) a product of one or more factors each of which is a non-constant function of a partner, so the sum is constant in \(z\) only if those summands cancel identically. \(\blacksquare\)
Corollary 5 (on a segment of \(x\), the rate is a variable graph in each partner). In the setting of Case 2 fix \(i\), a partner \(z_p\) (\(p \ge 1\)), and the values of all other features. Then \(z_p \mapsto r_i(z)\) is a continuous piecewise-linear function of \(z_p\) whose breaks lie among the knots of the factors \(B_{m,p}\) of the terms in \(M_x\). Along \(x\) with every partner held fixed, the rate changes only at the knots \(t_1, \dots, t_K\) of \(x\); it is in the joint space of \(x\) and its partners that the rate surface is cut both by the knots of \(x\) and by the knots of every partner.
Proof. With the other features fixed, each \(P_m(z)\) is a constant times either \(1\) (if \(p \notin F_m\)) or the single factor \(B_{m,p}(z_p)\), which is \(z_p\) itself, \(h(z_p - t)\) or \(h(t - z_p)\): a continuous piecewise-linear function of \(z_p\) with at most one break, at its knot. A finite linear combination of such functions, which is what Theorem 3 gives for \(r_i(z)\), is continuous and piecewise linear with breaks only where some summand breaks. The statement along \(x\) is Theorem 3 itself: for fixed \(z\), \(r_i(z)\) is one number on each \(S_i\) and the segments meet only at the knots of \(x\). \(\blacksquare\)
Corollary 6 (the bound of Theorem 1 fails). In the setting of Case 2 the number of terms with a non-zero summand in Theorem 3’s formula for \(r_i(z)\) is bounded only by \(|M_x|\), the number of terms containing \(x\), and may exceed \(K\): a knot of \(x\) may appear in several terms of \(M_x\) with different partners, each a distinct term. Conversely a term with \(s_{m,i} \ne 0\) contributes nothing at a point where its partner product is zero.
Proof. The terms \(\gamma_1\,h(x - 1500)\,\mathrm{lot}\) and \(\gamma_2\,h(x - 1500)\,h(\mathrm{age} - 10)\) are distinct terms of \(M_x\) with the same knot, and on the segment above \(1{,}500\) both have \(s_{m,i} = 1\), so both contribute, and \(r_i(z) = \gamma_1\,\mathrm{lot} + \gamma_2\,h(\mathrm{age} - 10)\) has two summands from one knot; adding further partners adds further terms at the same knot without bound. For the converse, take a term whose partner is a hinge \(h(\mathrm{lot} - 6000)\) at a point with \(\mathrm{lot} < 6000\): then \(P_m(z) = 0\) and the summand vanishes although \(s_{m,i} \ne 0\); at a point with \(\mathrm{lot} > 6000\) it does not. \(\blacksquare\)
A practical observation from the editor’s own appraisals belongs here. Once interactions are allowed, the living-area graph the software draws for the variable on its own often comes out straight, a single rate, while the bends that a model without interactions would have put into living area appear instead in the interaction terms, typically living area with sale age (the time between the sale and the effective date) or living area with bathrooms. Theorem 3 says why the straight line is not the rate. The per-variable plot in earthUI draws the terms with no partner; plotmo’s degree-one plot instead draws a slice of the whole model with the other variables at their medians. The interaction terms are drawn as surfaces elsewhere (the degree-one and degree-two plots of plotmo, Milborrow 2024b, which earthUI shows side by side). At any actual property the rate for living area is the straight line’s slope plus, for every active interaction term, its coefficient times its partner factor’s value; it changes at the living-area knots of those terms, and by how much depends on the partners: a sale six years ago and a sale last month, or a two-bath house and a four-bath one, sit on different rate tables for living area even though the living-area plot shows one line. A reader who takes the line for the rate has met the barrier again, one level up; the rate table at the subject’s point is the way through it. Figure 7 draws one such model the way the software does, as a surface over living area and sale age, and then reads the living-area variable graph off it at two sale ages.
Figure 8 runs the same idea in the other direction, starting from the market of Figure 2. A model is built for that market with a living-area by sale-age interaction, so that the living-area main effect is one straight line, $500 a square foot, and the four interaction terms carry the bends. The plot the software draws for living area on its own is the straight line. Read at a sale four years old, the living-area rates are Figure 2’s to the dollar, $600, $1,000, $750 and $100; read at a new sale it is the straight line; read at two years it is between. The model is constructed to make the point, not fitted to sales, and a real refit would not land on Figure 2 so neatly; but the mechanism is the one a real refit uses, and it is why an appraiser who sees the living-area plot straighten after adding interactions has not lost the bends. The bends have moved into the interaction terms, where only a reading at a point recovers them. The main-effect plot of a model with interactions draws the variable’s terms alone, which is the slice at a setting of the partners where every interaction term is zero (here, a new sale), not the market’s shape; read the variable graph at the subject.
The last consequence is about the adjustment rather than the rate, and it is the one that reaches the sales grid.
Theorem 4 (the split of an adjustment is order-dependent). In the setting of Case 2 let \(y = z_p\) (\(p \ge 1\)) be one of the other features and let \(w\) stand for the remaining ones, \(z_k\) for \(k \notin \{0, p\}\); write \(f(x, y, w)\) for \(f\) with its arguments so grouped. Let a comparable be at \((x_c, y_c, w)\) and a subject at \((x_s, y_s, w)\), the same \(w\) for both. For a value \(y^\ast\) of \(y\) define the adjustment for \(x\) with \(y\) held at \(y^\ast\) as \[\Delta_x(y^\ast) \;=\; f(x_s, y^\ast, w) - f(x_c, y^\ast, w).\] Let \(M_{x,y}\) be the terms containing both \(x\) and \(y\). Each such term is its coefficient times three parts, \(\gamma_m\, A_m(x)\, C_m(y)\, Q_m(w)\): \(A_m(x) = B_{m,0}(x)\) is its factor in \(x\), which is \(x\) itself or a hinge in \(x\); \(C_m(y) = B_{m,p}(y)\) is its factor in \(y\), which is \(y\) itself or a hinge in \(y\); and \(Q_m(w)\) is the product of its factors in the remaining features, each such a feature itself or a hinge in it, and is \(1\) when the term has no other factor. In the worked example below the one such term is \(0.03\,h(\mathrm{gla}-1200)\,h(\mathrm{lot}-6000)\), with \(A_m(x) = h(\mathrm{gla}-1200)\), \(C_m(y) = h(\mathrm{lot}-6000)\) and \(Q_m(w) = 1\). Write \(\Delta_x(y_s)\) and \(\Delta_x(y_c)\) for the adjustment for \(x\) with \(y\) held at the subject’s value \(y_s\) and at the comparable’s value \(y_c\), that is, \(\Delta_x(y^\ast)\) at \(y^\ast = y_s\) and at \(y^\ast = y_c\); in the worked example, with \(x\) the living area and \(y\) the lot, \(\Delta_x(y_c) = \$240{,}000\) at the comparable’s 5,000 square foot lot and \(\Delta_x(y_s) = \$288{,}000\) at the subject’s 10,000. Then \[\Delta_x(y_s) - \Delta_x(y_c) \;=\; \sum_{m \in M_{x,y}} \gamma_m \bigl[A_m(x_s) - A_m(x_c)\bigr]\bigl[C_m(y_s) - C_m(y_c)\bigr] Q_m(w),\] while the total difference \(f(x_s, y_s, w) - f(x_c, y_c, w)\) involves no choice of \(y^\ast\). The statement is about this two-feature slice, one partner \(y\) with everything else held at the same \(w\) for both properties; when three or more features differ between the two, the split of the total among them is path-dependent in the same way along a longer chain of one-feature moves, and the theorem applies to each step of the chain, with the features not yet moved held at their current values. In particular, with a single such term \(\gamma\,A(x)\,C(y)\) and no factors in \(w\), the two adjustments for \(x\) differ by \(\gamma\,[A(x_s) - A(x_c)]\,[C(y_s) - C(y_c)]\), which is not \(0\) whenever the move in \(x\) changes \(A\) and the two properties differ in \(C\). For \(A = h(x-t)\) and \(C = y\) this is \(\gamma\,[h(x_s-t) - h(x_c-t)]\,(y_s - y_c)\); for \(A = h(x-t)\) and \(C = h(y-s)\), the form of the worked example below, it is \(\gamma\,[h(x_s-t) - h(x_c-t)]\,[h(y_s-s) - h(y_c-s)]\).
Proof of Theorem 4. Group the terms of \(f\) by which of \(x\), \(y\) they contain. A term containing neither \(x\) nor \(y\) takes the same value at \((x_s, y^\ast, w)\) and \((x_c, y^\ast, w)\) and cancels in \(\Delta_x(y^\ast)\). A term containing \(y\) but not \(x\) likewise cancels. A term containing \(x\) but not \(y\) contributes to \(\Delta_x(y^\ast)\) an amount that does not depend on \(y^\ast\), so it cancels in \(\Delta_x(y_s) - \Delta_x(y_c)\). A term \(m \in M_{x,y}\) contributes \(\gamma_m [A_m(x_s) - A_m(x_c)] C_m(y^\ast) Q_m(w)\) to \(\Delta_x(y^\ast)\); setting \(y^\ast = y_s\) and \(y^\ast = y_c\) and subtracting gives the stated sum. The total difference is a difference of two values of the one function \(f\) and mentions no \(y^\ast\). \(\blacksquare\)
So the interaction’s value belongs to the pair of features, not to either. A grid that adjusts one feature at a time at the comparable’s values, and one that adjusts at the subject’s values, agree on the total and disagree on the split. Holding the other features at the subject’s values is one defensible convention and is the one the program uses; a report has to say which convention it used. A standard residential grid, such as that of the Uniform Residential Appraisal Report (URAR), has no line for an interaction. Done one feature at a time, the two moves must hold the partner at opposite ends — living area adjusted at the subject’s lot, then the lot at the comparable’s living area, or the reverse — so that the interaction is counted once and the lines sum to the model’s total difference. With contributions computed directly, a grid can also carry the interaction as a line of its own, the difference of the interaction terms between subject and comparable, next to the lines for each feature; each line is then one group of terms, and no order has to be chosen. In the worked example below the three lines are living area $240,000, lot $75,000, and living area by lot $120,000, which sum to the same $435,000. With interactions, the pair’s secant rate changes with the pair in two ways: once through the ranges crossed, and once through where the pair sits in the partners.
A worked example with an interaction
A coastal market again, now with two features, living area and lot size, and one interaction between them. earth prints:
(Intercept) 900000
h(gla-1200) 600
h(gla-2400) -350
h(gla-1200)*h(lot-6000) 0.03
lot 15
Read as Theorem 3 says. Living area has two knots, 1,200 and 2,400, and three terms in \(M_{\mathrm{gla}}\): the two plain hinges and the interaction, whose partner is \(h(\mathrm{lot}-6000)\). On the segment from 1,200 to 2,400 the plain hinge at 1,200 is active and so is the interaction’s hinge at 1,200, so the rate there is \(600 + 0.03\,h(\mathrm{lot}-6000)\): a variable graph in the lot, constant at 600 for lots up to 6,000 square feet and increasing by 3 cents for each further square foot of lot. Above 2,400 the hinge at 2,400 comes in and the rate is \(250 + 0.03\,h(\mathrm{lot}-6000)\). The lot’s own rate is \(15 + 0.03\,h(\mathrm{gla}-1200)\) above 6,000 square feet of lot and \(15\) below, so each feature’s rate depends on the other’s quantity.
Two points, two tables. The program’s rate table for living area over the data, 800 to 3,500 square feet, once at a 5,000 square foot lot and once at a 10,000 square foot lot. Each column is the model’s slope in living area with the lot held at that one value, and at no other:
| segment of living area (sf) | rate at lot 5,000 ($/sf) | rate at lot 10,000 ($/sf) |
|---|---|---|
| 800 to 1,200 | 0 | 0 |
| 1,200 to 2,400 | 600 | 720 |
| 2,400 to 3,500 | 250 | 370 |
At the smaller lot the partner factor \(h(5000-6000)\) is zero, so the interaction contributes nothing and the table is the one a model without the interaction would give; that is the “term can vanish” case of Corollary 6. At the larger lot the partner is \(4{,}000\), the interaction adds \(0.03 \times 4{,}000 = 120\) to every segment above 1,200, and the same knot, 1,200, is feeding two active terms, which is the failure of the one-per-knot bound.
Now the adjustment. The comparable has 1,800 square feet on a 5,000 square foot lot with a fitted value of $1,335,000; the subject has 2,200 square feet on a 10,000 square foot lot, fitted $1,770,000. The total to explain is $435,000. Adjust living area first, at the comparable’s lot, then the lot at the subject’s living area. Each adjustment is the difference of the two contributions it compares; where the move stays within one segment that difference is width times rate, which is how the table writes it:
| living area first, lot second | lot first, living area second | |
|---|---|---|
| living-area adjustment | \(400 \times 600 = 240{,}000\) | \(400 \times 720 = 288{,}000\) |
| lot adjustment | \(195{,}000\) | \(147{,}000\) |
| total | \(435{,}000\) | \(435{,}000\) |
The lot adjustments are differences of contributions in the same way, and the rates explain them; the lot’s own rate breaks at 6,000 square feet: at the subject’s 2,200 square feet the lot rate is $15 below the knot and $45 above it, so the move from 5,000 to 10,000 is \(1{,}000 \times 15 + 4{,}000 \times 45 = 195{,}000\), not \(5{,}000 \times 45\); at the comparable’s 1,800 square feet it is \(1{,}000 \times 15 + 4{,}000 \times 33 = 147{,}000\). The totals agree, as Theorem 4 says they must, and the splits differ by $48,000, which is exactly the theorem’s formula: \(0.03 \times [h(2200-1200) - h(1800-1200)] \times [h(10000-6000) - h(5000-6000)] = 0.03 \times 400 \times 4{,}000\). That $48,000 is the value of having the extra 400 square feet of house and the extra 4,000 square feet of lot together; it belongs to neither feature, and whichever is adjusted second collects it. The program’s convention, the other features held at the subject’s values, gives the right-hand column for living area, $288,000 at $720 a square foot, and its report says at what point the rate was read:
Feature: gla
Rates by range (data from 800 to 3500; nothing is reported outside it):
800 .. 1200 rate 0.0
1200 .. 2400 rate 720.0
2400 .. 3500 rate 370.0
Fitted value at the knots (intercept and partners included):
1200 1050000.0
2400 1914000.0
Comparable at 1800: contribution 432000.0
Subject at 2200: contribution 720000.0
Adjustment, range by range:
1800 .. 2200 400 at 720.0 = 288000.0
Adjustment added to the comparable: 288000.0
Secant rate for the pair (one straight-line rate): 720.0
Check: segments sum to the adjustment.
Both contributions are read at the subject’s lot of 10,000 square feet; at its own 5,000-square-foot lot the comparable’s living-area contribution is $360,000.
A reviewer who reruns this at the comparable’s lot gets $240,000 and is not wrong; the reviewer and the program are reading the same surface at two points, and the report has to say which.
In short: without interactions a MARS model is a rate table per feature, and every argument about a rate made for ordinary regression transfers segment by segment. With interactions a rate is a surface, Theorem 3 says exactly how it bends, and the appraiser must say at what point it was read.
The program
mars_rates.pl, printed in full in the addendum, reads earth’s printed table, or a model written as a Prolog term, and produces the rate table, the values at the knots, the two contributions and their difference, the adjustment, with its range-by-range explanation, the pair’s secant rate, and a check that the ranges sum to the adjustment. Given the data range, the smallest and largest house in the sales, it reports no rate outside it: a hinge’s algebra runs to infinity on one side, the sales do not, and a rate beyond them is extrapolation. For the example, on data from 800 to 3,500 square feet:
Feature: gla
Rates by range (data from 800 to 3500; nothing is reported outside it):
800 .. 1200 rate 600
1200 .. 2000 rate 1000
2000 .. 2800 rate 750
2800 .. 3500 rate 100
Fitted value at the knots (intercept and partners included):
1200 1520000
2000 2320000
2800 2920000
Comparable at 1800: contribution 600000
Subject at 2400: contribution 1100000
Adjustment, range by range:
1800 .. 2000 200 at 1000 = 200000
2000 .. 2400 400 at 750 = 300000
Adjustment added to the comparable: 500000
Secant rate for the pair (one straight-line rate): 833.3333333333334
Check: segments sum to the adjustment.
Two kinds of number stand in that block. The contributions are the living-area terms alone, with the intercept and every other feature’s terms left out: $600,000 and $1,100,000 differ by exactly the adjustment. The values at the knots are fitted values, intercept included, and in a model with interactions the partners’ terms at the point as well; here $1,520,000 at 1,200 square feet is the intercept because every hinge is zero there. The fitted values at the comparable and the subject, $2,120,000 and $2,620,000, carry the intercept the same way. The report labels the knot values as fitted values so that a reader does not take them for contributions.
That block is what belongs in a report’s addendum: the rates, the knots, and the arithmetic from one to the other, in a form a reviewer can redo by hand. The program’s 69 tests pin the sign rule, the interaction rule, the consistency of segments with adjustments, and the parser for earth’s output, and pass under Trealla, the Journal’s Prolog, and under SWI-Prolog and Scryer Prolog. For readers who work in R, the same reading is available without leaving it: mars_rates.R, published with the program, takes an earth object or its printed table and prints the same block, with the rates clamped to the data range; the Prolog remains the checked reference, and the R file carries its own self-checks against the examples of this supplement. The program, its tests and the figure script are published with this issue as a download beside the PDF, under the GNU Affero General Public License, version 3 or later.
Why MARS, and what this supplement leaves to other entries
The Journal models with MARS for three reasons, and they are the reasons this supplement can exist. Objectivity: the knots are placed where the sales place them, by one stated procedure with one stated pruning rule (the later stage that removes terms that do not earn their place), and nothing about the shape of a variable graph is decided beforehand beyond those stated settings (the maximum degree of interaction, the pruning penalty, the minimum spacing of knots). Discoverability: the forward pass searches every feature and every candidate knot, interactions included up to the stated degree, and reports what it found, which no method that starts from a chosen shape can do. Interpretability: constant rates over ranges the data chose, and interactions built from the same hinges, are what let the model be written as a rate table and an adjustment be explained as rate times width. Two other methods also produce rates that change across a feature’s range, and they are different from each other. The first, segmented (“broken-stick”) regression, takes a variable and a number of breaks chosen by the analyst and estimates where the breaks fall, with a standard error (a measure of how far the estimate could move with other sales) on each; between breaks the rate is constant, as in MARS. The second, a shape-constrained additive model, fits a smooth curve instead of straight segments, forced to a shape the analyst imposes — for example, that value never falls as living area grows, or that each added square foot adds less than the one before. Neither is used here. Each answers a question this supplement does not ask, and each gives up at least one of the three properties: segmented regression gives up discoverability, because the variable and the number of breaks are chosen in advance; the shape-constrained model gives up interpretability, because a curve has no constant rates to tabulate, and objectivity, because its shape is imposed. This supplement reads the model MARS produces; the choice of method, and the stability of the knots and rates MARS finds from one set of sales to the next, are subjects for entries of their own.
What this does not settle
The rates are the model’s, and the four statistical entries apply to them unchanged: a rate approximates the conditional expectation only as well as the model’s form allows (Conditional Expectation); it can carry an omitted feature’s value (Omitted Variable Bias); it can be distorted when a feature moves with the structural error (Endogeneity); and it may not be pinned down by the sales at all, however many there are, when two features always move together (Parameter Identification). MARS finds where a rate changes only where the sales contain the contrast to show it; a knot is a claim about the market and is only as good as the sales on either side of it. What this supplement adds is narrower: given the model, here is how to say what it says.
References.
Craytor, W. B. (2026). earthUI: An Interactive Interface for the earth (MARS) Package. Valuation Engineer Journal, 1(1). https://doi.org/10.67330/7fj41b65
Friedman, J. H. (1991). Multivariate Adaptive Regression Splines. The Annals of Statistics, 19(1), 1–67. https://doi.org/10.1214/aos/1176347963
Hastie, T., Tibshirani, R., & Friedman, J. (2009). The Elements of Statistical Learning: Data Mining, Inference, and Prediction (2nd ed.), §9.4, Multivariate Adaptive Regression Splines. Springer.
Milborrow, S. (2024a). earth: Multivariate Adaptive Regression Splines. R package. https://CRAN.R-project.org/package=earth
Milborrow, S. (2024b). plotmo: Plot a Model’s Residuals, Response, and Partial Dependence Plots. R package. https://CRAN.R-project.org/package=plotmo
Milborrow, S. (n.d.). Notes on the earth Package. http://www.milbo.org/doc/earth-notes.pdf
MARS is a registered trademark of Minitab, LLC. It is used in this Journal as the name of the statistical method introduced by Friedman (1991), and the software referred to is the R package earth, whose notation this Journal follows: hinges are written \(h(x-t)\) and \(h(t-x)\) and models are shown as earth prints them. Salford’s MARS writes the same functions as numbered basis functions, \(\mathrm{BF}1 = \max(0, X - t)\) and so on, and differs from earth in such details of notation, not in the method.↩︎