Polynomial Degree
Degree of the local polynomial fitted at each point.
Overview
Section titled “Overview”At each target point, LOESS fits a polynomial to the neighbouring data using weighted least squares. The degree parameter controls the order of that polynomial.
| Degree | Local Fit | Captures | Risk |
|---|---|---|---|
0 | Constant | Level only | Over-smooth, biased at edges |
1 | Linear | Trend (default) | Rarely overfits |
2 | Quadratic | Curvature | Overfits with small fraction |
3 | Cubic | Inflections | Requires larger fraction |
4 | Quartic | Fine structure | High variance, rarely needed |
Degree 0 — Local Constant
Section titled “Degree 0 — Local Constant”
The fit at each point is simply a weighted mean. Produces very smooth results but ignores local slope, introducing bias wherever the true function changes.
Use when: Maximum smoothness is more important than accuracy; computationally cheapest option.
const { Loess } = require('fastloess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Loess({ degree: "constant", fraction: 0.5 });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.2935Degree 1 — Local Linear (Default)
Section titled “Degree 1 — Local Linear (Default)”
Fits a weighted line through the neighbourhood. Removes first-order bias and handles boundary regions correctly. The right choice for the vast majority of applications.
Use when: Default; monotone or gently curved data; boundary accuracy matters.
const { Loess } = require('fastloess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Loess({ degree: "linear", fraction: 0.5 });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.1118Degree 2 — Local Quadratic
Section titled “Degree 2 — Local Quadratic”
Fits a weighted parabola through the neighbourhood. Removes second-order bias and captures local curvature more faithfully, but requires more data per neighbourhood — pair with a larger fraction (≥ 0.4) to avoid overfitting.
Use when: Data with pronounced peaks, valleys, or curvature; fraction ≥ 0.4.
const { Loess } = require('fastloess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Loess({ degree: "quadratic", fraction: 0.5 });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.0272Degree 3 — Local Cubic
Section titled “Degree 3 — Local Cubic”
Fits a weighted cubic polynomial. Captures inflection points and S-shaped local behaviour. Requires a substantially larger neighbourhood than degree 2 — use fraction ≥ 0.5 and verify visually for overfitting.
Use when: Data has clear S-shaped curves or multiple inflection points; fraction ≥ 0.5.
const { Loess } = require('fastloess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Loess({ degree: "cubic", fraction: 0.6 });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.0292Degree 4 — Local Quartic
Section titled “Degree 4 — Local Quartic”
Fits a weighted quartic polynomial. Rarely needed in practice; only useful for capturing highly oscillatory local structure. Very prone to overfitting — require fraction ≥ 0.6 and cross-validate.
Use when: Fine oscillatory structure is physically meaningful and the dataset is large; always cross-validate.
const { Loess } = require('fastloess-wasm');
const n = 100;const x = Float64Array.from({ length: n }, (_, i) => i * 2 * Math.PI / (n - 1));const y = Float64Array.from(x, (xi, i) => Math.sin(xi) + (((i * 7 + 3) % 17) / 17 - 0.5) * 0.6);
const model = new Loess({ degree: "quartic", fraction: 0.7 });const result = model.fit(x, y);console.log("y[0]:", result.y[0].toFixed(4));y[0]: 0.0327Choosing the Right Degree
Section titled “Choosing the Right Degree”| Situation | Recommended Degree |
|---|---|
| Monotone trend, general purpose | 1 (default) |
| Maximum smoothness, speed | 0 |
| Clear peaks / valleys / inflections | 2 (with fraction ≥ 0.4) |
| S-shaped curves, multiple inflections | 3 (with fraction ≥ 0.5) |
| Fine oscillatory structure (rare) | 4 (with fraction ≥ 0.6, cross-validate) |
| Boundary accuracy is critical | 1 or 2 (not 0) |
| Very small dataset (n < 50) | 1 |
Higher Degree Effects
Section titled “Higher Degree Effects”Surface Mode
Section titled “Surface Mode”The surface_mode parameter controls whether LOESS evaluates the local polynomial at every query point or at a sparser grid of vertices with Hermite cubic interpolation in between.
| Mode | Behaviour | Speed | Accuracy |
|---|---|---|---|
"interpolation" (default) | Evaluate at anchor vertices, blend via Hermite cubic | Faster | Slight approximation |
"direct" | Evaluate at every query point | Exact | Full precision |