2025-10-19

Introduction

Simple linear regression models the relationship:

\[ Y = \beta_0 + \beta_1X + \epsilon \]

The Dataset

For this demonstration, we’ll use the built-in trees dataset in R.
It contains measurements of the Girth, Height, and Volume of 31 Black Cherry trees.

head(trees)
##   Girth Height Volume
## 1   8.3     70   10.3
## 2   8.6     65   10.3
## 3   8.8     63   10.2
## 4  10.5     72   16.4
## 5  10.7     81   18.8
## 6  10.8     83   19.7

Visualizing Relationships with ggplot2

We’ll start by examining the relationship between Girth and Volume.

library(ggplot2)
p1 <- ggplot(trees, aes(x = Girth, y = Volume)) + 
  geom_point(color = "#8C1D40", size = 3) + 
  ggtitle("Tree Volume vs. Girth") +
  xlab("Girth (in inches)") + 
  ylab("Volume (in cubic feet)") +
  theme_minimal()
p1

Adding a Regression Line (ggplot2)

The regression model estimates a line that best fits the data.

p2 <- p1 + geom_smooth(method = "lm", se = FALSE, color = "darkblue")
p2
## `geom_smooth()` using formula = 'y ~ x'

\[ \text{Volume} = \beta_0 + \beta_1(\text{Girth}) + \epsilon \]

Model Fitting in R

We can estimate model parameters analytically using lm().

model <- lm(Volume ~ Girth, data = trees)
summary(model)
## 
## Call:
## lm(formula = Volume ~ Girth, data = trees)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -8.065 -3.107  0.152  3.495  9.587 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -36.9435     3.3651  -10.98 7.62e-12 ***
## Girth         5.0659     0.2474   20.48  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4.252 on 29 degrees of freedom
## Multiple R-squared:  0.9353, Adjusted R-squared:  0.9331 
## F-statistic: 419.4 on 1 and 29 DF,  p-value: < 2.2e-16

Interpretation of Coefficients

The equation from our model is approximately:

\[ \widehat{Volume} = -36.94 + 5.07(Girth) \]

This means each unit increase in Girth increases Volume by about 5 cubic feet.

Interactive Plot (Plotly)

Make the regression result interactive with plotly.

library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
fig <- plot_ly(trees, x = ~Girth, y = ~Volume, type = "scatter", mode = "markers",
               marker = list(color = 'rgba(165,0,52,0.7)', size = 9)) %>% 
  add_lines(x = ~Girth, y = fitted(model), name = "Fitted Line", 
            line = list(color = 'blue', width = 3)) %>%
  layout(title = "Interactive Regression Line", 
         xaxis = list(title = "Girth (inches)"), 
         yaxis = list(title = "Volume (cubic feet)"))
fig
## A marker object has been specified, but markers is not in the mode
## Adding markers to the mode...

Mathematical Derivation (LaTeX)

To find the slope and intercept:

\[ \beta_1 = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})} {\sum (x_i - \bar{x})^2} \]

\[ \beta_0 = \bar{y} - \beta_1 \bar{x} \]

These equations minimize the sum of squared residuals (SSR).

Using the Model for Prediction

We can predict tree volume for new Girth values:

new_data <- data.frame(Girth = c(10, 15, 20))
predict(model, new_data)
##        1        2        3 
## 13.71511 39.04439 64.37367

3D Visualization

This shows a 3D simulated surface using synthetic data.

set.seed(123)
x <- seq(5, 20, by=0.5)
y <- seq(50, 100, by=2)
z <- outer(x, y, function(x, y) sin(x/2) + log(y))
plot_ly(x = ~x, y = ~y, z = ~z, type = "surface") %>%
  layout(scene = list(xaxis = list(title="Girth"),
                      yaxis = list(title="Height"),
                      zaxis = list(title="Predicted Volume")))