Spline Regression › Example
Machine Learning from ScratchAll chapters Spline Regression › ExampleOne section · Sections in this chapter4 / 8 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Let's work through a concrete example to understand how spline regression works step-by-step. We'll use a simple dataset and see the complete calculation process for a cubic spline with two knots. This example will help you understand how all the mathematical concepts we've discussed come together in practice.
Step 1: Data Preparation
Consider the following dataset with 8 observations:
| Observation | X | Y |
|---|---|---|
| 1 | 1 | 2.1 |
| 2 | 2 | 3.8 |
| 3 | 3 | 6.2 |
| 4 | 4 | 8.9 |
| 5 | 5 | 12.1 |
| 6 | 6 | 15.8 |
| 7 | 7 | 20.2 |
| 8 | 8 | 25.1 |
Understanding Our Data:
- X values: These are our input values, ranging from 1 to 8
- Y values: These are our response values that we want to predict
- Pattern: Looking at the data, we can see that Y increases as X increases, but not in a perfectly linear way. The relationship appears to be accelerating (the Y values increase more rapidly as X gets larger)
This type of non-linear relationship is exactly what spline regression is designed to handle. If we tried to fit a straight line to this data, we would miss the accelerating pattern.
Step 2: Setting Up the Cubic Spline Model
We'll fit a cubic spline with knots at and . This divides our data into three segments:
- Segment 1: - This includes observations 1, 2, and 3
- Segment 2: - This includes observations 4, 5, and 6
- Segment 3: - This includes observations 7 and 8
Why These Knot Locations?
We chose knots at and because:
- They divide our data roughly into thirds
- They're positioned where we might expect the relationship to change behavior
- They give us enough data points in each segment to fit cubic polynomials
- : The square brackets mean the interval includes both endpoints (1 and 3)
- : The parenthesis on the left means 3 is excluded, the square bracket on the right means 6 is included
- : Similarly, 6 is excluded but 8 is included
This ensures that each data point belongs to exactly one segment, and the segments don't overlap.
Step 3: Constructing the B-spline Basis Matrix
For a cubic B-spline with knots at positions (note the repeated boundary knots), we need to construct the basis functions.
Understanding the Knot Vector:
The knot vector might look confusing at first, but here's what it means:
- Repeated knots at the boundaries: The knots at the beginning and at the end are repeated to ensure proper boundary behavior
- Interior knots: The knots and are our actual break points where the spline changes behavior
- Total knots: We have 10 knot values, but only 2 unique interior knots
Why Repeat Boundary Knots?
Repeating the boundary knots ensures that:
- The spline behaves properly at the edges of our data
- We get the right number of basis functions
- The spline doesn't extrapolate wildly beyond our data range
The Basis Matrix Dimensions:
The B-spline basis matrix will have dimensions :
- 8 rows: One for each observation in our dataset
- 7 columns: One for each B-spline basis function
Constructing the Basis Functions:
The basis matrix construction involves evaluating each B-spline basis function at each data point. For cubic B-splines, each basis function is defined using the Cox-de Boor recursion formula we discussed earlier.
What This Means in Practice:
For each of our 8 data points (X values 1 through 8), we need to calculate the value of each of the 7 B-spline basis functions. This gives us a matrix where:
- Row 1 contains the values of all 7 basis functions evaluated at X = 1
- Row 2 contains the values of all 7 basis functions evaluated at X = 2
- And so on...
Step 4: Matrix Calculations
Now we need to set up our matrices for the spline regression calculation. This is where we'll see how the mathematical framework we discussed earlier applies to our specific data.
The response vector contains all our observed Y values:
This is simply a column vector with 8 rows, where each row contains the Y value for the corresponding observation.
The B-spline basis matrix (constructed using the recursive Cox-de Boor formula) is approximately:
Understanding the Basis Matrix:
Let's examine what this matrix tells us:
-
Row 1 (X = 1): Only the first basis function has a non-zero value (1.000), while all others are 0. This means that for X = 1, only the first B-spline basis function contributes to the final prediction.
-
Row 2 (X = 2): The first two basis functions have non-zero values (0.296 and 0.704), and they sum to 1.000. This demonstrates the "partition of unity" property we discussed.
-
Row 3 (X = 3): This is at our first knot! Notice how the values are distributed across the first three basis functions, showing the transition behavior at the knot.
-
Rows 4-5 (X = 4, 5): These are in the middle segment. Notice how the non-zero values shift to different basis functions.
-
Row 6 (X = 6): This is at our second knot! Again, we see the transition behavior.
-
Rows 7-8 (X = 7, 8): These are in the final segment, and we can see the non-zero values shifting toward the rightmost basis functions.
Key Observations:
- Compact Support: Each row has mostly zeros, showing that only a few basis functions are active at each point
- Partition of Unity: Each row sums to approximately 1.000 (allowing for small rounding errors)
- Smooth Transitions: The values change smoothly as we move from one row to the next
- Knot Behavior: At the knots (rows 3 and 6), we see the transition between different sets of active basis functions
Step 5: Solving for Coefficients
Now we need to find the optimal coefficients that will make our spline function fit the data as closely as possible. We'll use the normal equation we discussed earlier.
The Normal Equation:
Using the normal equation :
Step 5a: Calculating
First, we need to calculate . Remember that is the transpose of (rows become columns and columns become rows).
Understanding :
This matrix represents the "overlap" between different basis functions. Notice that:
- The diagonal elements are larger (representing how much each basis function overlaps with itself)
- The off-diagonal elements are smaller (representing how much different basis functions overlap with each other)
- Most elements are zero (showing the compact support property)
Step 5b: Calculating
Next, we calculate :
where each element is computed as:
For example, the first element is:
Understanding :
This vector represents the "overlap" or projection between each basis function and our response data. Each element tells us how much the -th basis function contributes to explaining the observed Y values.
Step 6: Final Model
Solving the System:
Now we need to solve the system for . This is a system of 7 linear equations with 7 unknowns.
The solution is:
Understanding the Coefficients:
Notice something interesting: the coefficients are exactly equal to our original Y values! This might seem surprising, but it makes sense when you think about it:
- Each coefficient represents the "weight" we give to the -th basis function
- Since our B-spline basis functions are designed to be "local" (each one is active only in a small region), the coefficients end up being close to the Y values in those regions
- This is a special property of B-splines that makes them very efficient for interpolation
Step 7: Verification
Our Fitted Spline Model:
Our fitted spline model is:
where:
- : the predicted response value at input
- : the estimated coefficient for the -th basis function
- : the -th B-spline basis function evaluated at
- : index ranging from 1 to 7 (we have 7 basis functions in this example)
Verification Calculations:
Let's verify that our model works by calculating predictions at the data points. We'll use the basis matrix values from Step 4 and the coefficients from Step 6.
For (Row 1 of ):
For (Row 2 of ):
Note: The values shown in the basis matrix are rounded for display. In practice, when using the exact basis matrix values (not rounded), the predictions would match the observed values exactly due to the interpolation property of B-splines with sufficient basis functions.
What This Means:
The spline model interpolates the training data perfectly, which is expected for a cubic spline with sufficient flexibility. This means:
- Perfect Fit: Our spline passes exactly through all our data points
- Smooth Transitions: The smooth transitions between segments ensure that the resulting curve is continuous and differentiable
- Local Behavior: Each segment of the spline is influenced primarily by the data points in that segment
- Global Smoothness: Despite being piecewise, the entire function is smooth and well-behaved
Why Perfect Interpolation?
This perfect interpolation happens because:
- We have 8 data points and 7 basis functions (plus the intercept)
- The B-spline basis functions are designed to provide maximum flexibility
- Cubic splines have enough degrees of freedom to fit any set of data points exactly
In practice, when we have noise in our data, we might not want perfect interpolation, and we might use regularization or fewer knots to get a smoother fit that generalizes better to new data.