@visactor/vutils 1.0.26 → 1.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.zh-CN.md +17 -0
- package/cjs/common/ascending.js +1 -2
- package/cjs/common/deviation.js +2 -1
- package/cjs/common/getType.js +1 -2
- package/cjs/common/isFunction.js +2 -1
- package/cjs/common/isObject.js +1 -2
- package/cjs/common/isPrototype.js +1 -1
- package/cjs/common/isRegExp.js +1 -1
- package/cjs/common/isShallowEqual.js +1 -1
- package/cjs/common/isString.js +1 -1
- package/cjs/common/isType.js +1 -1
- package/cjs/common/kde.d.ts +4 -0
- package/cjs/common/kde.js +25 -14
- package/cjs/common/kde.js.map +1 -1
- package/cjs/common/regression-lowess.d.ts +1 -1
- package/cjs/common/regression-lowess.js +2 -2
- package/cjs/common/regression-lowess.js.map +1 -1
- package/cjs/data-structure/bounds.js +1 -1
- package/cjs/data-structure/hashTable.js +2 -1
- package/cjs/data-structure/index.js +1 -1
- package/cjs/data-structure/matrix.js +1 -1
- package/cjs/data-structure/point.js +1 -1
- package/dist/index.js +68 -41
- package/dist/index.min.js +15 -15
- package/es/common/ascending.js +1 -2
- package/es/common/deviation.js +2 -1
- package/es/common/getType.js +1 -2
- package/es/common/isFunction.js +2 -1
- package/es/common/isObject.js +1 -2
- package/es/common/isPrototype.js +1 -1
- package/es/common/isRegExp.js +1 -1
- package/es/common/isShallowEqual.js +1 -1
- package/es/common/isString.js +1 -1
- package/es/common/isType.js +1 -1
- package/es/common/kde.d.ts +4 -0
- package/es/common/kde.js +29 -14
- package/es/common/kde.js.map +1 -1
- package/es/common/regression-lowess.d.ts +1 -1
- package/es/common/regression-lowess.js +2 -2
- package/es/common/regression-lowess.js.map +1 -1
- package/es/data-structure/bounds.js +1 -1
- package/es/data-structure/hashTable.js +2 -1
- package/es/data-structure/index.js +1 -1
- package/es/data-structure/matrix.js +1 -1
- package/es/data-structure/point.js +1 -1
- package/package.json +3 -4
- package/REGRESSION.md +0 -36
package/es/common/ascending.js
CHANGED
package/es/common/deviation.js
CHANGED
package/es/common/getType.js
CHANGED
package/es/common/isFunction.js
CHANGED
package/es/common/isObject.js
CHANGED
package/es/common/isPrototype.js
CHANGED
package/es/common/isRegExp.js
CHANGED
package/es/common/isString.js
CHANGED
package/es/common/isType.js
CHANGED
package/es/common/kde.d.ts
CHANGED
|
@@ -22,6 +22,10 @@ export interface KDEOptions {
|
|
|
22
22
|
kernel?: Kernel;
|
|
23
23
|
bandwidth?: number;
|
|
24
24
|
bandwidthMethod?: 'scott' | 'silverman';
|
|
25
|
+
/** Automatic bandwidth uses population deviation by default, preserving existing behavior. */
|
|
26
|
+
standardDeviation?: 'sample' | 'population';
|
|
27
|
+
/** Positive multiplier applied once to either fixed or automatic bandwidth. */
|
|
28
|
+
bandwidthAdjust?: number;
|
|
25
29
|
}
|
|
26
30
|
export interface KDEEvaluator {
|
|
27
31
|
bandwidth: number;
|
package/es/common/kde.js
CHANGED
|
@@ -6,8 +6,11 @@
|
|
|
6
6
|
* - bandwidth selectors: scott, silverman
|
|
7
7
|
* - kde: main function to compute density estimates at provided points
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import { mean } from "./mean";
|
|
10
|
+
|
|
11
|
+
import { variance } from "./variance";
|
|
12
|
+
|
|
13
|
+
/** Gaussian kernel (standard normal) */ export const gaussian = u => 1 / Math.sqrt(2 * Math.PI) * Math.exp(-.5 * u * u);
|
|
11
14
|
|
|
12
15
|
/** Epanechnikov kernel (compact support) */ export const epanechnikov = u => Math.abs(u) <= 1 ? .75 * (1 - u * u) : 0;
|
|
13
16
|
|
|
@@ -26,32 +29,44 @@ export function silverman(n, std, dim = 1) {
|
|
|
26
29
|
|
|
27
30
|
/**
|
|
28
31
|
* Compute standard deviation for numeric array
|
|
29
|
-
*/ function std(values) {
|
|
32
|
+
*/ function std(values, convention) {
|
|
30
33
|
const n = values.length;
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
mean /= n;
|
|
35
|
-
let s = 0;
|
|
34
|
+
if (n < 2) return 0;
|
|
35
|
+
const center = mean(values), differences = [];
|
|
36
|
+
let scale = 0, sourceScale = 1;
|
|
36
37
|
for (let i = 0; i < n; i++) {
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const difference = values[i] - center;
|
|
39
|
+
differences.push(difference), scale = Math.max(scale, Math.abs(difference));
|
|
40
|
+
}
|
|
41
|
+
// Finite values of opposite signs can overflow subtraction although population deviation is representable.
|
|
42
|
+
if (scale === 1 / 0) {
|
|
43
|
+
sourceScale = Math.abs(center);
|
|
44
|
+
for (const value of values) sourceScale = Math.max(sourceScale, Math.abs(value));
|
|
45
|
+
scale = 0;
|
|
46
|
+
for (let i = 0; i < n; i++) differences[i] = values[i] / sourceScale - center / sourceScale,
|
|
47
|
+
scale = Math.max(scale, Math.abs(differences[i]));
|
|
39
48
|
}
|
|
40
|
-
|
|
49
|
+
if (0 === scale) return 0;
|
|
50
|
+
for (let i = 0; i < n; i++) differences[i] /= scale;
|
|
51
|
+
const correction = "population" === convention ? (n - 1) / n : 1;
|
|
52
|
+
return Math.sqrt(variance(differences) * correction) * scale * sourceScale;
|
|
41
53
|
}
|
|
42
54
|
|
|
43
55
|
/**
|
|
44
56
|
* Factory: create a KDE evaluator for given data and options.
|
|
45
57
|
* Usage: const model = kde(data, options); model.evaluate(x) or model.evaluate([x1,x2])
|
|
46
58
|
*/ export function kde(data, options = {}) {
|
|
59
|
+
const deviation = void 0 === options.standardDeviation ? "population" : options.standardDeviation, adjustment = void 0 === options.bandwidthAdjust ? 1 : options.bandwidthAdjust;
|
|
60
|
+
if ("sample" !== deviation && "population" !== deviation) throw new RangeError("standardDeviation must be sample or population");
|
|
61
|
+
if (!Number.isFinite(adjustment) || adjustment <= 0) throw new RangeError("bandwidthAdjust must be finite and positive");
|
|
47
62
|
const n = data.length, kernel = options.kernel || gaussian;
|
|
48
63
|
let h = options.bandwidth;
|
|
49
64
|
if (!h || h <= 0) {
|
|
50
|
-
const sd = std(data) || 0, method = options.bandwidthMethod || "scott";
|
|
65
|
+
const sd = std(data, deviation) || 0, method = options.bandwidthMethod || "scott";
|
|
51
66
|
h = "silverman" === method ? silverman(n, sd, 1) : scott(n, sd, 1);
|
|
52
67
|
}
|
|
53
68
|
// if still zero (constant data), evaluator returns zeros
|
|
54
|
-
|
|
69
|
+
if (h *= adjustment, !h || h <= 0) {
|
|
55
70
|
return {
|
|
56
71
|
bandwidth: 0,
|
|
57
72
|
kernel: kernel,
|
|
@@ -87,7 +102,7 @@ export function silverman(n, std, dim = 1) {
|
|
|
87
102
|
}
|
|
88
103
|
};
|
|
89
104
|
}
|
|
90
|
-
const invNh = 1 /
|
|
105
|
+
const invNh = 1 / n / h;
|
|
91
106
|
function evalPoint(x) {
|
|
92
107
|
let sum = 0;
|
|
93
108
|
for (let j = 0; j < n; j++) sum += kernel((x - data[j]) / h);
|
package/es/common/kde.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/common/kde.ts"],"names":[],"mappings":"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","file":"kde.js","sourcesContent":["/**\n * Kernel Density Estimation (KDE) utilities\n *\n * Exports:\n * - Kernel functions: gaussian, epanechnikov\n * - bandwidth selectors: scott, silverman\n * - kde: main function to compute density estimates at provided points\n */\n\nexport type Kernel = (u: number) => number;\n\n/** Gaussian kernel (standard normal) */\nexport const gaussian: Kernel = (u: number) => {\n const invSqrt2Pi = 1 / Math.sqrt(2 * Math.PI);\n return invSqrt2Pi * Math.exp(-0.5 * u * u);\n};\n\n/** Epanechnikov kernel (compact support) */\nexport const epanechnikov: Kernel = (u: number) => {\n const absu = Math.abs(u);\n return absu <= 1 ? 0.75 * (1 - u * u) : 0;\n};\n\n/**\n * Bandwidth selectors\n * - scott: h = n^{-1/(d+4)} * std\n * - silverman: h = ( (4/(d+2))^{1/(d+4)} ) * n^{-1/(d+4)} * std\n */\nexport function scott(n: number, std: number, dim = 1) {\n if (n <= 0 || std === 0) {\n return 0;\n }\n return std * Math.pow(n, -1 / (dim + 4));\n}\n\nexport function silverman(n: number, std: number, dim = 1) {\n if (n <= 0 || std === 0) {\n return 0;\n }\n const factor = Math.pow(4 / (dim + 2), 1 / (dim + 4));\n return factor * std * Math.pow(n, -1 / (dim + 4));\n}\n\nexport interface KDEOptions {\n kernel?: Kernel;\n bandwidth?: number; // fixed bandwidth\n bandwidthMethod?: 'scott' | 'silverman';\n // if bandwidth not provided, compute from data using method\n}\n\n/**\n * Compute standard deviation for numeric array\n */\nfunction std(values: number[]) {\n const n = values.length;\n if (n === 0) {\n return 0;\n }\n let mean = 0;\n for (let i = 0; i < n; i++) {\n mean += values[i];\n }\n mean /= n;\n let s = 0;\n for (let i = 0; i < n; i++) {\n const d = values[i] - mean;\n s += d * d;\n }\n return Math.sqrt(s / n);\n}\n\nexport interface KDEEvaluator {\n bandwidth: number;\n kernel: Kernel;\n /**\n * Evaluate density at a single point or array of points.\n * - If given a number, returns a number.\n * - If given an array, returns an array aligned with input.\n */\n evaluate: ((x: number) => number) & ((xs: number[]) => number[]);\n /**\n * Produce N uniformly spaced points across the data range and evaluate densities.\n * Returns an array { x: number, y: number }[].\n */\n evaluateGrid: (N: number) => { x: number; y: number }[];\n}\n\n/**\n * Factory: create a KDE evaluator for given data and options.\n * Usage: const model = kde(data, options); model.evaluate(x) or model.evaluate([x1,x2])\n */\nexport function kde(data: number[], options: KDEOptions = {}): KDEEvaluator {\n const n = data.length;\n const kernel = options.kernel || gaussian;\n\n let h = options.bandwidth;\n if (!h || h <= 0) {\n const sd = std(data) || 0;\n const method = options.bandwidthMethod || 'scott';\n if (method === 'silverman') {\n h = silverman(n, sd, 1);\n } else {\n h = scott(n, sd, 1);\n }\n }\n\n // if still zero (constant data), evaluator returns zeros\n if (!h || h <= 0) {\n const zerosEval = (x: number | number[]) => {\n if (Array.isArray(x)) {\n const out: number[] = [];\n for (let i = 0; i < x.length; i++) {\n out.push(0);\n }\n return out;\n }\n return 0;\n };\n const zerosGrid = (N: number) => {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n // compute data min (use data range if available)\n let min = Infinity;\n let max = -Infinity;\n for (let j = 0; j < n; j++) {\n const v = data[j];\n if (v < min) {\n min = v;\n }\n if (v > max) {\n max = v;\n }\n }\n if (min === Infinity || max === -Infinity) {\n for (let i = 0; i < N; i++) {\n out.push({ x: 0, y: 0 });\n }\n return out;\n }\n for (let i = 0; i < N; i++) {\n out.push({ x: min, y: 0 });\n }\n return out;\n };\n return {\n bandwidth: 0,\n kernel,\n evaluate: zerosEval as any,\n evaluateGrid: zerosGrid\n };\n }\n\n const invNh = 1 / (n * h);\n\n function evalPoint(x: number) {\n let sum = 0;\n for (let j = 0; j < n; j++) {\n sum += kernel((x - data[j]) / h);\n }\n return sum * invNh;\n }\n\n function evaluate(x: number | number[]) {\n if (Array.isArray(x)) {\n const out: number[] = [];\n for (let i = 0; i < x.length; i++) {\n out.push(evalPoint(x[i]));\n }\n return out;\n }\n return evalPoint(x as number);\n }\n\n return {\n bandwidth: h,\n kernel,\n evaluate: evaluate as any,\n evaluateGrid(N: number) {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n // compute data range\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < n; i++) {\n const v = data[i];\n if (v < min) {\n min = v;\n }\n if (v > max) {\n max = v;\n }\n }\n if (min === Infinity || max === -Infinity) {\n return out;\n }\n if (min === max) {\n // single point repeated\n for (let i = 0; i < N; i++) {\n out.push({ x: min, y: evalPoint(min) });\n }\n return out;\n }\n\n const step = (max - min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const x = i === N - 1 ? max : min + step * i;\n out.push({ x, y: evalPoint(x) });\n }\n return out;\n }\n };\n}\n\nexport default kde;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/common/kde.ts"],"names":[],"mappings":"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","file":"kde.js","sourcesContent":["/**\n * Kernel Density Estimation (KDE) utilities\n *\n * Exports:\n * - Kernel functions: gaussian, epanechnikov\n * - bandwidth selectors: scott, silverman\n * - kde: main function to compute density estimates at provided points\n */\n\nimport { mean } from './mean';\nimport { variance } from './variance';\n\nexport type Kernel = (u: number) => number;\n\n/** Gaussian kernel (standard normal) */\nexport const gaussian: Kernel = (u: number) => {\n const invSqrt2Pi = 1 / Math.sqrt(2 * Math.PI);\n return invSqrt2Pi * Math.exp(-0.5 * u * u);\n};\n\n/** Epanechnikov kernel (compact support) */\nexport const epanechnikov: Kernel = (u: number) => {\n const absu = Math.abs(u);\n return absu <= 1 ? 0.75 * (1 - u * u) : 0;\n};\n\n/**\n * Bandwidth selectors\n * - scott: h = n^{-1/(d+4)} * std\n * - silverman: h = ( (4/(d+2))^{1/(d+4)} ) * n^{-1/(d+4)} * std\n */\nexport function scott(n: number, std: number, dim = 1) {\n if (n <= 0 || std === 0) {\n return 0;\n }\n return std * Math.pow(n, -1 / (dim + 4));\n}\n\nexport function silverman(n: number, std: number, dim = 1) {\n if (n <= 0 || std === 0) {\n return 0;\n }\n const factor = Math.pow(4 / (dim + 2), 1 / (dim + 4));\n return factor * std * Math.pow(n, -1 / (dim + 4));\n}\n\nexport interface KDEOptions {\n kernel?: Kernel;\n bandwidth?: number; // fixed bandwidth\n bandwidthMethod?: 'scott' | 'silverman';\n /** Automatic bandwidth uses population deviation by default, preserving existing behavior. */\n standardDeviation?: 'sample' | 'population';\n /** Positive multiplier applied once to either fixed or automatic bandwidth. */\n bandwidthAdjust?: number;\n // if bandwidth not provided, compute from data using method\n}\n\n/**\n * Compute standard deviation for numeric array\n */\nfunction std(values: number[], convention: 'sample' | 'population') {\n const n = values.length;\n if (n < 2) {\n return 0;\n }\n const center = mean(values);\n const differences: number[] = [];\n let scale = 0;\n let sourceScale = 1;\n for (let i = 0; i < n; i++) {\n const difference = values[i] - center;\n differences.push(difference);\n scale = Math.max(scale, Math.abs(difference));\n }\n // Finite values of opposite signs can overflow subtraction although population deviation is representable.\n if (scale === Infinity) {\n sourceScale = Math.abs(center);\n for (const value of values) {\n sourceScale = Math.max(sourceScale, Math.abs(value));\n }\n scale = 0;\n for (let i = 0; i < n; i++) {\n differences[i] = values[i] / sourceScale - center / sourceScale;\n scale = Math.max(scale, Math.abs(differences[i]));\n }\n }\n if (scale === 0) {\n return 0;\n }\n for (let i = 0; i < n; i++) {\n differences[i] /= scale;\n }\n const correction = convention === 'population' ? (n - 1) / n : 1;\n return Math.sqrt(variance(differences) * correction) * scale * sourceScale;\n}\n\nexport interface KDEEvaluator {\n bandwidth: number;\n kernel: Kernel;\n /**\n * Evaluate density at a single point or array of points.\n * - If given a number, returns a number.\n * - If given an array, returns an array aligned with input.\n */\n evaluate: ((x: number) => number) & ((xs: number[]) => number[]);\n /**\n * Produce N uniformly spaced points across the data range and evaluate densities.\n * Returns an array { x: number, y: number }[].\n */\n evaluateGrid: (N: number) => { x: number; y: number }[];\n}\n\n/**\n * Factory: create a KDE evaluator for given data and options.\n * Usage: const model = kde(data, options); model.evaluate(x) or model.evaluate([x1,x2])\n */\nexport function kde(data: number[], options: KDEOptions = {}): KDEEvaluator {\n const deviation = options.standardDeviation === undefined ? 'population' : options.standardDeviation;\n const adjustment = options.bandwidthAdjust === undefined ? 1 : options.bandwidthAdjust;\n if (deviation !== 'sample' && deviation !== 'population') {\n throw new RangeError('standardDeviation must be sample or population');\n }\n if (!Number.isFinite(adjustment) || adjustment <= 0) {\n throw new RangeError('bandwidthAdjust must be finite and positive');\n }\n const n = data.length;\n const kernel = options.kernel || gaussian;\n\n let h = options.bandwidth;\n if (!h || h <= 0) {\n const sd = std(data, deviation) || 0;\n const method = options.bandwidthMethod || 'scott';\n if (method === 'silverman') {\n h = silverman(n, sd, 1);\n } else {\n h = scott(n, sd, 1);\n }\n }\n h *= adjustment;\n\n // if still zero (constant data), evaluator returns zeros\n if (!h || h <= 0) {\n const zerosEval = (x: number | number[]) => {\n if (Array.isArray(x)) {\n const out: number[] = [];\n for (let i = 0; i < x.length; i++) {\n out.push(0);\n }\n return out;\n }\n return 0;\n };\n const zerosGrid = (N: number) => {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n // compute data min (use data range if available)\n let min = Infinity;\n let max = -Infinity;\n for (let j = 0; j < n; j++) {\n const v = data[j];\n if (v < min) {\n min = v;\n }\n if (v > max) {\n max = v;\n }\n }\n if (min === Infinity || max === -Infinity) {\n for (let i = 0; i < N; i++) {\n out.push({ x: 0, y: 0 });\n }\n return out;\n }\n for (let i = 0; i < N; i++) {\n out.push({ x: min, y: 0 });\n }\n return out;\n };\n return {\n bandwidth: 0,\n kernel,\n evaluate: zerosEval as any,\n evaluateGrid: zerosGrid\n };\n }\n\n const invNh = 1 / n / h;\n\n function evalPoint(x: number) {\n let sum = 0;\n for (let j = 0; j < n; j++) {\n sum += kernel((x - data[j]) / h);\n }\n return sum * invNh;\n }\n\n function evaluate(x: number | number[]) {\n if (Array.isArray(x)) {\n const out: number[] = [];\n for (let i = 0; i < x.length; i++) {\n out.push(evalPoint(x[i]));\n }\n return out;\n }\n return evalPoint(x as number);\n }\n\n return {\n bandwidth: h,\n kernel,\n evaluate: evaluate as any,\n evaluateGrid(N: number) {\n const out: { x: number; y: number }[] = [];\n if (N <= 0) {\n return out;\n }\n // compute data range\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < n; i++) {\n const v = data[i];\n if (v < min) {\n min = v;\n }\n if (v > max) {\n max = v;\n }\n }\n if (min === Infinity || max === -Infinity) {\n return out;\n }\n if (min === max) {\n // single point repeated\n for (let i = 0; i < N; i++) {\n out.push({ x: min, y: evalPoint(min) });\n }\n return out;\n }\n\n const step = (max - min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const x = i === N - 1 ? max : min + step * i;\n out.push({ x, y: evalPoint(x) });\n }\n return out;\n }\n };\n}\n\nexport default kde;\n"]}
|
|
@@ -5,12 +5,12 @@ import { median } from "./median";
|
|
|
5
5
|
import { computeLinearCIComponents, confidenceCriticalValue, confidenceHalfWidth, stdErrorsAt } from "./regression-utils";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* 局部线性 LOWESS
|
|
8
|
+
* 局部线性 LOWESS。默认全量观测,保留历史参数 span=0.3、iterations=2。
|
|
9
9
|
* delta 显式插值加速;maxSamples 仅保留显式选择的历史抽样用途。
|
|
10
10
|
* predict 与 evaluateGrid 查询构建时固定的同一模型,不触发再拟合。
|
|
11
11
|
*/ export function regressionLowess(data, x = (d => d.x), y = (d => d.y), options = {}) {
|
|
12
12
|
var _a, _b, _c, _d, _e;
|
|
13
|
-
const span = null !== (_a = options.span) && void 0 !== _a ? _a :
|
|
13
|
+
const span = null !== (_a = options.span) && void 0 !== _a ? _a : .3, degree = null !== (_b = options.degree) && void 0 !== _b ? _b : 1, iterations = null !== (_c = options.iterations) && void 0 !== _c ? _c : 2, delta = null !== (_d = options.delta) && void 0 !== _d ? _d : 0, alpha = null !== (_e = options.alpha) && void 0 !== _e ? _e : .05;
|
|
14
14
|
if (!(span > 0 && span <= 1) || !Number.isInteger(iterations) || iterations < 0 || !Number.isFinite(delta) || delta < 0 || 0 !== degree && 1 !== degree || null != options.maxSamples && (!Number.isInteger(options.maxSamples) || options.maxSamples < 2)) throw new RangeError("Invalid LOWESS span, degree, iterations, delta or maxSamples");
|
|
15
15
|
let pts = regressionPoints(data, x, y).sort(((a, b) => a.x - b.x || a.y - b.y));
|
|
16
16
|
if (null != options.maxSamples && pts.length > options.maxSamples) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/common/regression-lowess.ts"],"names":[],"mappings":"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","file":"regression-lowess.js","sourcesContent":["import { regressionPoints, regressionGrid, regressionBasis, normalizeRegression } from './regression-solver';\nimport { median } from './median';\nimport {\n computeLinearCIComponents,\n confidenceCriticalValue,\n confidenceHalfWidth,\n stdErrorsAt\n} from './regression-utils';\n\n/**\n * 局部线性 LOWESS。默认全量观测、span=2/3、三次稳健重加权。\n * delta 显式插值加速;maxSamples 仅保留显式选择的历史抽样用途。\n * predict 与 evaluateGrid 查询构建时固定的同一模型,不触发再拟合。\n */\nexport function regressionLowess(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options: {\n span?: number;\n degree?: 1 | 0;\n iterations?: number;\n alpha?: number;\n maxSamples?: number;\n delta?: number;\n } = {}\n) {\n const span = options.span ?? 2 / 3;\n const degree = options.degree ?? 1;\n const iterations = options.iterations ?? 3;\n const delta = options.delta ?? 0;\n const alpha = options.alpha ?? 0.05;\n if (\n !(span > 0 && span <= 1) ||\n !Number.isInteger(iterations) ||\n iterations < 0 ||\n !Number.isFinite(delta) ||\n delta < 0 ||\n (degree !== 0 && degree !== 1) ||\n (options.maxSamples != null && (!Number.isInteger(options.maxSamples) || options.maxSamples < 2))\n ) {\n throw new RangeError('Invalid LOWESS span, degree, iterations, delta or maxSamples');\n }\n let pts = regressionPoints(data, x, y).sort((a, b) => a.x - b.x || a.y - b.y);\n if (options.maxSamples != null && pts.length > options.maxSamples) {\n const full = pts;\n const count = options.maxSamples;\n pts = Array.from({ length: count }, (_, i) => full[Math.floor((i * (full.length - 1)) / (count - 1))]);\n }\n const n = pts.length;\n const ptsX = pts.map(p => p.x);\n const ptsY = pts.map(p => p.y);\n const basis = regressionBasis(pts);\n const normalizedX = ptsX.map(v => normalizeRegression(v, basis.xCenter, basis.xScale));\n const normalizedY = ptsY.map(v => normalizeRegression(v, basis.yCenter, basis.yScale));\n const count = Math.min(n, Math.max(2, Math.floor(span * n + 1e-10)));\n let robustWeights: number[] | undefined;\n\n function exact(x0: number) {\n if (!n) {\n return 0;\n }\n const query = normalizeRegression(x0, basis.xCenter, basis.xScale);\n // 找到连续的最近邻窗口;相等距离选择较小的 x(ties 的 y 已排序)。\n let left = 0;\n let right = n - count;\n while (left < right) {\n const mid = (left + right) >>> 1;\n const lowerDistance = x0 - ptsX[mid];\n const upperDistance = ptsX[mid + count] - x0;\n if (\n Number.isFinite(lowerDistance) && Number.isFinite(upperDistance)\n ? lowerDistance > upperDistance\n : query - normalizedX[mid] > normalizedX[mid + count] - query\n ) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let start = left;\n let end = left + count;\n if (ptsX[start] === ptsX[end - 1]) {\n while (start > 0 && ptsX[start - 1] === ptsX[start]) {\n start--;\n }\n while (end < n && ptsX[end] === ptsX[start]) {\n end++;\n }\n }\n const rawRadius = Math.max(Math.abs(ptsX[start] - x0), Math.abs(ptsX[end - 1] - x0));\n const scaled = !Number.isFinite(rawRadius);\n const radius = scaled\n ? Math.max(Math.abs(normalizedX[start] - query), Math.abs(normalizedX[end - 1] - query))\n : rawRadius;\n // 局部响应坐标不能由远处、未参与该邻域的观测决定精度。\n let yMin = Infinity;\n let yMax = -Infinity;\n for (let i = start; i < end; i++) {\n yMin = Math.min(yMin, ptsY[i]);\n yMax = Math.max(yMax, ptsY[i]);\n }\n const yCenter = yMin / 2 + yMax / 2;\n const yScale = Math.max(Math.abs(yMin - yCenter), Math.abs(yMax - yCenter)) || 1;\n let sw = 0;\n let sx = 0;\n let sy = 0;\n let sxx = 0;\n let sxy = 0;\n for (let i = start; i < end; i++) {\n const z = radius === 0 ? 0 : (scaled ? normalizedX[i] - query : ptsX[i] - x0) / radius;\n const u = Math.abs(z);\n const t = u >= 1 ? 0 : 1 - u * u * u;\n const w = t * t * t * (robustWeights ? robustWeights[i] : 1);\n sw += w;\n sx += w * z;\n const response = normalizeRegression(ptsY[i], yCenter, yScale);\n sy += w * response;\n sxx += w * z * z;\n sxy += w * z * response;\n }\n if (sw === 0) {\n // 核边界零权重时使用最近有效观测的加权常数;等距离取均值。\n let distance = Infinity;\n let weight = 0;\n let value = 0;\n for (let i = 0; i < n; i++) {\n const w = robustWeights ? robustWeights[i] : 1;\n if (w === 0) {\n continue;\n }\n const d = Math.abs(scaled ? normalizedX[i] - query : ptsX[i] - x0);\n if (d < distance) {\n distance = d;\n weight = w;\n value = ptsY[i];\n } else if (d === distance) {\n value = value * (weight / (weight + w)) + ptsY[i] * (w / (weight + w));\n weight += w;\n }\n }\n if (weight === 0) {\n throw new RangeError('LOWESS has no effective local observations');\n }\n return value;\n }\n const mx = sx / sw;\n const my = sy / sw;\n const variance = sxx / sw - mx * mx;\n const slope = degree === 0 || variance <= Number.EPSILON * 32 ? 0 : (sxy / sw - mx * my) / variance;\n return yCenter + yScale * (my - slope * mx);\n }\n\n // delta 不删除观测。只减少局部回归求值位置,全部残差参与重加权。\n const anchors: number[] = [];\n for (let i = 0; i < n; ) {\n anchors.push(i);\n if (i === n - 1) {\n break;\n }\n let next = i + 1;\n if (delta > 0) {\n while (next + 1 < n && ptsX[next + 1] - ptsX[i] <= delta) {\n next++;\n }\n }\n // 重复 x 一起使用同一预测;端点不能丢失。\n while (next + 1 < n && ptsX[next + 1] === ptsX[next]) {\n next++;\n }\n i = next;\n }\n let fits = new Array<number>(n);\n function fitObservations() {\n const out = new Array<number>(n);\n for (let a = 0; a < anchors.length; a++) {\n const index = anchors[a];\n out[index] = exact(ptsX[index]);\n if (a === 0) {\n continue;\n }\n const previous = anchors[a - 1];\n const rawWidth = ptsX[index] - ptsX[previous];\n const width = Number.isFinite(rawWidth) ? rawWidth : normalizedX[index] - normalizedX[previous];\n for (let i = previous + 1; i < index; i++) {\n const t =\n width === 0\n ? 0\n : (Number.isFinite(rawWidth) ? ptsX[i] - ptsX[previous] : normalizedX[i] - normalizedX[previous]) / width;\n out[i] = out[previous] * (1 - t) + out[index] * t;\n }\n }\n return out;\n }\n for (let iteration = 0; iteration <= iterations; iteration++) {\n fits = fitObservations();\n if (iteration === iterations) {\n break;\n }\n const residuals = fits.map((v, i) => {\n const residual = ptsY[i] - v;\n return Number.isFinite(residual)\n ? Math.abs(residual / basis.yScale)\n : Math.abs(normalizedY[i] - normalizeRegression(v, basis.yCenter, basis.yScale));\n });\n const med = median(residuals.slice());\n const currentFits = fits;\n robustWeights = residuals.map((r, i) => {\n if (med === 0) {\n const tolerance = Number.EPSILON * 64 * (Math.max(Math.abs(ptsY[i]), Math.abs(currentFits[i])) / basis.yScale);\n return r <= tolerance ? 1 : 0;\n }\n const u = r / (6 * med);\n return u >= 1 ? 0 : (1 - u * u) ** 2;\n });\n }\n function predictSingle(x0: number): number {\n if (delta === 0 || n < 2 || x0 < ptsX[0] || x0 > ptsX[n - 1]) {\n return exact(x0);\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = (lo + hi) >>> 1;\n if (ptsX[mid] <= x0) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n if (ptsX[hi] === ptsX[lo]) {\n return fits[lo];\n }\n const width = ptsX[hi] - ptsX[lo];\n const t = Number.isFinite(width)\n ? (x0 - ptsX[lo]) / width\n : (normalizeRegression(x0, basis.xCenter, basis.xScale) - normalizedX[lo]) / (normalizedX[hi] - normalizedX[lo]);\n return fits[lo] * (1 - t) + fits[hi] * t;\n }\n function predict(x0: number | number[]) {\n return Array.isArray(x0) ? x0.map(predictSingle) : predictSingle(x0);\n }\n function evaluateGrid(N: number) {\n return regressionGrid(ptsX[0], ptsX[n - 1], N, predictSingle);\n }\n\n function confidenceInterval(N: number = 50) {\n const out: { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[] = [];\n\n if (N <= 0) {\n return out;\n }\n if (n === 0) {\n return out;\n }\n\n // use data x-range (already sorted)\n const min = ptsX[0];\n const max = ptsX[n - 1];\n\n if (min === undefined || max === undefined || min === Infinity || max === -Infinity) {\n return out;\n }\n\n const comps = computeLinearCIComponents(data, x, y, (xx: number) => predictSingle(xx));\n if (comps.n === 0) {\n return out;\n }\n\n const z = confidenceCriticalValue(alpha);\n if (comps.min === comps.max) {\n const v = predictSingle(comps.min);\n const errs = stdErrorsAt(comps.min, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n for (let i = 0; i < N; i++) {\n out.push({\n x: comps.min,\n mean: v,\n lower: v - meanHalfWidth,\n upper: v + meanHalfWidth,\n predLower: v - predHalfWidth,\n predUpper: v + predHalfWidth\n });\n }\n return out;\n }\n\n const step = (max - min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n const yh = predictSingle(px);\n const errs = stdErrorsAt(px, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n out.push({\n x: px,\n mean: yh,\n lower: yh - meanHalfWidth,\n upper: yh + meanHalfWidth,\n predLower: yh - predHalfWidth,\n predUpper: yh + predHalfWidth\n });\n }\n return out;\n }\n\n return {\n predict,\n evaluate: predict,\n evaluateGrid,\n confidenceInterval,\n // 节点值按 x 排序,重复观测仍保持其统计权重。\n fitted: pts.map((p, i) => ({ x: p.x, y: fits[i] }))\n };\n}\nexport default regressionLowess;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/common/regression-lowess.ts"],"names":[],"mappings":"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","file":"regression-lowess.js","sourcesContent":["import { regressionPoints, regressionGrid, regressionBasis, normalizeRegression } from './regression-solver';\nimport { median } from './median';\nimport {\n computeLinearCIComponents,\n confidenceCriticalValue,\n confidenceHalfWidth,\n stdErrorsAt\n} from './regression-utils';\n\n/**\n * 局部线性 LOWESS。默认全量观测,保留历史参数 span=0.3、iterations=2。\n * delta 显式插值加速;maxSamples 仅保留显式选择的历史抽样用途。\n * predict 与 evaluateGrid 查询构建时固定的同一模型,不触发再拟合。\n */\nexport function regressionLowess(\n data: any[],\n x: (d: any) => number = d => d.x,\n y: (d: any) => number = d => d.y,\n options: {\n span?: number;\n degree?: 1 | 0;\n iterations?: number;\n alpha?: number;\n maxSamples?: number;\n delta?: number;\n } = {}\n) {\n const span = options.span ?? 0.3;\n const degree = options.degree ?? 1;\n const iterations = options.iterations ?? 2;\n const delta = options.delta ?? 0;\n const alpha = options.alpha ?? 0.05;\n if (\n !(span > 0 && span <= 1) ||\n !Number.isInteger(iterations) ||\n iterations < 0 ||\n !Number.isFinite(delta) ||\n delta < 0 ||\n (degree !== 0 && degree !== 1) ||\n (options.maxSamples != null && (!Number.isInteger(options.maxSamples) || options.maxSamples < 2))\n ) {\n throw new RangeError('Invalid LOWESS span, degree, iterations, delta or maxSamples');\n }\n let pts = regressionPoints(data, x, y).sort((a, b) => a.x - b.x || a.y - b.y);\n if (options.maxSamples != null && pts.length > options.maxSamples) {\n const full = pts;\n const count = options.maxSamples;\n pts = Array.from({ length: count }, (_, i) => full[Math.floor((i * (full.length - 1)) / (count - 1))]);\n }\n const n = pts.length;\n const ptsX = pts.map(p => p.x);\n const ptsY = pts.map(p => p.y);\n const basis = regressionBasis(pts);\n const normalizedX = ptsX.map(v => normalizeRegression(v, basis.xCenter, basis.xScale));\n const normalizedY = ptsY.map(v => normalizeRegression(v, basis.yCenter, basis.yScale));\n const count = Math.min(n, Math.max(2, Math.floor(span * n + 1e-10)));\n let robustWeights: number[] | undefined;\n\n function exact(x0: number) {\n if (!n) {\n return 0;\n }\n const query = normalizeRegression(x0, basis.xCenter, basis.xScale);\n // 找到连续的最近邻窗口;相等距离选择较小的 x(ties 的 y 已排序)。\n let left = 0;\n let right = n - count;\n while (left < right) {\n const mid = (left + right) >>> 1;\n const lowerDistance = x0 - ptsX[mid];\n const upperDistance = ptsX[mid + count] - x0;\n if (\n Number.isFinite(lowerDistance) && Number.isFinite(upperDistance)\n ? lowerDistance > upperDistance\n : query - normalizedX[mid] > normalizedX[mid + count] - query\n ) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let start = left;\n let end = left + count;\n if (ptsX[start] === ptsX[end - 1]) {\n while (start > 0 && ptsX[start - 1] === ptsX[start]) {\n start--;\n }\n while (end < n && ptsX[end] === ptsX[start]) {\n end++;\n }\n }\n const rawRadius = Math.max(Math.abs(ptsX[start] - x0), Math.abs(ptsX[end - 1] - x0));\n const scaled = !Number.isFinite(rawRadius);\n const radius = scaled\n ? Math.max(Math.abs(normalizedX[start] - query), Math.abs(normalizedX[end - 1] - query))\n : rawRadius;\n // 局部响应坐标不能由远处、未参与该邻域的观测决定精度。\n let yMin = Infinity;\n let yMax = -Infinity;\n for (let i = start; i < end; i++) {\n yMin = Math.min(yMin, ptsY[i]);\n yMax = Math.max(yMax, ptsY[i]);\n }\n const yCenter = yMin / 2 + yMax / 2;\n const yScale = Math.max(Math.abs(yMin - yCenter), Math.abs(yMax - yCenter)) || 1;\n let sw = 0;\n let sx = 0;\n let sy = 0;\n let sxx = 0;\n let sxy = 0;\n for (let i = start; i < end; i++) {\n const z = radius === 0 ? 0 : (scaled ? normalizedX[i] - query : ptsX[i] - x0) / radius;\n const u = Math.abs(z);\n const t = u >= 1 ? 0 : 1 - u * u * u;\n const w = t * t * t * (robustWeights ? robustWeights[i] : 1);\n sw += w;\n sx += w * z;\n const response = normalizeRegression(ptsY[i], yCenter, yScale);\n sy += w * response;\n sxx += w * z * z;\n sxy += w * z * response;\n }\n if (sw === 0) {\n // 核边界零权重时使用最近有效观测的加权常数;等距离取均值。\n let distance = Infinity;\n let weight = 0;\n let value = 0;\n for (let i = 0; i < n; i++) {\n const w = robustWeights ? robustWeights[i] : 1;\n if (w === 0) {\n continue;\n }\n const d = Math.abs(scaled ? normalizedX[i] - query : ptsX[i] - x0);\n if (d < distance) {\n distance = d;\n weight = w;\n value = ptsY[i];\n } else if (d === distance) {\n value = value * (weight / (weight + w)) + ptsY[i] * (w / (weight + w));\n weight += w;\n }\n }\n if (weight === 0) {\n throw new RangeError('LOWESS has no effective local observations');\n }\n return value;\n }\n const mx = sx / sw;\n const my = sy / sw;\n const variance = sxx / sw - mx * mx;\n const slope = degree === 0 || variance <= Number.EPSILON * 32 ? 0 : (sxy / sw - mx * my) / variance;\n return yCenter + yScale * (my - slope * mx);\n }\n\n // delta 不删除观测。只减少局部回归求值位置,全部残差参与重加权。\n const anchors: number[] = [];\n for (let i = 0; i < n; ) {\n anchors.push(i);\n if (i === n - 1) {\n break;\n }\n let next = i + 1;\n if (delta > 0) {\n while (next + 1 < n && ptsX[next + 1] - ptsX[i] <= delta) {\n next++;\n }\n }\n // 重复 x 一起使用同一预测;端点不能丢失。\n while (next + 1 < n && ptsX[next + 1] === ptsX[next]) {\n next++;\n }\n i = next;\n }\n let fits = new Array<number>(n);\n function fitObservations() {\n const out = new Array<number>(n);\n for (let a = 0; a < anchors.length; a++) {\n const index = anchors[a];\n out[index] = exact(ptsX[index]);\n if (a === 0) {\n continue;\n }\n const previous = anchors[a - 1];\n const rawWidth = ptsX[index] - ptsX[previous];\n const width = Number.isFinite(rawWidth) ? rawWidth : normalizedX[index] - normalizedX[previous];\n for (let i = previous + 1; i < index; i++) {\n const t =\n width === 0\n ? 0\n : (Number.isFinite(rawWidth) ? ptsX[i] - ptsX[previous] : normalizedX[i] - normalizedX[previous]) / width;\n out[i] = out[previous] * (1 - t) + out[index] * t;\n }\n }\n return out;\n }\n for (let iteration = 0; iteration <= iterations; iteration++) {\n fits = fitObservations();\n if (iteration === iterations) {\n break;\n }\n const residuals = fits.map((v, i) => {\n const residual = ptsY[i] - v;\n return Number.isFinite(residual)\n ? Math.abs(residual / basis.yScale)\n : Math.abs(normalizedY[i] - normalizeRegression(v, basis.yCenter, basis.yScale));\n });\n const med = median(residuals.slice());\n const currentFits = fits;\n robustWeights = residuals.map((r, i) => {\n if (med === 0) {\n const tolerance = Number.EPSILON * 64 * (Math.max(Math.abs(ptsY[i]), Math.abs(currentFits[i])) / basis.yScale);\n return r <= tolerance ? 1 : 0;\n }\n const u = r / (6 * med);\n return u >= 1 ? 0 : (1 - u * u) ** 2;\n });\n }\n function predictSingle(x0: number): number {\n if (delta === 0 || n < 2 || x0 < ptsX[0] || x0 > ptsX[n - 1]) {\n return exact(x0);\n }\n let lo = 0;\n let hi = n - 1;\n while (hi - lo > 1) {\n const mid = (lo + hi) >>> 1;\n if (ptsX[mid] <= x0) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n if (ptsX[hi] === ptsX[lo]) {\n return fits[lo];\n }\n const width = ptsX[hi] - ptsX[lo];\n const t = Number.isFinite(width)\n ? (x0 - ptsX[lo]) / width\n : (normalizeRegression(x0, basis.xCenter, basis.xScale) - normalizedX[lo]) / (normalizedX[hi] - normalizedX[lo]);\n return fits[lo] * (1 - t) + fits[hi] * t;\n }\n function predict(x0: number | number[]) {\n return Array.isArray(x0) ? x0.map(predictSingle) : predictSingle(x0);\n }\n function evaluateGrid(N: number) {\n return regressionGrid(ptsX[0], ptsX[n - 1], N, predictSingle);\n }\n\n function confidenceInterval(N: number = 50) {\n const out: { x: number; mean: number; lower: number; upper: number; predLower: number; predUpper: number }[] = [];\n\n if (N <= 0) {\n return out;\n }\n if (n === 0) {\n return out;\n }\n\n // use data x-range (already sorted)\n const min = ptsX[0];\n const max = ptsX[n - 1];\n\n if (min === undefined || max === undefined || min === Infinity || max === -Infinity) {\n return out;\n }\n\n const comps = computeLinearCIComponents(data, x, y, (xx: number) => predictSingle(xx));\n if (comps.n === 0) {\n return out;\n }\n\n const z = confidenceCriticalValue(alpha);\n if (comps.min === comps.max) {\n const v = predictSingle(comps.min);\n const errs = stdErrorsAt(comps.min, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n for (let i = 0; i < N; i++) {\n out.push({\n x: comps.min,\n mean: v,\n lower: v - meanHalfWidth,\n upper: v + meanHalfWidth,\n predLower: v - predHalfWidth,\n predUpper: v + predHalfWidth\n });\n }\n return out;\n }\n\n const step = (max - min) / (N - 1);\n for (let i = 0; i < N; i++) {\n const px = i === N - 1 ? max : min + step * i;\n const yh = predictSingle(px);\n const errs = stdErrorsAt(px, comps);\n const meanHalfWidth = confidenceHalfWidth(z, errs.seMean);\n const predHalfWidth = confidenceHalfWidth(z, errs.sePred);\n out.push({\n x: px,\n mean: yh,\n lower: yh - meanHalfWidth,\n upper: yh + meanHalfWidth,\n predLower: yh - predHalfWidth,\n predUpper: yh + predHalfWidth\n });\n }\n return out;\n }\n\n return {\n predict,\n evaluate: predict,\n evaluateGrid,\n confidenceInterval,\n // 节点值按 x 排序,重复观测仍保持其统计权重。\n fitted: pts.map((p, i) => ({ x: p.x, y: fits[i] }))\n };\n}\nexport default regressionLowess;\n"]}
|
|
@@ -150,4 +150,4 @@ export class Matrix {
|
|
|
150
150
|
out.e = oe + oa * rotateCenterX + oc * rotateCenterY - a1 * offsetX - c1 * offsetY,
|
|
151
151
|
out.f = of + ob * rotateCenterX + od * rotateCenterY - b1 * offsetX - d1 * offsetY;
|
|
152
152
|
}
|
|
153
|
-
//# sourceMappingURL=matrix.js.map
|
|
153
|
+
//# sourceMappingURL=matrix.js.map
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visactor/vutils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.28",
|
|
4
4
|
"main": "cjs/index.js",
|
|
5
5
|
"module": "es/index.js",
|
|
6
6
|
"types": "es/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"cjs",
|
|
9
9
|
"es",
|
|
10
|
-
"dist"
|
|
11
|
-
"REGRESSION.md"
|
|
10
|
+
"dist"
|
|
12
11
|
],
|
|
13
12
|
"description": "util",
|
|
14
13
|
"author": {
|
|
@@ -37,8 +36,8 @@
|
|
|
37
36
|
"typescript": "4.9.5",
|
|
38
37
|
"@types/node": "*",
|
|
39
38
|
"@internal/bundler": "0.0.1",
|
|
40
|
-
"@internal/eslint-config": "0.0.1",
|
|
41
39
|
"@internal/ts-config": "0.0.1",
|
|
40
|
+
"@internal/eslint-config": "0.0.1",
|
|
42
41
|
"@internal/jest-config": "0.0.1"
|
|
43
42
|
},
|
|
44
43
|
"dependencies": {
|
package/REGRESSION.md
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# 一元回归与成对 bootstrap 契约
|
|
2
|
-
|
|
3
|
-
本轮修正面向 VUtil 1.0.25 的回归工具;正式 npm 1.0.25 不包含这些修复和新 API。
|
|
4
|
-
|
|
5
|
-
- regressionLinear:使用中心化/缩放的一元 OLS,预测在稳定坐标中求值,保留 coef.a/b。增加 rank;常量 x 的历史常数估计继续有定义,图表需要可识别斜率时由输入边界拒绝。
|
|
6
|
-
- regressionPolynomial:以归一化设计矩阵做增量 Givens QR;秩不足时对小型 R 做 Jacobi SVD 得到最小范数解,增加 rank,不再返回伪造零系数。coef 保持升幂的原始 x 坐标含义,predict 用稳定基底。degree 为非负整数,默认仍为 0。原始系数不能有限表示时明确报 RangeError。
|
|
7
|
-
- regressionLowess:默认 span 从 0.3 改为 2/3、iterations 从 2 改为 3,使用全部有效观测;不再隐藏抽样或按 N 关闭稳健迭代。拟合时固定稳健状态,predict/evaluateGrid/fitted 节点一致。显式 maxSamples 保留历史抽样用途,并包含端点;delta 默认为 0,正值以观测锚点插值加速,全量观测仍参与局部权重与稳健残差。fitted 按 x 排序,保留重复样本。此默认行为调整会改变旧 LOWESS 曲线,调用方需要明确选择参数。
|
|
8
|
-
- LOWESS 使用查询点附近的局部 x/y 坐标,避免远处观测压缩近邻精度;只有距离或插值区间溢出时才改用归一化 x 距离。
|
|
9
|
-
- 等距离邻域选择较小 x,再按 y 排序,不依赖调用方行顺序。相同 x 的零半径邻域包含所有相同 x 观测。零核权重时用最近有效观测的加权常数,等距离取均值;没有有效稳健观测时明确报错。median=0 时保留数值精度内零残差点的权重,对明显非零残差赋零权重。
|
|
10
|
-
- regressionBootstrap 从包根导出,仅 linear/polynomial。options 为 method/degree?/grid/level/resamples/seed,完整 (x,y) 成对有放回抽样,每次拟合一次。原始组须有满秩设计及正残差自由度,退化重采样在原始固定归一化基底中取最小范数解,不删抽样或重抽。每个 grid 位置按线性插值分位数生成 lower/upper,表示均值响应的逐点 percentile CI,不是预测区间。
|
|
11
|
-
|
|
12
|
-
既有 confidenceInterval 的正态临界值与旧区间用途没有在本轮改成 bootstrap。尤其旧多项式/LOWESS 区间近似不能用来声称符合新的回归置信带契约;完整整理独立处理。
|
|
13
|
-
|
|
14
|
-
缺失 accessor 的既有排除行为保留;无穷大不参与拟合,StatPlots 另有更严格的有限原始观测边界。新增求解器不修改输入。bootstrap 在内部对配对排序,同组同 seed 可复现;不承诺与 NumPy RNG 相同。
|
|
15
|
-
|
|
16
|
-
独立数值对照使用 __tests__/fixtures/regression-python.json 的固定参考数据,文件记录参考环境的 Python、NumPy 和 statsmodels 版本;TypeScript 测试直接读取 JSON,无需 Python 运行环境。LOWESS 正常非退化数据对照 statsmodels,bootstrap 重放同一抽样索引后对照 NumPy 最小二乘与分位数。退化/ties 行为及坐标基底差异单独声明,不承诺全部参数逐位相同。
|
|
17
|
-
|
|
18
|
-
性能在真实 Node 构建产物测量,避免 Jest VM 对 Math 属性代理的显著额外成本;先 npm run build,再运行 lowess-performance.test.ts 或 node benchmarks/lowess.cjs。保留原 100/150/200ms 预算,使用显式 delta 并断言所有节点保留,精确路径另由数值测试和浏览器实测覆盖。VUtils 的 Jest 配置使用单 worker,CI 的 Rush test 使用 --parallelism 1,避免同包或其他包并发测试影响墙钟预算;所有单元与性能用例均执行。
|
|
19
|
-
|
|
20
|
-
## 调用示例
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
import { regressionLinear, regressionBootstrap, regressionLowess } from '@visactor/vutils';
|
|
24
|
-
|
|
25
|
-
const samples = [{ x: 0, y: 1 }, { x: 1, y: 3 }, { x: 2, y: 4 }, { x: 3, y: 7 }];
|
|
26
|
-
const model = regressionLinear(samples);
|
|
27
|
-
const curve = model.evaluateGrid(100);
|
|
28
|
-
const bounds = regressionBootstrap(samples, {
|
|
29
|
-
method: 'linear', grid: curve.map(p => p.x), level: 0.95, resamples: 1000, seed: 0
|
|
30
|
-
});
|
|
31
|
-
const smooth = regressionLowess(samples, undefined, undefined, { span: 2 / 3, iterations: 3, delta: 0 });
|
|
32
|
-
// bounds 与 curve 使用相同 x;LOWESS 的 fitted 保留排序后的全部有效观测。
|
|
33
|
-
const prediction = smooth.predict(1);
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
bootstrap 的 level 严格在 (0,1),resamples 为正整数,seed 为 uint32;grid 为有限数字数组。主模型不满秩或没有残差自由度时抛出 RangeError。bootstrap 的多项式使用 method='polynomial' 和正整数 degree。图表层可采用更严格的次数和预算上限,不改变通用求解器契约。
|