A Comprehensive Guide to Building Polynomial Regression Models in R
Polynomial regression is a powerful technique that allows you to model nonlinear relationships between a dependent variable and one or more independent variables. If a scatterplot between your variables looks curvy rather than like a straight line, polynomial regression can often fit the data much better than simple linear regression.
In this guide, we‘ll walk through the end-to-end process of building, evaluating, and interpreting polynomial regression models in R. Whether you‘re a beginner or have some experience with modeling in R already, you‘ll come away with a solid understanding of how to apply polynomial regression to real-world data. We‘ll also cover some more advanced techniques for optimizing your models.
By the end, you‘ll be ready to use polynomial regression to make predictions, understand complex relationships in your data, and impress your friends, colleagues, and maybe even your statistics professor. Let‘s dive in!
When to Use Polynomial Regression
You should consider using polynomial regression when you observe a curved relationship between your independent and dependent variables. Some examples of nonlinear trends polynomial regression is well-suited for include:
- Modeling the rise and fall in a population over time
- Examining the effect of drug dosage on patient outcomes, where higher doses become counterproductive past a certain point
- Analyzing the relationship between income and happiness, which tends to level off for high earners
- Predicting agricultural crop yields based on temperature and rainfall
Essentially, any time your data points don‘t seem to follow a straight-line pattern, polynomial regression is worth a try. Just keep in mind that more complex models are prone to overfitting, so it‘s important to use proper validation techniques, which we‘ll cover later on.
Step-by-Step: Building a Polynomial Model
Let‘s say we want to predict car fuel efficiency (in miles per gallon) based on the vehicle‘s weight (in pounds). We suspect the relationship may be nonlinear, so we‘ll use polynomial regression. Here‘s how to do it in R:
Step 1: Visualize the Data
Before we start building models, it‘s always a good idea to plot our variables to visualize their relationship. We can use ggplot2 to create a scatterplot:
library(ggplot2)
ggplot(data, aes(x=weight, y=mpg)) +
geom_point() +
geom_smooth()
The geom_smooth() function fits a curved lowess line to the data, revealing the nonlinear trend we suspected. A polynomial model should work well here.
Step 2: Specify Model Degree
The next step is to decide what degree polynomial to use. A quadratic model (2nd degree) is a good place to start for most curved relationships. We can create the polynomial terms using the poly() function:
quadratic_model <- lm(mpg ~ poly(weight, 2), data=data)
This fits a model of the form:
mpg = β0 + β1weight + β2weight^2
For more complex curves, we could try a cubic or higher-degree polynomial.
Step 3: Evaluate Model Fit
After fitting our model, we need to assess how well it fits the data. The summary() function provides key information:
summary(quadratic_model)
# Output:
# Adjusted R-squared: 0.7925
# F-statistic: 259.7 on 2 and 397 DF, p-value: < 2.2e-16
The high adjusted R-squared value and significant F-statistic suggest our quadratic model fits the data well. We can also use anova() to compare the quadratic model to a simple linear one:
linear_model <- lm(mpg ~ weight, data=data)
anova(linear_model, quadratic_model)
# Output:
# Model 1: mpg ~ weight
# Model 2: mpg ~ poly(weight, 2)
# Res.Df RSS Df Sum of Sq F Pr(>F)
# 1 398 1354.5
# 2 397 1007.9 1 346.65 136.52 < 2.2e-16 ***
The ANOVA results confirm the quadratic model provides a significantly better fit.
Step 4: Check Assumptions
As with any regression model, we need to verify our polynomial model meets the key assumptions of linear regression:
- Linearity: The model should be linear in the coefficients (but polynomial in the predictor variables)
- Independence: The residuals should be independent of each other
- Normality: The residuals should follow a normal distribution
- Equal variance: The variance of the residuals should be constant
We can check these assumptions using diagnostic plots:
par(mfrow=c(2,2)) # set up 2x2 grid
plot(quadratic_model)
If there are any major red flags like a strong pattern in the residuals vs fitted plot or residual points deviating substantially from the Q-Q plot diagonal line, we may need to Transform our data or use a different modeling approach.
Step 5: Interpret Coefficients
Once we have a polynomial model that fits well and meets the assumptions reasonably, we can interpret the model coefficients. The coefficients indicate the change in mpg associated with a 1-unit increase in each term.
coefficients(quadratic_model)
# Output:
# (Intercept) poly(weight, 2)1 poly(weight, 2)2
# 40.03120276 -12.81909903 0.08693908
Based on these results, we would expect a car‘s fuel efficiency to decrease by about 12.8 mpg for each 1,000 lb increase in weight, but that penalty diminishes as weight increases due to the positive squared term coefficient.
It‘s important to note these coefficient interpretations only apply in the model‘s units. In this case, the poly() function standardized the weight values, so the coefficients aren‘t very intuitive. If we want coefficients in the original units, we can add the raw=TRUE argument:
quadratic_model_raw <- lm(mpg ~ poly(weight, 2, raw=TRUE), data=data)
coefficients(quadratic_model_raw)
Step 6: Make Predictions
Finally, we can use our model to make predictions for new data points. The predict() function makes this easy:
new_data <- data.frame(weight = c(2000, 3000, 4000))
predict(quadratic_model, newdata=new_data)
# Output:
# 1 2 3
# 35.19545 28.32461 24.22188
Our model predicts a car weighing 2000 lbs would average around 35.2 mpg, while a 4000 lb car would only get about 24.2 mpg.
We can also plot our model‘s predictions against the original data to visualize the fit:
ggplot(data, aes(x=weight, y=mpg)) +
geom_point() +
geom_line(aes(y=predict(quadratic_model_raw, newdata=data)))
Techniques to Improve Polynomial Models
While the example above demonstrates the basic process of polynomial regression, there are several techniques we can use to improve our model‘s performance and generalizability:
Feature Scaling
Recall that the poly() function standardizes the polynomial terms by default. Standardization (subtracting the mean and dividing by the standard deviation) or other scaling methods like normalization (converting to a 0-1 scale) often help polynomial models converge and reduce multicollinearity between higher-order terms.
If using unscaled predictors, be sure to check for high variance inflation factors (VIF):
library(car)
vif(quadratic_model_raw)
VIF values over 5 or 10 indicate problematic multicollinearity.
Regularization
Higher-degree polynomial models risk overfitting the training data and predicting poorly on new data. Regularized regression methods like ridge regression or the lasso add a penalty to the model coefficients, controlling their size to prevent overfitting.
We can use the glmnet package to fit a regularized polynomial model:
library(glmnet)
x <- model.matrix(mpg ~ poly(weight, 2), data=data)[,-1]
y <- data$mpg
cv_fit <- cv.glmnet(x, y, alpha=0)
best_lambda <- cv_fit$lambda.min
best_model <- glmnet(x, y, alpha=0, lambda=best_lambda)
coef(best_model)
This uses cross-validation to find the optimal value of the regularization parameter lambda for a ridge regression model.
Cross-Validation
Speaking of cross-validation, it‘s one of the best ways to estimate a model‘s out-of-sample prediction error and compare different candidate models. We can easily run k-fold cross validation using the train function from the caret package:
library(caret)
train_control <- trainControl(method="cv", number=10)
cv_quad_model <- train(mpg ~ poly(weight,2), data=data,
method="lm", trControl=train_control)
cv_cubic_model <- train(mpg ~ poly(weight,3), data=data,
method="lm", trControl=train_control)
cv_quad_model$results$RMSE
cv_cubic_model$results$RMSE
Comparing the cross-validated root mean squared errors can tell us whether it‘s worth using a more complex cubic model or not.
Avoiding Common Pitfalls
We‘ve covered a lot of ground, but there are a few key things to keep in mind with polynomial regression:
-
Don‘t use a higher degree than you need. Start simple with a quadratic and only add higher-order terms if the data really calls for it.
-
Beware of extrapolation. Polynomial models can fit the observed data well but quickly veer off into nonsense for x-values outside the training range. Avoid making predictions beyond a reasonable range.
-
Check your residual plots! Patterns in your residuals are a major red flag that your model is missing something important.
-
Don‘t neglect the outliers. A polynomial model can sometimes hide the influence of outliers, so be sure to investigate any extreme values that could be skewing your results.
Real-World Applications
Polynomial regression has proven useful across a wide range of fields:
-
In finance, polynomial models can fit non-linear patterns in stock prices, interest rates, and exchange rates over time.
-
Ecologists use polynomial regression to model population dynamics, species diversity, and animal movement in response to environmental conditions.
-
Astronomers model the nonlinear trajectories of planets, comets, and other celestial bodies with polynomial functions.
-
Marketers and economists use polynomial regression to capture saturation and diminishing returns effects in advertising spend, pricing strategies, and consumer demand curves.
-
Epidemiologists have modeled infection rates over time with polynomial curves to predict the rise and fall of disease outbreaks.
-
Civil engineers apply polynomial regression to understand complex relationships between traffic flow, highway design, driver behavior, road conditions, and accident rates.
Wherever there are curvy data trends to decipher, polynomial regression is a versatile tool to have in your back pocket.
Conclusion
We‘ve taken a deep dive into the why, how, and when of polynomial regression in R:
-
Polynomial models extend linear regression to fit non-linear relationships between variables.
-
Building a polynomial regression model in R involves the familiar lm() function along with the poly() function to generate polynomial terms.
-
It‘s critical to evaluate model fit, check regression assumptions through residual plots, and properly interpret the model coefficients.
-
Techniques like feature scaling, regularization, and cross-validation can help optimize polynomial models and combat overfitting.
-
Polynomial regression has diverse applications but should be used judiciously. Simpler models are preferable when they get the job done.
Properly applied, polynomial regression is a powerful way to uncover complex nonlinear patterns in your data. With the foundation from this guide and some practice, you‘ll be on your way to harnessing curvy data like a pro!
Stay tuned – our next post will tackle spline regression for an even more flexible approach to non-linear modeling. Happy modeling!