Skip to content

Custom Weights

Per-observation weights that encode data quality directly into the LOWESS fit.

Standard LOWESS assigns equal prior trust to all observations. Custom weights let you override this assumption point by point — before any distance or robustness weighting is applied.

The effective weight of observation jj in a local fit centred at xix_i is:

wij=custom_weights[j]×K ⁣(dijhi)×rjw_{ij} = \text{custom\_weights}[j] \times K\!\left(\frac{d_{ij}}{h_i}\right) \times r_j

where KK is the distance kernel, hih_i is the local bandwidth, and rjr_j is the robustness weight from the current iteration.

Streaming and Online adapters.

SituationRecommended weight
Point known to be erroneous0.0 — fully excluded
Unreliable sensor / low precision0.1 – 0.5
Standard observation1.0 (default)
Carefully calibrated measurement> 1.0
Measurement uncertainty σi\sigma_i1/σi21 / \sigma_i^2

Both mechanisms handle unreliable data, but they serve different purposes:

Custom WeightsRobustness Iterations
When knownBefore fittingComputed from residuals
Knowledge requiredPrior knowledge of qualityNone — data-driven
EffectFixed throughout fitAdapts each iteration
Use caseKnown bad sensors, calibrationUnknown outlier contamination

They compose: you can use both simultaneously. Custom weights suppress a priori bad points; robustness iterations then handle any residual outliers that remain.


Set the weight to 0 at the bad point — it is excluded from every local fit that would otherwise include it.

const fastlowess = require('fastlowess');
const x = Float64Array.from({length: 10}, (_, i) => i);
const y = Float64Array.from(x, v => v * 2);
y[5] = 100.0; // spike
const weights = new Float64Array(10).fill(1.0);
weights[5] = 0.0; // exclude the spike
const model = new fastlowess.Lowess({fraction: 0.5, iterations: 0});
const result = model.fit(x, y, weights);
console.log("y[0]:", result.y[0].toFixed(4));
y[0]: 0.5726

Assign high weights to measurements you trust most — calibration standards, reference instruments, or low-noise observations.

const fastlowess = require('fastlowess');
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 calibrationIndices = [5, 20, 40, 60, 80];
const weights = new Float64Array(x.length).fill(1.0);
for (const i of calibrationIndices) weights[i] = 10.0;
const model = new fastlowess.Lowess({fraction: 0.5});
const result = model.fit(x, y, weights);
console.log("y[0]:", result.y[0].toFixed(4));
y[0]: 0.0865

If each observation has a known standard deviation σi\sigma_i, set wi=1/σi2w_i = 1 / \sigma_i^2 to give the fit information-theoretically optimal weighting.

const fastlowess = require('fastlowess');
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 sigma = Float64Array.from({ length: n }, (_, i) => 0.1 + ((i*7+3)%17)/17*0.4);
const weights = Float64Array.from(sigma, s => 1.0 / (s * s));
const model = new fastlowess.Lowess({fraction: 0.5});
const result = model.fit(x, y, weights);
console.log("y[0]:", result.y[0].toFixed(4));
y[0]: -0.1265

Custom weights and robustness iterations compose naturally: use custom weights for known bad points and robustness for unknown contamination.

const fastlowess = require('fastlowess');
const x = Float64Array.from({length: 20}, (_, i) => i);
const y = Float64Array.from({length: 20}, (_, i) => i * 1.5);
y[3] = -50.0; // known bad
y[12] = 80.0; // unknown outlier
const weights = new Float64Array(20).fill(1.0);
weights[3] = 0.0;
const model = new fastlowess.Lowess({fraction: 0.4, iterations: 3});
const result = model.fit(x, y, weights);
console.log("y[0]:", result.y[0].toFixed(4));
y[0]: 1.7984

RuleEffect
Length must equal nError at fit time if mismatched
All values must be ≥ 0Negative weights are rejected
All-zero weight vectorError: no points remain for any local fit
Uniform weights (1.0 everywhere)Identical result to omitting weights