2025-06-06

Introduction

  • Simple Linear Regression is “a statistical method that allows us to summarize and study relationships between two continuous quantitative variables”1: \[ y = \beta_0 + \beta_1 x + \varepsilon \]

    • The variable, x, is known as the independent variable

    • The other variable, y, is known as the dependent variable

    • \(\beta_0\) is the intercept

    • \(\beta_1\) is the slope

    • \(\varepsilon\) is the error term

Least Squares Estimation

  • Least squares and linear regression are closely related, as least squares is “used to find a best-fitting line in linear regression by minimizing the sum of the squared differences between predicted and actual values.”2

  • The slope (\(\beta_1\)) and intercept (\(\beta_0\)) are calculated to minimize the following sum of squared errors, which tells us the residuals or how well the model fits a given dataset:

\[ \text{SSE} = \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \] - Where: - \(y_i\) is the observed value - \(\hat{y}_i\) is the predicted value

Regression Using ggplot (Code)

  • Let’s say we want to find the correlation between how many times someone blinks per minute, x, and their hear rate in beats per minute, y.

#Note that real data is not being used
#Data will be "randomly" generated from a preset random number dataset:
set.seed(123)
#x represents blinks per minute
x <- 1:50
#y represents their heart rate
y <- 35 +1.5 * x + rnorm(50, 0, 10) #Last part is for random noise
data <- data.frame(x,y)

ggplot(data, aes(x = x, y = y)) +
  geom_point(color = "maroon") +
  geom_smooth(method = "lm", se = F, color = "gold") + 
  labs(title = "Blinks Per Minute versus Beats Per Minute",
       x = "Blinks Per Minute",
       y = "Beats Per Minute")

Regression Using ggplot (Plot)

Histogram ggplot of the Residuals (SSE)

  • Note:

    • Positive residuals are a result of the actual y values lying above the regression line

    • Negative residuals are a result of the actual y values lying below the regression line.

Plotly Plot: Adding Stress

  • To add a new variable, a normal 2D graph will not suffice

  • We will be adding a new value to consider, stress (z)

  • Stress will be measured on a scale of 0 to 100

  • Note: We are using a dataset with a preset random number generation, so the random values are not “random”

  • Since there are three variables, it will not be a best fit line, but rather a best fit plane

  • With this in mind, we will now generate our last plot

Plotly Plot: Code Part 1

#Using same "random" seed so data is consistent with last graphs
#We do this since it ensures reproducibility even if it is random data
set.seed(123)
x <- 1:50
y <- 35 + 1.5 * x + rnorm(50, 0, 10)
#Add new dimension to simulate stress "data"
z <- y + rnorm(50, 0, 5)
z <- pmin(z, 100) #Cap stress level at 100
#Can't be more stressed than 100%!

#Multiple linear regression model, correlates x and y with z
  model <- lm(z ~ x + y)
#Want evenly spaced values from min to max for x and y
  x2 <- seq(min(x), max(x), length.out = 50) 
  y2 <- seq(min(y), max(y), length.out = 50)
#Inputs data frame into graph, combines our x and y
  graph <- expand.grid(x = x2, y = y2)
#Predict z values for each x/y pair and adds this as a new column
  graph$z <- predict(model, newdata = graph)

Plotly Plot: Code Part 2

#Generate 3D scatter plot (x,y,z) with best fit plane
plot_ly() %>% #Using pipes here to chain everything together
  #This will generate our scatter points in 3D, Color for ASU
  add_markers(x = x, y = y, z = z, marker = list(color = 'maroon'),
              name = "Test Subjects") %>%
  #Matrix function converts the z values to match the dimensions
add_surface(x = x2, y = y2, 
            z = matrix(graph$z, nrow = 50, ncol = 50),
            colorscale = list(c(0, 1), c('gold', 'gold')),
            opacity = 0.6,
            showscale = FALSE, #TOOK SO LONG TO FIND this code
            name = "Best Fit Plane") %>%
  #Final section sets the title, and configures the 3D axis
  layout(title = "3D Scatter Plot with Best Fit Plane",
         scene = list(
           xaxis = list(title = "Blinks Per Minute"),
           yaxis = list(title = "Beats Per Minute"),
           zaxis = list(title = "Stress Level [%]")
         ))

Plotly Plot: Plot

References