--- title: "Custom Weights" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Custom Weights} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` ## How Custom Weights Work 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 $j$ in a local fit centred at $x_i$ is: $$w_{ij} = \text{custom\_weights}[j] \times K\!\left(\frac{d_{ij}}{h_i}\right) \times r_j$$ where $K$ is the distance kernel, $h_i$ is the local bandwidth, and $r_j$ is the robustness weight from the current iteration. > **Batch adapter only:** `custom_weights` applies in **Batch** mode. It is > silently ignored in Streaming and Online adapters. --- ## When to Use Custom Weights | Situation | Recommended weight | | --- | --- | | Point known to be erroneous | `0.0` — fully excluded | | Unreliable sensor / low precision | `0.1 – 0.5` | | Standard observation | `1.0` (default) | | Carefully calibrated measurement | `> 1.0` | | Measurement uncertainty $\sigma_i$ | $1 / \sigma_i^2$ | ### Custom Weights vs. Robustness Iterations Both mechanisms handle unreliable data, but they serve different purposes: | | Custom Weights | Robustness Iterations | | --- | --- | --- | | **When known** | Before fitting | Computed from residuals | | **Knowledge required** | Prior knowledge of quality | None — data-driven | | **Effect** | Fixed throughout fit | Adapts each iteration | | **Use case** | Known bad sensors | Unknown 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. --- ## Basic Usage ### Suppress a Known Outlier Set the weight to `0` at the bad point — it is excluded from every local fit that would otherwise include it. ```{r custom_weights_1} library(rfastlowess) x <- 1:10 y <- x * 2.0 y[6] <- 100.0 # spike at index 6 weights <- rep(1.0, 10) weights[6] <- 0.0 # exclude the spike model <- Lowess(fraction = 0.5, iterations = 0L) result <- fit(model, x, y, custom_weights = weights) cat("Smoothed y[0]:", result$y[1], "\n") ``` --- ### Emphasize Important Points Assign high weights to measurements you trust most — calibration standards, reference instruments, or low-noise observations. ```{r custom_weights_2} library(rfastlowess) x <- seq(0, 2 * pi, length.out = 100) y <- sin(x) + 0.1 calibration_indices <- c(6, 21, 41, 61, 81) weights <- rep(1.0, length(x)) weights[calibration_indices] <- 10.0 model <- Lowess(fraction = 0.5) result <- fit(model, x, y, custom_weights = weights) cat("Smoothed y[0]:", result$y[1], "\n") ``` --- ### Propagate Measurement Uncertainty If each observation has a known standard deviation $\sigma_i$, set $w_i = 1 / \sigma_i^2$ to give the fit information-theoretically optimal weighting. ```{r custom_weights_3} library(rfastlowess) x <- seq(0, 2 * pi, length.out = 100) y <- sin(x) + 0.1 sigma <- 0.1 + (seq_along(x) %% 4) * 0.1 weights <- 1 / sigma^2 model <- Lowess(fraction = 0.5) result <- fit(model, x, y, custom_weights = weights) plot(x, y, pch = 16, cex = 0.5 + weights / max(weights), col = "gray", main = "Inverse-Variance Weighted LOWESS") lines(result$x, result$y, col = "blue", lwd = 2) cat("Smoothed y[0]:", result$y[1], "\n") ``` --- ## Combined with Robustness Iterations Custom weights and robustness iterations compose naturally: use custom weights for *known* bad points and robustness for *unknown* contamination. ```{r custom_weights_4} library(rfastlowess) x <- 0:19 y <- x * 1.5 y[4] <- -50.0 # known bad y[13] <- 80.0 # unknown outlier weights <- rep(1.0, 20) weights[4] <- 0.0 model <- Lowess(fraction = 0.4, iterations = 3) result <- fit(model, x, y, custom_weights = weights) cat("Smoothed y[0]:", result$y[1], "\n") ``` --- ## Validation Rules | Rule | Effect | | --- | --- | | Length must equal `n` | Error at fit time if mismatched | | All values must be ≥ 0 | Negative weights are rejected | | All-zero weight vector | Error: no points remain for any local fit | | Uniform weights (`1.0` everywhere) | Identical result to omitting weights | > **Zero-weight windows:** If a local neighbourhood contains only zero-weight > points, the fit at that centre point falls back to the behaviour specified by > `zero_weight_fallback` (default: `"use_local_mean"`). --- ## See Also - [Robustness](robustness.html) — adaptive outlier downweighting via IRLS - `?Lowess` — full parameter reference ```{r session-info} sessionInfo() ```