Regression and Curve Fitting

Least squares, R², several inputs, polynomial and regularized fits, residual plots and the danger of extrapolation.

Fitting a line

Regression predicts a number from inputs. The simplest model is a straight line y = m x + b. Least squares picks the line that makes the sum of the squared vertical errors (the residuals) as small as possible. For data points (xi, yi) with means x̄ and ȳ:

m = Σ (x − x̄)(y − ȳ) ÷ Σ (x − x̄)² b = ȳ − m x̄ R² = 1 − SSE ÷ SST

R² is the fraction of the variation in y that the line explains: 1 is perfect, 0 is no better than the average (the baseline in What Machine Learning Is and When to Use It).

Worked example: calibrating a sensor

Five readings: x = 1, 2, 3, 4, 5 (a reference) and y = 2.1, 3.9, 6.2, 7.8, 10.1 (the sensor output).

  • Means: x̄ = 3, ȳ = 6.02. Σ(x − x̄)² = 10; Σ(x − x̄)(y − ȳ) = 19.9.
  • Slope m = 19.9 ÷ 10 = 1.990. Intercept b = 6.02 − 1.99 × 3 = 0.050.
  • Sum of squared errors = 0.107, so R² = 0.9973: the line explains 99.7 % of the variation.
  • Prediction at x = 6: 1.99 × 6 + 0.05 = 11.99 (an extrapolation: see below).
0481201234567x (input)y (output)(1, 2.1)(2, 3.9)(3, 6.2)(4, 7.8)(5, 10.1)prediction at 6: 11.99Least-squares liney = 1.990 x + 0.050R² = 0.9973sum of squared errors = 0.107Residuals (data minus line)are all under 0.25. The fitminimizes their squared sum.Dashed: extrapolation, whichis less trustworthy.
The least-squares line through the five points, with residuals and a prediction beyond the data.
import numpy as np
from sklearn.linear_model import LinearRegression
x = np.array([1, 2, 3, 4, 5]).reshape(-1, 1)
y = np.array([2.1, 3.9, 6.2, 7.8, 10.1])
model = LinearRegression().fit(x, y)
print(model.coef_[0], model.intercept_)     # 1.99 and 0.05
print(model.score(x, y))                    # R squared, about 0.9973
print(model.predict([[6]]))                 # about 11.99

How well is the line known?

The slope and intercept are estimates from a few noisy points; they come with uncertainty. The residual standard deviation is s = √(SSE ÷ (n − 2)), and the standard error of the slope is s ÷ √Σ(x − x̄)².

Worked example: an interval for the slope

  • s = √(0.107 ÷ 3) = 0.189. Standard error of the slope = 0.189 ÷ √10 = 0.060; of the intercept = 0.198.
  • With t = 3.182 (95 %, 3 degrees of freedom) the slope is 1.990 ± 0.190, that is 1.80 to 2.18.
  • Five points give a wide interval; more points across a wider range of x narrow it. Report the interval, not just the slope, when the line is used to make decisions.
  • R² does not tell you the uncertainty of a prediction. A high R² with 5 points can still leave a wide interval.

Several inputs

The same idea extends to many inputs: y = b + m1 x1 + m2 x2 + …, solved by the same least-squares machinery. Extra inputs let the model explain more, at the cost of more parameters to estimate.

Worked example: temperature and airflow

Ten dryer runs record outlet temperature, airflow and product moisture (%). Fitting moisture to temperature alone gives R² = 0.973. Fitting both inputs gives:

  • moisture = 37.04 − 0.313 × T − 0.168 × airflow (both inputs lower the moisture), with R² = 0.998 and an adjusted R² of 0.997.
  • Prediction for T = 72 °C and airflow 30: 9.44 %.
  • Adjusted R² penalizes extra inputs, so it can fall when a useless input is added; plain R² never does.
  • The inputs here are correlated (r = 0.73 between temperature and airflow), so the two coefficients trade off against each other and are less reliable than they look; the combined prediction is still fine inside the range of the data.
  • Include inputs that make physical sense; a coefficient with the wrong sign is a warning that something is confounded.
  • Check units and scale before reading coefficient sizes: a bigger coefficient does not mean a more important input unless the inputs are scaled (see Data Preparation, Splitting and Leakage).
  • Do not add inputs until R² looks good. Judge on held-out data (see Overfitting, Validation and Tuning).

Residuals: is the model right?

A single number such as R² can hide a model that is wrong in a systematic way. Always plot the residuals (data minus model) against the input and against the prediction. They should look like random scatter around zero with a roughly constant spread.

A good R² can hide a wrong model0246810010203040xyR² = 0.960 for the line y = 4.32 x – 6.530246810-404xresidual (data minus line)positive, then negative, then positive: the model is missing a curve
A straight line fitted to curved data: R² looks excellent, but the residuals form a U shape.
Pattern in the residualsMeaningWhat to do
A curve (U or arch)The relationship is not a straight lineAdd a squared term or use a nonlinear model
Spread growing with xThe error is proportional to the valueFit the logarithm, or weight the points
A run of the same signDrift over time or a missing inputPlot against time; add the missing variable
One huge residualA faulty reading or a different regimeCheck the cause before removing it
Residuals correlated with each otherSamples are not independent (time series)Model the dynamics; the standard errors are too small

Curves and the danger of extrapolating

