Linear Regression—long before transformers and LLMs, it served as one of the first tools in the machine learning toolbox. Despite the rise of complex models, its role in modern statistical analysis remains essential and unshaken.
Rregression models measure the statistical relationship of an dependent variable (\(y\)), and a series of other variables (\(x_i\)). They are widely used for prediction, estimation, hypothesis testing, and modeling causal relationships. Independate variables serve as inputs into a system and take on different values freely. Dependent variables are those values that change as a consequence of change in other values in the system. \(X\) can refers to predictor or explanatory variable. \(Y\) denotes the response variable.
First Order Linear Model
\[Y=\theta_0 + \theta_1 X\]
where Y is the dependent variable, \(\theta_0\) is the y-incercept, \(\theta_1\) is the slop of the line, and \(X\) is the independent variable.
This is the standard \(y=mx + b\) model taught in middle school.
From this, we can create a hypothesis function (model):
\[h_\theta(x) = \theta_0 + \theta_1 x.\]
Note that we use a lowercase \(x\) to denote an individual data point. How do we find the optimal \(\theta\) coefficients? Sure we can plot the data and eye-ball a drawn line where half of the data points lie above and the other half below the line. But consider an application like baseball data. A historic game like baseball has decades of seasons. If we were to model batting average \((\frac{\text{hits}}{\text{at-bats}})\), it would be impossible to guess the best-fitted line by hand. We need a cleverer method.
We turn to least-squares linear regression. Cost function: \[Cost(\theta) = \frac{1}{2\times n}\sum_{i=0}^{n}(h_\theta(x^{(i)}) - y^{(i)})^2.\]
The cost function is takes the average of square-error differences among all data points. We fit by solving \(\text{min}_\theta Cost(\theta)\) or in other words, the parameters \(\theta\) that minimze the mean squared-error (MSE).
Gradient descent is the method we use to find the optimal \(\theta\) values. More formally,
\(\alpha\) is the learning rate. Calculus is inescapable. One of its most powerful contributions to humanity is the ability to systematically find optimal values—a cornerstone of decision-making in science, economics, engineering, and machine learning. Let’s solve for \(\theta_0\) and \(\theta_1\) for first-order linear regression.
We first take the partial derivative with respect to \(\theta_j\)
Baseball is a game of numbers. There exist several statistics to measure a hitter’s offensive contribution. The simplest and well-known metric is batting average (BA or AVG); \(BA=\frac{\text{Hits}}{\text{At-bats}}\). Whlie batting average only considers hits, slugging percentage weights different types of hits, giving more value to extra base hits; \(SLG=\frac{(1B \cdot 1 + 2B \cdot 2 + 3B\cdot 3 + HR\cdot 4)}{AB}\). On-base percentage (\(OBP\)) “refers to how frequently a batter reachers base per plate appearance.” (“Standard StatsGlossary” 2025). \(OPS\) (on-base plus slugging) is an amalgamation of \(OBP\) and \(SLG\). That is, \(OPS=OBP + SLG\). \(OPS\) encapsulates a batter’s power and on-base rate. Lastly, there’s weighted on-base average (\(wOBA\)). \(wOBA\) is an all-empcompasing offensive measurement. Similar to \(SLG\), \(wOBA\) weighs batted-events, however, it does so with a different formula. Each batted event (walks, singles, home run, etc.), is weighted by the adjusted run expectancy in the context of a season.
Figure 1 illustrates the relationships between various baseball statistics and runs. Observe that the strength of the relationship between the independent variables (\(AVG, OBP, SLG, OPS, wOBA\)) and the dependent variable \(R\) (runs) are not the same.
Figure 1: Scatter plots of baseball metrics and runs.
We will need to compute the linear model’s weights if we want to accurate prediction of team runs given a statistic. To hold true to our mathematical derivation, we’ll implement our own linear regression model. Of course, ready-made solutions exist in libraries such as Scikit-Learn.
Code
import numpy as npclass LinearRegression:def__init__(self):self.slope =Noneself.intercept =Nonedef fit(self, X, y): n =len(X) x_mean = np.mean(X) y_mean = np.mean(y) numerator =0 denominator =0for i inrange(n): numerator += (X[i] - x_mean) * (y[i] - y_mean) denominator += (X[i] - x_mean) **2self.slope = numerator / denominatorself.intercept = y_mean -self.slope * x_meandef predict(self, X): y_pred = []for x in X: y_pred.append(self.slope * x +self.intercept)return y_predlong_df["y_pred"] = np.nanmodel_dict = {}# Batting Average Modelfor metric in ["AVG", "OBP", "SLG", "OPS", "wOBA"]: model = LinearRegression() mask = long_df["Metric"] == metric X = long_df.loc[mask, "Value"].to_numpy() y = long_df.loc[mask, "R"].to_numpy() model.fit(X, y) model_dict[metric] = model y_pred = model.predict(X) long_df.loc[mask, "y_pred"] = y_predg = sns.FacetGrid(long_df, col="Metric", col_wrap=3, height=4, sharex=False, sharey=False)g.map_dataframe(sns.scatterplot, x="Value", y="R")g.map_dataframe(sns.lineplot, x="Value", y="y_pred", color="red")g.set_ylabels("Predicted Runs")
Figure 2: Scatter plots of baseball metrics and runs with linear regression line.
Suppose we want to predict a team’s runs given a metric. In 2024, Dodgers had a team OPS of 0.781. Let’s use our newly trained OPS linear regression to predict the team runs.
Code
dodgers_ops =0.781predicted_runs = model_dict["OPS"].predict([dodgers_ops])[0]print(f"Dodgers predicted runs in 2024: {round(predicted_runs)}")print(f"Dodgers actual runs in 2024: {842}")
Dodgers predicted runs in 2024: 821
Dodgers actual runs in 2024: 842
Not bad! The Dodgers currently have an OPS of .801 in their 2025 season. Based on the OPS model, and assuming the Dodgers maintain their high OPS throughout the remaining season, they are slated to score 860 runs.
I’ll have to revisit these models when the 2025 season ends.
Multivariable Linear Regression
Let’s predict exit velocity from swing metrics. This season, Statcast released their swing path and swing length data on BaseballSavant. Granular bat tracking data can reveal mechanical trends that lendthemselves to batting outcomes.
Observe Figure 3. We consider two independent variables: average swing speed and swing length. The dependent variable is average exit velocity.
Figure 3: Scatter plots of average swing speed, swing length, and average exit velocity.
We apply a multivariable linear regression to see if there’s a statistical relationship among average swing speed, swing length, and average exit velocity. To model this relationship, we turn to a vectorized version of the first-order linear regression above. \(y=X.W\) and \(W=(X^T\cdot X)^{-1}X^T\cdot y\).
class MVLinearRegression:def__init__(self):self.W =Nonedef fit(self, X, y):''' X: n x d '''# Add bias term to X -> [1 X] n = X.shape[0] X = np.hstack([np.ones((n, 1)), X])self.W = np.linalg.inv(X.T @ X) @ X.T @ ydef predict(self, X): n = X.shape[0] X = np.hstack([np.ones((n, 1)), X])return X @self.Wdf_train = df[df["year"]<2025]X = df_train[["avg_swing_speed","avg_swing_length"]].to_numpy()y = df_train[["exit_velocity_avg"]].to_numpy().squeeze()model = MVLinearRegression()model.fit(X,y)print(f"Model weights: {model.W}")df_test = df[df["year"]==2025]X_test = df_test[["avg_swing_speed","avg_swing_length"]].to_numpy()y_test = df_test[["exit_velocity_avg"]].to_numpy().squeeze()y_pred = model.predict(X_test)
Model weights: [51.12674671 0.644755 -1.05884044]
Figure 4 depicts multivariable linear regression analysis reveals that swing speed and swing length have opposing effects on exit velocity. Swing speed is a strong positive predictor: for every 1 mph increase in average swing speed, exit velocity increases by approximately 0.64 mph, a relationship that is highly statistically significant. In contrast, swing length shows a significant negative association, with each additional unit of swing length reducing exit velocity by about -1.0 mph when holding swing speed constant. This suggests that while higher swing speeds directly contribute to better batted-ball outcomes, longer swings may hinder efficient energy transfer, potentially due to reduced compactness or timing inefficiencies. Overall, the model highlights the importance of optimizing both speed and mechanical efficiency to maximize exit velocity.
(a) Predicted Exit Velocity as a Function of Swing Speed and Swing Length.
(b)
Figure 4
The residual analysis in Figure 5 for the 2025 test data shows that the multivariable linear regression model predicting exit velocity from average swing speed and swing length produces reasonably centered errors. The histogram of residuals appears roughly symmetric and centered near zero, suggesting that the model does not systematically over- or under-predict exit velocity on unseen data.
Quantitatively, the residuals are relatively small in magnitude, which indicates good calibration. However, the presence of some wider residual spread implies that other unmodeled factors—such as point-of-contact, pitch type, or bat-to-ball precision—may be influencing exit velocity and are not captured by swing speed and swing length alone.
Overall, the model performs well given its simplicity and the limited feature set. It serves as a useful first-order approximation for evaluating how mechanical swing inputs affect batted ball output, but more sophisticated modeling approaches (e.g., nonlinear models or additional features) would likely reduce residual variance and improve predictive accuracy.