Worked example: line against parabola

  • Ten points follow y ≈ 0.35 x² + 0.5 x + 1 with a little scatter. The straight line has R² = 0.960 and an RMS error of 2.53.
  • Adding an x² term (a quadratic fit) reduces the RMS error to 0.34: the model now matches the shape, and the residuals look like noise.
  • Extrapolate to x = 14: the underlying curve gives 76.6; the line predicts 53.9 (low by 22.7) and the quadratic 76.0. Even a good fit extrapolates badly if the behavior changes, and a wrong model fails fast.
  • Trust interpolation, distrust extrapolation: predictions outside the range of the training inputs have no support from the data. Saturation, yield, boiling and limits all bend curves.
  • High-order polynomials wiggle between and beyond the points; keep the degree low and test on held-out data (see Overfitting, Validation and Tuning).
  • Use physics where you can: a model with the right shape (an exponential, a power law) extrapolates far better than a polynomial.

Exponentials and other curves

Many physical laws become straight lines after a transformation. A cooling curve T = Tamb + ΔT e−t/τ is exponential, but ln(T − Tamb) = ln ΔT − t ÷ τ is a straight line in t, so least squares finds τ.

Worked example: a time constant from a cooling curve

  • A part cools in 22 °C air. Temperatures at t = 0, 60, 120, 180, 240, 300, 360, 420 s are 79.6, 63.8, 51.8, 43.1, 37.6, 33.1, 29.7, 27.3 °C.
  • Fit ln(T − 22) against t: slope = -0.00565, intercept = 4.072.
  • So τ = −1 ÷ slope = 177 s and ΔT = e4.072 = 58.7 °C. The half-time is τ ln 2 = 123 s.
  • Caution: the transformation changes the error weighting (points near the end, where T − Tamb is small, get exaggerated noise). For a precise result use nonlinear least squares (scipy.optimize.curve_fit) starting from this estimate (see Numerical Methods).
LawTransform to a linePlot
y = a ekxln y = ln a + k xln y against x
y = a xnln y = ln a + n ln xln y against ln x (log–log)
y = a + b ÷ xy against 1 ÷ xy against 1 ÷ x
Beta thermistor1 ÷ T = A + B ln R1 ÷ T against ln R

Many inputs and regularization

With many inputs, or inputs that nearly duplicate each other, ordinary least squares gives large, unstable coefficients that swing wildly with small changes in the data. Ridge regression adds a penalty λ Σ m² on the coefficients; lasso penalizes Σ |m| and can set some coefficients exactly to zero, which selects inputs. The penalty trades a little bias for a great deal of stability.

Worked example: two almost identical inputs

Two sensors measure nearly the same thing (x2 ≈ x1 ± 0.1), and y ≈ 2 x1 + 1. The true total effect is about 2.

MethodCoefficient of x1Coefficient of x2Sum
Ordinary least squares1.970.001.97
Ridge, λ = 20.970.951.92
Ridge, λ = 200.790.801.59

The sum is stable, but ordinary least squares puts nearly all of the effect on one input, and with different noise it could just as easily put it on the other. Ridge with λ = 2 shares the effect evenly, a more sensible and more repeatable answer. A much larger penalty (λ = 20) shrinks the total effect to 1.59, too far from 2: the penalty buys stability at the price of bias. Choose λ by validation, not by looking at the training fit (see Overfitting, Validation and Tuning).

from sklearn.linear_model import Ridge, Lasso, RidgeCV
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
model = make_pipeline(StandardScaler(), RidgeCV(alphas=[0.01, 0.1, 1, 10, 100]))   # picks the penalty by cross-validation
model.fit(X_train, y_train)

Calibration as regression

Worked example: correcting a sensor from three reference points

  • A sensor reads 0.31, 50.18, 99.74 at references of 0, 50, 100. Regressing reading on reference gives a gain of 0.9943 and an offset of 0.362.
  • To correct a reading, invert the line: reference = (reading − offset) ÷ gain. A raw reading of 60.20 becomes 60.18.
  • Regress the reading on the reference (the reference is the better known), then invert; keep the coefficients with the data (see Data Quality, Analysis and Reporting).

Related

FAQ

What is a good R²?

It depends on the noise in the data and what you need. For a calibration you may expect 0.999; for a soft sensor on a messy process 0.7 may be useful. Judge by prediction error on new data, in the units of the output, and by the residual plot.

When should I use a polynomial?

When a plot shows a smooth curve and you have no physical law. Keep the degree low (2 or 3), test on held-out data, and never extrapolate with it.

What is the difference between ridge and lasso?

Ridge shrinks all coefficients smoothly; lasso can set some to zero, selecting inputs. Use ridge for correlated inputs, lasso when you suspect only a few matter.

Should I use a neural network instead?

Try the line, then a tree model, first. A network helps with many inputs and strong non-linearity, but needs more data and is harder to check. See Neural Networks and Deep Learning.

References

  • James, G., Witten, D., Hastie, T. and Tibshirani, R., An Introduction to Statistical Learning, chapters 3 and 6.
  • Montgomery, D. C., Peck, E. A. and Vining, G. G., Introduction to Linear Regression Analysis, Wiley.
  • The scikit-learn user guide: linear models; scipy.optimize.curve_fit documentation.

Last reviewed: October 2026. Data in the worked examples are illustrative: the method is what to reuse.