rowpipe 2.2.1 → 2.10.2
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.md +34 -4
- package/dist/analytics/abtest.d.ts +39 -0
- package/dist/analytics/abtest.d.ts.map +1 -0
- package/dist/analytics/abtest.js +266 -0
- package/dist/analytics/abtest.js.map +1 -0
- package/dist/analytics/cluster.d.ts +25 -0
- package/dist/analytics/cluster.d.ts.map +1 -0
- package/dist/analytics/cluster.js +212 -0
- package/dist/analytics/cluster.js.map +1 -0
- package/dist/analytics/cohort.d.ts +22 -0
- package/dist/analytics/cohort.d.ts.map +1 -0
- package/dist/analytics/cohort.js +170 -0
- package/dist/analytics/cohort.js.map +1 -0
- package/dist/analytics/correlation.d.ts +15 -0
- package/dist/analytics/correlation.d.ts.map +1 -0
- package/dist/analytics/correlation.js +116 -0
- package/dist/analytics/correlation.js.map +1 -0
- package/dist/analytics/crosstab.d.ts +27 -0
- package/dist/analytics/crosstab.d.ts.map +1 -0
- package/dist/analytics/crosstab.js +90 -0
- package/dist/analytics/crosstab.js.map +1 -0
- package/dist/analytics/entropy.d.ts +23 -0
- package/dist/analytics/entropy.d.ts.map +1 -0
- package/dist/analytics/entropy.js +180 -0
- package/dist/analytics/entropy.js.map +1 -0
- package/dist/analytics/funnel.d.ts +29 -0
- package/dist/analytics/funnel.d.ts.map +1 -0
- package/dist/analytics/funnel.js +170 -0
- package/dist/analytics/funnel.js.map +1 -0
- package/dist/analytics/ngrams.d.ts +25 -0
- package/dist/analytics/ngrams.d.ts.map +1 -0
- package/dist/analytics/ngrams.js +110 -0
- package/dist/analytics/ngrams.js.map +1 -0
- package/dist/analytics/outliers.d.ts +25 -0
- package/dist/analytics/outliers.d.ts.map +1 -0
- package/dist/analytics/outliers.js +114 -0
- package/dist/analytics/outliers.js.map +1 -0
- package/dist/analytics/pareto.d.ts +36 -0
- package/dist/analytics/pareto.d.ts.map +1 -0
- package/dist/analytics/pareto.js +140 -0
- package/dist/analytics/pareto.js.map +1 -0
- package/dist/analytics/quantiles.d.ts +18 -0
- package/dist/analytics/quantiles.d.ts.map +1 -0
- package/dist/analytics/quantiles.js +62 -0
- package/dist/analytics/quantiles.js.map +1 -0
- package/dist/analytics/regression.d.ts +18 -0
- package/dist/analytics/regression.d.ts.map +1 -0
- package/dist/analytics/regression.js +79 -0
- package/dist/analytics/regression.js.map +1 -0
- package/dist/analytics/rfm.d.ts +41 -0
- package/dist/analytics/rfm.d.ts.map +1 -0
- package/dist/analytics/rfm.js +221 -0
- package/dist/analytics/rfm.js.map +1 -0
- package/dist/analytics/stats.d.ts.map +1 -1
- package/dist/analytics/stats.js +65 -15
- package/dist/analytics/stats.js.map +1 -1
- package/dist/analytics/technical.d.ts +19 -0
- package/dist/analytics/technical.d.ts.map +1 -0
- package/dist/analytics/technical.js +365 -0
- package/dist/analytics/technical.js.map +1 -0
- package/dist/cli/commands/abtest.d.ts +10 -0
- package/dist/cli/commands/abtest.d.ts.map +1 -0
- package/dist/cli/commands/abtest.js +68 -0
- package/dist/cli/commands/abtest.js.map +1 -0
- package/dist/cli/commands/cluster.d.ts +9 -0
- package/dist/cli/commands/cluster.d.ts.map +1 -0
- package/dist/cli/commands/cluster.js +77 -0
- package/dist/cli/commands/cluster.js.map +1 -0
- package/dist/cli/commands/cohort.d.ts +10 -0
- package/dist/cli/commands/cohort.d.ts.map +1 -0
- package/dist/cli/commands/cohort.js +66 -0
- package/dist/cli/commands/cohort.js.map +1 -0
- package/dist/cli/commands/completion.d.ts +5 -0
- package/dist/cli/commands/completion.d.ts.map +1 -0
- package/dist/cli/commands/completion.js +7 -0
- package/dist/cli/commands/completion.js.map +1 -0
- package/dist/cli/commands/concat.d.ts +9 -0
- package/dist/cli/commands/concat.d.ts.map +1 -0
- package/dist/cli/commands/concat.js +62 -0
- package/dist/cli/commands/concat.js.map +1 -0
- package/dist/cli/commands/convert.d.ts +2 -0
- package/dist/cli/commands/convert.d.ts.map +1 -1
- package/dist/cli/commands/convert.js.map +1 -1
- package/dist/cli/commands/corr.d.ts +7 -0
- package/dist/cli/commands/corr.d.ts.map +1 -0
- package/dist/cli/commands/corr.js +70 -0
- package/dist/cli/commands/corr.js.map +1 -0
- package/dist/cli/commands/crosstab.d.ts +11 -0
- package/dist/cli/commands/crosstab.d.ts.map +1 -0
- package/dist/cli/commands/crosstab.js +71 -0
- package/dist/cli/commands/crosstab.js.map +1 -0
- package/dist/cli/commands/entropy.d.ts +9 -0
- package/dist/cli/commands/entropy.d.ts.map +1 -0
- package/dist/cli/commands/entropy.js +71 -0
- package/dist/cli/commands/entropy.js.map +1 -0
- package/dist/cli/commands/explode.d.ts +8 -0
- package/dist/cli/commands/explode.d.ts.map +1 -0
- package/dist/cli/commands/explode.js +61 -0
- package/dist/cli/commands/explode.js.map +1 -0
- package/dist/cli/commands/fetch.d.ts +8 -0
- package/dist/cli/commands/fetch.d.ts.map +1 -0
- package/dist/cli/commands/fetch.js +41 -0
- package/dist/cli/commands/fetch.js.map +1 -0
- package/dist/cli/commands/files.d.ts +1 -1
- package/dist/cli/commands/files.d.ts.map +1 -1
- package/dist/cli/commands/flatten.d.ts +8 -0
- package/dist/cli/commands/flatten.d.ts.map +1 -0
- package/dist/cli/commands/flatten.js +57 -0
- package/dist/cli/commands/flatten.js.map +1 -0
- package/dist/cli/commands/freq.d.ts +10 -0
- package/dist/cli/commands/freq.d.ts.map +1 -0
- package/dist/cli/commands/freq.js +122 -0
- package/dist/cli/commands/freq.js.map +1 -0
- package/dist/cli/commands/funnel.d.ts +11 -0
- package/dist/cli/commands/funnel.d.ts.map +1 -0
- package/dist/cli/commands/funnel.js +69 -0
- package/dist/cli/commands/funnel.js.map +1 -0
- package/dist/cli/commands/fuzzy-join.d.ts +25 -0
- package/dist/cli/commands/fuzzy-join.d.ts.map +1 -0
- package/dist/cli/commands/fuzzy-join.js +85 -0
- package/dist/cli/commands/fuzzy-join.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +8 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +34 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/mask.d.ts +6 -0
- package/dist/cli/commands/mask.d.ts.map +1 -0
- package/dist/cli/commands/mask.js +58 -0
- package/dist/cli/commands/mask.js.map +1 -0
- package/dist/cli/commands/ngrams.d.ts +11 -0
- package/dist/cli/commands/ngrams.d.ts.map +1 -0
- package/dist/cli/commands/ngrams.js +70 -0
- package/dist/cli/commands/ngrams.js.map +1 -0
- package/dist/cli/commands/outliers.d.ts +13 -0
- package/dist/cli/commands/outliers.d.ts.map +1 -0
- package/dist/cli/commands/outliers.js +58 -0
- package/dist/cli/commands/outliers.js.map +1 -0
- package/dist/cli/commands/pareto.d.ts +8 -0
- package/dist/cli/commands/pareto.d.ts.map +1 -0
- package/dist/cli/commands/pareto.js +80 -0
- package/dist/cli/commands/pareto.js.map +1 -0
- package/dist/cli/commands/partition.d.ts +8 -0
- package/dist/cli/commands/partition.d.ts.map +1 -0
- package/dist/cli/commands/partition.js +44 -0
- package/dist/cli/commands/partition.js.map +1 -0
- package/dist/cli/commands/pipeline.d.ts +6 -0
- package/dist/cli/commands/pipeline.d.ts.map +1 -1
- package/dist/cli/commands/pipeline.js +22 -0
- package/dist/cli/commands/pipeline.js.map +1 -1
- package/dist/cli/commands/pivot.d.ts +11 -0
- package/dist/cli/commands/pivot.d.ts.map +1 -0
- package/dist/cli/commands/pivot.js +58 -0
- package/dist/cli/commands/pivot.js.map +1 -0
- package/dist/cli/commands/plot.d.ts +12 -0
- package/dist/cli/commands/plot.d.ts.map +1 -0
- package/dist/cli/commands/plot.js +123 -0
- package/dist/cli/commands/plot.js.map +1 -0
- package/dist/cli/commands/quantiles.d.ts +7 -0
- package/dist/cli/commands/quantiles.d.ts.map +1 -0
- package/dist/cli/commands/quantiles.js +94 -0
- package/dist/cli/commands/quantiles.js.map +1 -0
- package/dist/cli/commands/regression.d.ts +7 -0
- package/dist/cli/commands/regression.d.ts.map +1 -0
- package/dist/cli/commands/regression.js +86 -0
- package/dist/cli/commands/regression.js.map +1 -0
- package/dist/cli/commands/report.d.ts +8 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +36 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/rfm.d.ts +11 -0
- package/dist/cli/commands/rfm.d.ts.map +1 -0
- package/dist/cli/commands/rfm.js +78 -0
- package/dist/cli/commands/rfm.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +7 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +43 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/split.d.ts +8 -0
- package/dist/cli/commands/split.d.ts.map +1 -0
- package/dist/cli/commands/split.js +43 -0
- package/dist/cli/commands/split.js.map +1 -0
- package/dist/cli/commands/table.d.ts +9 -0
- package/dist/cli/commands/table.d.ts.map +1 -0
- package/dist/cli/commands/table.js +9 -0
- package/dist/cli/commands/table.js.map +1 -0
- package/dist/cli/commands/technical.d.ts +8 -0
- package/dist/cli/commands/technical.d.ts.map +1 -0
- package/dist/cli/commands/technical.js +54 -0
- package/dist/cli/commands/technical.js.map +1 -0
- package/dist/cli/commands/test.d.ts +7 -0
- package/dist/cli/commands/test.d.ts.map +1 -0
- package/dist/cli/commands/test.js +53 -0
- package/dist/cli/commands/test.js.map +1 -0
- package/dist/cli/commands/timeseries.d.ts +11 -0
- package/dist/cli/commands/timeseries.d.ts.map +1 -0
- package/dist/cli/commands/timeseries.js +82 -0
- package/dist/cli/commands/timeseries.js.map +1 -0
- package/dist/cli/commands/unpivot.d.ts +12 -0
- package/dist/cli/commands/unpivot.d.ts.map +1 -0
- package/dist/cli/commands/unpivot.js +59 -0
- package/dist/cli/commands/unpivot.js.map +1 -0
- package/dist/cli/completion.d.ts +5 -0
- package/dist/cli/completion.d.ts.map +1 -0
- package/dist/cli/completion.js +194 -0
- package/dist/cli/completion.js.map +1 -0
- package/dist/cli/index.js +816 -15
- package/dist/cli/index.js.map +1 -1
- package/dist/core/error-handler.d.ts +38 -0
- package/dist/core/error-handler.d.ts.map +1 -0
- package/dist/core/error-handler.js +81 -0
- package/dist/core/error-handler.js.map +1 -0
- package/dist/core/pipeline.d.ts +10 -0
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +14 -0
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/types.d.ts +4 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/dataops/fetch.d.ts +27 -0
- package/dist/dataops/fetch.d.ts.map +1 -0
- package/dist/dataops/fetch.js +150 -0
- package/dist/dataops/fetch.js.map +1 -0
- package/dist/dataops/generate.d.ts +16 -0
- package/dist/dataops/generate.d.ts.map +1 -0
- package/dist/dataops/generate.js +201 -0
- package/dist/dataops/generate.js.map +1 -0
- package/dist/dataops/mask.d.ts +25 -0
- package/dist/dataops/mask.d.ts.map +1 -0
- package/dist/dataops/mask.js +133 -0
- package/dist/dataops/mask.js.map +1 -0
- package/dist/dataops/report.d.ts +7 -0
- package/dist/dataops/report.d.ts.map +1 -0
- package/dist/dataops/report.js +139 -0
- package/dist/dataops/report.js.map +1 -0
- package/dist/dataops/server.d.ts +10 -0
- package/dist/dataops/server.d.ts.map +1 -0
- package/dist/dataops/server.js +137 -0
- package/dist/dataops/server.js.map +1 -0
- package/dist/dataops/test-runner.d.ts +34 -0
- package/dist/dataops/test-runner.d.ts.map +1 -0
- package/dist/dataops/test-runner.js +128 -0
- package/dist/dataops/test-runner.js.map +1 -0
- package/dist/db/adapters/sqlite.d.ts.map +1 -1
- package/dist/db/adapters/sqlite.js +4 -1
- package/dist/db/adapters/sqlite.js.map +1 -1
- package/dist/diff/engine.d.ts.map +1 -1
- package/dist/diff/engine.js +73 -16
- package/dist/diff/engine.js.map +1 -1
- package/dist/diff/storage/disk-index.d.ts +10 -1
- package/dist/diff/storage/disk-index.d.ts.map +1 -1
- package/dist/diff/storage/disk-index.js +95 -13
- package/dist/diff/storage/disk-index.js.map +1 -1
- package/dist/files/hash.d.ts +9 -2
- package/dist/files/hash.d.ts.map +1 -1
- package/dist/files/hash.js +9 -10
- package/dist/files/hash.js.map +1 -1
- package/dist/files/reader.d.ts.map +1 -1
- package/dist/files/reader.js +17 -10
- package/dist/files/reader.js.map +1 -1
- package/dist/files/types.d.ts +2 -1
- package/dist/files/types.d.ts.map +1 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +66 -1
- package/dist/index.js.map +1 -1
- package/dist/planner/executor.d.ts.map +1 -1
- package/dist/planner/executor.js +17 -0
- package/dist/planner/executor.js.map +1 -1
- package/dist/planner/types.d.ts +11 -0
- package/dist/planner/types.d.ts.map +1 -1
- package/dist/readers/csv.d.ts.map +1 -1
- package/dist/readers/csv.js +206 -164
- package/dist/readers/csv.js.map +1 -1
- package/dist/readers/json.d.ts.map +1 -1
- package/dist/readers/json.js +145 -121
- package/dist/readers/json.js.map +1 -1
- package/dist/readers/jsonl.d.ts.map +1 -1
- package/dist/readers/jsonl.js +51 -31
- package/dist/readers/jsonl.js.map +1 -1
- package/dist/transforms/concat.d.ts +26 -0
- package/dist/transforms/concat.d.ts.map +1 -0
- package/dist/transforms/concat.js +57 -0
- package/dist/transforms/concat.js.map +1 -0
- package/dist/transforms/explode.d.ts +14 -0
- package/dist/transforms/explode.d.ts.map +1 -0
- package/dist/transforms/explode.js +81 -0
- package/dist/transforms/explode.js.map +1 -0
- package/dist/transforms/flatten.d.ts +12 -0
- package/dist/transforms/flatten.d.ts.map +1 -0
- package/dist/transforms/flatten.js +65 -0
- package/dist/transforms/flatten.js.map +1 -0
- package/dist/transforms/fuzzy-join.d.ts +53 -0
- package/dist/transforms/fuzzy-join.d.ts.map +1 -0
- package/dist/transforms/fuzzy-join.js +347 -0
- package/dist/transforms/fuzzy-join.js.map +1 -0
- package/dist/transforms/jit-compiler.d.ts.map +1 -1
- package/dist/transforms/jit-compiler.js +103 -14
- package/dist/transforms/jit-compiler.js.map +1 -1
- package/dist/transforms/map.d.ts +6 -2
- package/dist/transforms/map.d.ts.map +1 -1
- package/dist/transforms/map.js +64 -26
- package/dist/transforms/map.js.map +1 -1
- package/dist/transforms/partition.d.ts +35 -0
- package/dist/transforms/partition.d.ts.map +1 -0
- package/dist/transforms/partition.js +150 -0
- package/dist/transforms/partition.js.map +1 -0
- package/dist/transforms/pivot.d.ts +16 -0
- package/dist/transforms/pivot.d.ts.map +1 -0
- package/dist/transforms/pivot.js +194 -0
- package/dist/transforms/pivot.js.map +1 -0
- package/dist/transforms/sort/comparator.d.ts.map +1 -1
- package/dist/transforms/sort/comparator.js +153 -24
- package/dist/transforms/sort/comparator.js.map +1 -1
- package/dist/transforms/sort/external-sort.js +1 -1
- package/dist/transforms/sort/external-sort.js.map +1 -1
- package/dist/transforms/split.d.ts +17 -0
- package/dist/transforms/split.d.ts.map +1 -0
- package/dist/transforms/split.js +88 -0
- package/dist/transforms/split.js.map +1 -0
- package/dist/transforms/timeseries.d.ts +42 -0
- package/dist/transforms/timeseries.d.ts.map +1 -0
- package/dist/transforms/timeseries.js +276 -0
- package/dist/transforms/timeseries.js.map +1 -0
- package/dist/transforms/unpivot.d.ts +14 -0
- package/dist/transforms/unpivot.d.ts.map +1 -0
- package/dist/transforms/unpivot.js +56 -0
- package/dist/transforms/unpivot.js.map +1 -0
- package/dist/ui/chart.d.ts +30 -0
- package/dist/ui/chart.d.ts.map +1 -0
- package/dist/ui/chart.js +91 -0
- package/dist/ui/chart.js.map +1 -0
- package/dist/writers/index.d.ts +1 -0
- package/dist/writers/index.d.ts.map +1 -1
- package/dist/writers/index.js +10 -0
- package/dist/writers/index.js.map +1 -1
- package/dist/writers/table.d.ts +23 -0
- package/dist/writers/table.d.ts.map +1 -0
- package/dist/writers/table.js +156 -0
- package/dist/writers/table.js.map +1 -0
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -35,19 +35,49 @@ Designed around stream backpressure and batch processing, Rowpipe processes mult
|
|
|
35
35
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
38
|
+
Rowpipe is available as a **standalone zero-dependency executable** (no Node.js required) as well as an npm package.
|
|
39
|
+
|
|
40
|
+
### Option 1: Standalone Single Executable (Recommended)
|
|
41
|
+
|
|
42
|
+
#### 🍏 macOS & 🐧 Linux (Universal 1-Line Installer)
|
|
38
43
|
```bash
|
|
39
|
-
|
|
44
|
+
curl -fsSL https://raw.githubusercontent.com/litepacks/rowpipe/main/install.sh | bash
|
|
40
45
|
```
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
#### 🍺 Homebrew (macOS & Linux)
|
|
48
|
+
```bash
|
|
49
|
+
brew tap litepacks/tap
|
|
50
|
+
brew install rowpipe
|
|
51
|
+
```
|
|
52
|
+
*(Or install directly from the repository formula)*
|
|
53
|
+
```bash
|
|
54
|
+
brew install litepacks/rowpipe/rowpipe
|
|
55
|
+
```
|
|
43
56
|
|
|
57
|
+
#### 📦 Debian / Ubuntu (`apt` / `.deb`)
|
|
44
58
|
```bash
|
|
45
|
-
|
|
59
|
+
curl -sLO https://github.com/litepacks/rowpipe/releases/latest/download/rowpipe_2.10.1_amd64.deb
|
|
60
|
+
sudo apt install -y ./rowpipe_2.10.1_amd64.deb
|
|
46
61
|
```
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
#### 🪟 Windows & GitHub Releases
|
|
64
|
+
Pre-compiled standalone binaries for **macOS (Apple Silicon)**, **Linux (x64)**, and **Windows (x64)** are available on the [GitHub Releases](https://github.com/litepacks/rowpipe/releases) page:
|
|
65
|
+
* `rowpipe-darwin-arm64.tar.gz` (macOS Apple Silicon M1/M2/M3/M4)
|
|
66
|
+
* `rowpipe-linux-x64.tar.gz` / `rowpipe_2.10.1_amd64.deb` (Linux)
|
|
67
|
+
* `rowpipe-win32-x64.zip` (Windows)
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### Option 2: Via NPM (Node.js 20+)
|
|
49
72
|
|
|
50
73
|
```bash
|
|
74
|
+
# Global CLI installation
|
|
75
|
+
npm install -g rowpipe
|
|
76
|
+
|
|
77
|
+
# Or run instantly without installation
|
|
78
|
+
npx rowpipe --help
|
|
79
|
+
|
|
80
|
+
# Or install as a programmatic library
|
|
51
81
|
npm install rowpipe
|
|
52
82
|
```
|
|
53
83
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Row, DataBatch } from "../core/types.js";
|
|
2
|
+
export interface AbTestOptions {
|
|
3
|
+
groupCol?: string;
|
|
4
|
+
metricCol?: string;
|
|
5
|
+
controlGroup?: string;
|
|
6
|
+
variantGroup?: string;
|
|
7
|
+
type?: "auto" | "proportion" | "means";
|
|
8
|
+
confidenceLevel?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface AbTestResult {
|
|
11
|
+
test_type: "Two-Proportion Z-Test" | "Welch's Two-Sample T-Test";
|
|
12
|
+
control_group: string;
|
|
13
|
+
variant_group: string;
|
|
14
|
+
control_sample_size: number;
|
|
15
|
+
variant_sample_size: number;
|
|
16
|
+
control_metric: number;
|
|
17
|
+
variant_metric: number;
|
|
18
|
+
absolute_difference: number;
|
|
19
|
+
relative_lift_pct: number;
|
|
20
|
+
test_statistic: number;
|
|
21
|
+
statistic_name: "Z-score" | "t-score";
|
|
22
|
+
p_value: number;
|
|
23
|
+
confidence_level: number;
|
|
24
|
+
ci_lower: number;
|
|
25
|
+
ci_upper: number;
|
|
26
|
+
significant: boolean;
|
|
27
|
+
verdict: string;
|
|
28
|
+
formattedRows: Row[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Standard Normal Cumulative Distribution Function Φ(x) using Abramowitz and Stegun approximation
|
|
32
|
+
*/
|
|
33
|
+
export declare function normalCdf(z: number): number;
|
|
34
|
+
/**
|
|
35
|
+
* Student's t-distribution two-tailed p-value approximation (Hill 1970 / Normal limit for large df)
|
|
36
|
+
*/
|
|
37
|
+
export declare function studentTPValue(t: number, df: number): number;
|
|
38
|
+
export declare function computeAbTest(batchIterator: AsyncIterable<DataBatch>, options?: AbTestOptions): Promise<AbTestResult>;
|
|
39
|
+
//# sourceMappingURL=abtest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abtest.d.ts","sourceRoot":"","sources":["../../src/analytics/abtest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,OAAO,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,uBAAuB,GAAG,2BAA2B,CAAC;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,SAAS,GAAG,SAAS,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,GAAG,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAc3C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAkB5D;AAcD,wBAAsB,aAAa,CACjC,aAAa,EAAE,aAAa,CAAC,SAAS,CAAC,EACvC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAwPvB"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard Normal Cumulative Distribution Function Φ(x) using Abramowitz and Stegun approximation
|
|
3
|
+
*/
|
|
4
|
+
export function normalCdf(z) {
|
|
5
|
+
const p = 0.2316419;
|
|
6
|
+
const b1 = 0.31938153;
|
|
7
|
+
const b2 = -0.356563782;
|
|
8
|
+
const b3 = 1.781477937;
|
|
9
|
+
const b4 = -1.821255978;
|
|
10
|
+
const b5 = 1.330274429;
|
|
11
|
+
const absZ = Math.abs(z);
|
|
12
|
+
const t = 1.0 / (1.0 + p * absZ);
|
|
13
|
+
const pdf = (1.0 / Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * z * z);
|
|
14
|
+
const cdf = 1.0 - pdf * (b1 * t + b2 * Math.pow(t, 2) + b3 * Math.pow(t, 3) + b4 * Math.pow(t, 4) + b5 * Math.pow(t, 5));
|
|
15
|
+
return z >= 0 ? cdf : 1.0 - cdf;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Student's t-distribution two-tailed p-value approximation (Hill 1970 / Normal limit for large df)
|
|
19
|
+
*/
|
|
20
|
+
export function studentTPValue(t, df) {
|
|
21
|
+
if (df <= 0)
|
|
22
|
+
return 1.0;
|
|
23
|
+
const absT = Math.abs(t);
|
|
24
|
+
if (df >= 100) {
|
|
25
|
+
// Normal approximation for large degrees of freedom
|
|
26
|
+
return 2 * (1 - normalCdf(absT));
|
|
27
|
+
}
|
|
28
|
+
// Standard approximation for moderate df
|
|
29
|
+
const x = df / (df + absT * absT);
|
|
30
|
+
// Regularized incomplete beta function approximation via standard series
|
|
31
|
+
let sum = 0;
|
|
32
|
+
const numSteps = 50;
|
|
33
|
+
for (let i = 0; i < numSteps; i++) {
|
|
34
|
+
// simple integration approximation
|
|
35
|
+
const u = (i + 0.5) / numSteps;
|
|
36
|
+
sum += Math.pow(u, df / 2 - 1) * Math.pow(1 - u * x, -0.5);
|
|
37
|
+
}
|
|
38
|
+
return Math.min(1.0, Math.max(0.0, 2 * (1 - normalCdf(absT * (1 - 1 / (4 * df))))));
|
|
39
|
+
}
|
|
40
|
+
function parseBinaryValue(val) {
|
|
41
|
+
if (val === null || val === undefined)
|
|
42
|
+
return null;
|
|
43
|
+
if (typeof val === "boolean")
|
|
44
|
+
return val ? 1 : 0;
|
|
45
|
+
if (typeof val === "number")
|
|
46
|
+
return val === 1 ? 1 : val === 0 ? 0 : null;
|
|
47
|
+
if (typeof val === "string") {
|
|
48
|
+
const s = val.trim().toLowerCase();
|
|
49
|
+
if (s === "1" || s === "true" || s === "yes" || s === "y" || s === "converted" || s === "success")
|
|
50
|
+
return 1;
|
|
51
|
+
if (s === "0" || s === "false" || s === "no" || s === "n" || s === "dropped" || s === "failed")
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
export async function computeAbTest(batchIterator, options = {}) {
|
|
57
|
+
let groupCol = options.groupCol;
|
|
58
|
+
let metricCol = options.metricCol;
|
|
59
|
+
const groups = new Map();
|
|
60
|
+
for await (const batch of batchIterator) {
|
|
61
|
+
if (batch.rows.length === 0)
|
|
62
|
+
continue;
|
|
63
|
+
if (!groupCol || !metricCol) {
|
|
64
|
+
const firstRow = batch.rows[0];
|
|
65
|
+
const keys = Object.keys(firstRow);
|
|
66
|
+
if (!groupCol) {
|
|
67
|
+
groupCol =
|
|
68
|
+
keys.find((k) => /^(group|variant|experiment|test_group|cohort|treatment|ab|arm)$/i.test(k)) ??
|
|
69
|
+
keys[0];
|
|
70
|
+
}
|
|
71
|
+
if (!metricCol) {
|
|
72
|
+
metricCol =
|
|
73
|
+
keys.find((k) => /(converted|conversion|revenue|metric|value|score|amount|spend|clicks|click)/i.test(k)) ??
|
|
74
|
+
keys[1];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const row of batch.rows) {
|
|
78
|
+
const rawG = row[groupCol];
|
|
79
|
+
if (rawG === null || rawG === undefined || rawG === "")
|
|
80
|
+
continue;
|
|
81
|
+
const g = String(rawG).trim();
|
|
82
|
+
const rawVal = row[metricCol];
|
|
83
|
+
let numVal = null;
|
|
84
|
+
if (typeof rawVal === "number") {
|
|
85
|
+
numVal = rawVal;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const bin = parseBinaryValue(rawVal);
|
|
89
|
+
if (bin !== null) {
|
|
90
|
+
numVal = bin;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const parsed = parseFloat(String(rawVal));
|
|
94
|
+
if (!isNaN(parsed))
|
|
95
|
+
numVal = parsed;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (numVal === null)
|
|
99
|
+
continue;
|
|
100
|
+
let acc = groups.get(g);
|
|
101
|
+
if (!acc) {
|
|
102
|
+
acc = { n: 0, sum: 0, mean: 0, m2: 0, binaryCount: 0 };
|
|
103
|
+
groups.set(g, acc);
|
|
104
|
+
}
|
|
105
|
+
acc.n += 1;
|
|
106
|
+
acc.sum += numVal;
|
|
107
|
+
if (numVal === 0 || numVal === 1) {
|
|
108
|
+
acc.binaryCount += 1;
|
|
109
|
+
}
|
|
110
|
+
// Welford update
|
|
111
|
+
const delta = numVal - acc.mean;
|
|
112
|
+
acc.mean += delta / acc.n;
|
|
113
|
+
const delta2 = numVal - acc.mean;
|
|
114
|
+
acc.m2 += delta * delta2;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const groupKeys = Array.from(groups.keys());
|
|
118
|
+
if (groupKeys.length < 2) {
|
|
119
|
+
throw new Error(`A/B test requires at least 2 distinct groups in column '${groupCol}', but found ${groupKeys.length} (${groupKeys.join(", ")})`);
|
|
120
|
+
}
|
|
121
|
+
// Determine control and variant
|
|
122
|
+
let ctrlName = options.controlGroup;
|
|
123
|
+
let varName = options.variantGroup;
|
|
124
|
+
if (!ctrlName) {
|
|
125
|
+
ctrlName =
|
|
126
|
+
groupKeys.find((k) => /^(control|ctrl|base|baseline|a|orig|original)$/i.test(k)) ??
|
|
127
|
+
groupKeys[0];
|
|
128
|
+
}
|
|
129
|
+
if (!varName) {
|
|
130
|
+
varName =
|
|
131
|
+
groupKeys.find((k) => k !== ctrlName && /^(variant|var|treatment|treat|b|test|new)$/i.test(k)) ??
|
|
132
|
+
groupKeys.find((k) => k !== ctrlName);
|
|
133
|
+
}
|
|
134
|
+
const ctrl = groups.get(ctrlName);
|
|
135
|
+
const variant = groups.get(varName);
|
|
136
|
+
if (!ctrl || !variant) {
|
|
137
|
+
throw new Error(`Could not find specified groups: Control='${ctrlName}', Variant='${varName}'`);
|
|
138
|
+
}
|
|
139
|
+
// Check if test is proportion (binary) or means (continuous)
|
|
140
|
+
const isBinary = options.type === "proportion" ||
|
|
141
|
+
(options.type !== "means" &&
|
|
142
|
+
ctrl.binaryCount === ctrl.n &&
|
|
143
|
+
variant.binaryCount === variant.n);
|
|
144
|
+
const confLevel = options.confidenceLevel ?? 0.95;
|
|
145
|
+
const zCrit = confLevel === 0.99 ? 2.576 : confLevel === 0.90 ? 1.645 : 1.96;
|
|
146
|
+
if (isBinary) {
|
|
147
|
+
// Two-Proportion Z-Test
|
|
148
|
+
const n1 = ctrl.n;
|
|
149
|
+
const x1 = ctrl.sum;
|
|
150
|
+
const p1 = n1 > 0 ? x1 / n1 : 0;
|
|
151
|
+
const n2 = variant.n;
|
|
152
|
+
const x2 = variant.sum;
|
|
153
|
+
const p2 = n2 > 0 ? x2 / n2 : 0;
|
|
154
|
+
const pPooled = (x1 + x2) / (n1 + n2);
|
|
155
|
+
const sePooled = Math.sqrt(pPooled * (1 - pPooled) * (1 / n1 + 1 / n2));
|
|
156
|
+
const zScore = sePooled > 0 ? (p2 - p1) / sePooled : 0;
|
|
157
|
+
const pValue = 2 * (1 - normalCdf(Math.abs(zScore)));
|
|
158
|
+
const diff = p2 - p1;
|
|
159
|
+
const liftPct = p1 > 0 ? ((p2 - p1) / p1) * 100 : 0;
|
|
160
|
+
const seDiff = Math.sqrt((p1 * (1 - p1)) / n1 + (p2 * (1 - p2)) / n2);
|
|
161
|
+
const ciLower = diff - zCrit * seDiff;
|
|
162
|
+
const ciUpper = diff + zCrit * seDiff;
|
|
163
|
+
const isSig = pValue < 1 - confLevel;
|
|
164
|
+
const verdict = isSig
|
|
165
|
+
? liftPct > 0
|
|
166
|
+
? `Statistically Significant Winner (${(liftPct > 0 ? "+" : "") + liftPct.toFixed(2)}% lift, p = ${pValue.toFixed(4)})`
|
|
167
|
+
: `Statistically Significant Loser (${liftPct.toFixed(2)}% lift, p = ${pValue.toFixed(4)})`
|
|
168
|
+
: `Inconclusive / Not Statistically Significant (p = ${pValue.toFixed(4)} >= ${(1 - confLevel).toFixed(2)})`;
|
|
169
|
+
const formattedRows = [
|
|
170
|
+
{ metric: "test_type", value: "Two-Proportion Z-Test (Binary Conversion)" },
|
|
171
|
+
{ metric: "control_group", value: `${ctrlName} (n=${n1.toLocaleString()})` },
|
|
172
|
+
{ metric: "variant_group", value: `${varName} (n=${n2.toLocaleString()})` },
|
|
173
|
+
{ metric: "control_rate", value: `${(p1 * 100).toFixed(2)}% (${x1}/${n1})` },
|
|
174
|
+
{ metric: "variant_rate", value: `${(p2 * 100).toFixed(2)}% (${x2}/${n2})` },
|
|
175
|
+
{ metric: "absolute_diff", value: `${diff >= 0 ? "+" : ""}${(diff * 100).toFixed(2)}%` },
|
|
176
|
+
{ metric: "relative_lift", value: `${liftPct >= 0 ? "+" : ""}${liftPct.toFixed(2)}%` },
|
|
177
|
+
{ metric: "z_statistic", value: Math.round(zScore * 10000) / 10000 },
|
|
178
|
+
{ metric: "p_value", value: Math.round(pValue * 10000) / 10000 },
|
|
179
|
+
{ metric: "confidence_level", value: `${(confLevel * 100).toFixed(0)}%` },
|
|
180
|
+
{ metric: "confidence_interval", value: `[${(ciLower * 100).toFixed(2)}%, ${(ciUpper * 100).toFixed(2)}%]` },
|
|
181
|
+
{ metric: "verdict", value: verdict },
|
|
182
|
+
];
|
|
183
|
+
return {
|
|
184
|
+
test_type: "Two-Proportion Z-Test",
|
|
185
|
+
control_group: ctrlName,
|
|
186
|
+
variant_group: varName,
|
|
187
|
+
control_sample_size: n1,
|
|
188
|
+
variant_sample_size: n2,
|
|
189
|
+
control_metric: p1,
|
|
190
|
+
variant_metric: p2,
|
|
191
|
+
absolute_difference: diff,
|
|
192
|
+
relative_lift_pct: liftPct,
|
|
193
|
+
test_statistic: zScore,
|
|
194
|
+
statistic_name: "Z-score",
|
|
195
|
+
p_value: pValue,
|
|
196
|
+
confidence_level: confLevel,
|
|
197
|
+
ci_lower: ciLower,
|
|
198
|
+
ci_upper: ciUpper,
|
|
199
|
+
significant: isSig,
|
|
200
|
+
verdict,
|
|
201
|
+
formattedRows,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// Welch's Two-Sample T-Test (Continuous)
|
|
206
|
+
const n1 = ctrl.n;
|
|
207
|
+
const mean1 = ctrl.mean;
|
|
208
|
+
const var1 = n1 > 1 ? ctrl.m2 / (n1 - 1) : 0;
|
|
209
|
+
const n2 = variant.n;
|
|
210
|
+
const mean2 = variant.mean;
|
|
211
|
+
const var2 = n2 > 1 ? variant.m2 / (n2 - 1) : 0;
|
|
212
|
+
const diff = mean2 - mean1;
|
|
213
|
+
const liftPct = mean1 !== 0 ? (diff / mean1) * 100 : 0;
|
|
214
|
+
const seDiff = Math.sqrt(var1 / n1 + var2 / n2);
|
|
215
|
+
const tScore = seDiff > 0 ? diff / seDiff : 0;
|
|
216
|
+
// Welch-Satterthwaite df
|
|
217
|
+
const numerator = Math.pow(var1 / n1 + var2 / n2, 2);
|
|
218
|
+
const denom = Math.pow(var1 / n1, 2) / (n1 - 1 || 1) + Math.pow(var2 / n2, 2) / (n2 - 1 || 1);
|
|
219
|
+
const df = denom > 0 ? numerator / denom : 1;
|
|
220
|
+
const pValue = studentTPValue(tScore, df);
|
|
221
|
+
const ciLower = diff - zCrit * seDiff;
|
|
222
|
+
const ciUpper = diff + zCrit * seDiff;
|
|
223
|
+
const isSig = pValue < 1 - confLevel;
|
|
224
|
+
const verdict = isSig
|
|
225
|
+
? liftPct > 0
|
|
226
|
+
? `Statistically Significant Increase (${(liftPct > 0 ? "+" : "") + liftPct.toFixed(2)}% lift, p = ${pValue.toFixed(4)})`
|
|
227
|
+
: `Statistically Significant Decrease (${liftPct.toFixed(2)}% lift, p = ${pValue.toFixed(4)})`
|
|
228
|
+
: `Inconclusive / Not Statistically Significant (p = ${pValue.toFixed(4)} >= ${(1 - confLevel).toFixed(2)})`;
|
|
229
|
+
const formattedRows = [
|
|
230
|
+
{ metric: "test_type", value: "Welch's Two-Sample T-Test (Continuous Means)" },
|
|
231
|
+
{ metric: "control_group", value: `${ctrlName} (n=${n1.toLocaleString()})` },
|
|
232
|
+
{ metric: "variant_group", value: `${varName} (n=${n2.toLocaleString()})` },
|
|
233
|
+
{ metric: "control_mean", value: Math.round(mean1 * 1000) / 1000 },
|
|
234
|
+
{ metric: "variant_mean", value: Math.round(mean2 * 1000) / 1000 },
|
|
235
|
+
{ metric: "absolute_diff", value: `${diff >= 0 ? "+" : ""}${Math.round(diff * 1000) / 1000}` },
|
|
236
|
+
{ metric: "relative_lift", value: `${liftPct >= 0 ? "+" : ""}${liftPct.toFixed(2)}%` },
|
|
237
|
+
{ metric: "t_statistic", value: Math.round(tScore * 10000) / 10000 },
|
|
238
|
+
{ metric: "degrees_of_freedom", value: Math.round(df * 10) / 10 },
|
|
239
|
+
{ metric: "p_value", value: Math.round(pValue * 10000) / 10000 },
|
|
240
|
+
{ metric: "confidence_level", value: `${(confLevel * 100).toFixed(0)}%` },
|
|
241
|
+
{ metric: "confidence_interval", value: `[${Math.round(ciLower * 1000) / 1000}, ${Math.round(ciUpper * 1000) / 1000}]` },
|
|
242
|
+
{ metric: "verdict", value: verdict },
|
|
243
|
+
];
|
|
244
|
+
return {
|
|
245
|
+
test_type: "Welch's Two-Sample T-Test",
|
|
246
|
+
control_group: ctrlName,
|
|
247
|
+
variant_group: varName,
|
|
248
|
+
control_sample_size: n1,
|
|
249
|
+
variant_sample_size: n2,
|
|
250
|
+
control_metric: mean1,
|
|
251
|
+
variant_metric: mean2,
|
|
252
|
+
absolute_difference: diff,
|
|
253
|
+
relative_lift_pct: liftPct,
|
|
254
|
+
test_statistic: tScore,
|
|
255
|
+
statistic_name: "t-score",
|
|
256
|
+
p_value: pValue,
|
|
257
|
+
confidence_level: confLevel,
|
|
258
|
+
ci_lower: ciLower,
|
|
259
|
+
ci_upper: ciUpper,
|
|
260
|
+
significant: isSig,
|
|
261
|
+
verdict,
|
|
262
|
+
formattedRows,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=abtest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abtest.js","sourceRoot":"","sources":["../../src/analytics/abtest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Row, DataBatch } from "../core/types.js";
|
|
2
|
+
export interface ClusterOptions {
|
|
3
|
+
cols?: string | string[];
|
|
4
|
+
k?: number;
|
|
5
|
+
seed?: number;
|
|
6
|
+
summary?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface CentroidInfo {
|
|
9
|
+
cluster_id: number;
|
|
10
|
+
size: number;
|
|
11
|
+
percentage: number;
|
|
12
|
+
coordinates: Record<string, number>;
|
|
13
|
+
avg_distance: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ClusterResult {
|
|
16
|
+
k: number;
|
|
17
|
+
columns: string[];
|
|
18
|
+
total_samples: number;
|
|
19
|
+
inertia: number;
|
|
20
|
+
centroids: CentroidInfo[];
|
|
21
|
+
formattedRows: Row[];
|
|
22
|
+
}
|
|
23
|
+
export declare function computeKMeans(batchIterator: AsyncIterable<DataBatch>, options?: ClusterOptions): Promise<ClusterResult>;
|
|
24
|
+
export declare function clusterAssignTransform(batchIterator: AsyncIterable<DataBatch>, result: ClusterResult): AsyncIterable<DataBatch>;
|
|
25
|
+
//# sourceMappingURL=cluster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster.d.ts","sourceRoot":"","sources":["../../src/analytics/cluster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,aAAa,EAAE,GAAG,EAAE,CAAC;CACtB;AAWD,wBAAsB,aAAa,CACjC,aAAa,EAAE,aAAa,CAAC,SAAS,CAAC,EACvC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA+KxB;AAED,wBAAuB,sBAAsB,CAC3C,aAAa,EAAE,aAAa,CAAC,SAAS,CAAC,EACvC,MAAM,EAAE,aAAa,GACpB,aAAa,CAAC,SAAS,CAAC,CAqD1B"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
function euclideanDistanceSq(point, centroid) {
|
|
2
|
+
let sum = 0;
|
|
3
|
+
for (let i = 0; i < point.length; i++) {
|
|
4
|
+
const diff = point[i] - centroid[i];
|
|
5
|
+
sum += diff * diff;
|
|
6
|
+
}
|
|
7
|
+
return sum;
|
|
8
|
+
}
|
|
9
|
+
export async function computeKMeans(batchIterator, options = {}) {
|
|
10
|
+
const k = Math.max(2, options.k ?? 3);
|
|
11
|
+
let targetCols;
|
|
12
|
+
if (options.cols) {
|
|
13
|
+
targetCols = Array.isArray(options.cols)
|
|
14
|
+
? options.cols.flatMap((c) => c.split(",").map((s) => s.trim()))
|
|
15
|
+
: options.cols.split(",").map((s) => s.trim());
|
|
16
|
+
}
|
|
17
|
+
let centroids = [];
|
|
18
|
+
let centroidCounts = [];
|
|
19
|
+
let centroidDistSums = [];
|
|
20
|
+
let totalSamples = 0;
|
|
21
|
+
let totalInertia = 0;
|
|
22
|
+
// Buffer initial samples for K-Means++ initialization
|
|
23
|
+
const initBuffer = [];
|
|
24
|
+
const initSampleSize = Math.max(k * 10, 100);
|
|
25
|
+
for await (const batch of batchIterator) {
|
|
26
|
+
if (batch.rows.length === 0)
|
|
27
|
+
continue;
|
|
28
|
+
if (!targetCols) {
|
|
29
|
+
const firstRow = batch.rows[0];
|
|
30
|
+
targetCols = Object.keys(firstRow).filter((col) => {
|
|
31
|
+
const val = firstRow[col];
|
|
32
|
+
return typeof val === "number" || (!isNaN(Number(val)) && val !== null && val !== "" && typeof val !== "boolean");
|
|
33
|
+
});
|
|
34
|
+
if (targetCols.length === 0) {
|
|
35
|
+
throw new Error("No numeric columns found for K-Means clustering.");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const numericVectors = [];
|
|
39
|
+
for (const row of batch.rows) {
|
|
40
|
+
const vec = [];
|
|
41
|
+
let valid = true;
|
|
42
|
+
for (const col of targetCols) {
|
|
43
|
+
const raw = row[col];
|
|
44
|
+
const num = typeof raw === "number" ? raw : parseFloat(String(raw));
|
|
45
|
+
if (isNaN(num)) {
|
|
46
|
+
valid = false;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
vec.push(num);
|
|
50
|
+
}
|
|
51
|
+
if (valid) {
|
|
52
|
+
numericVectors.push(vec);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (numericVectors.length === 0)
|
|
56
|
+
continue;
|
|
57
|
+
// Initialization phase (K-Means++)
|
|
58
|
+
if (centroids.length < k) {
|
|
59
|
+
for (const vec of numericVectors) {
|
|
60
|
+
if (initBuffer.length < initSampleSize) {
|
|
61
|
+
initBuffer.push(vec);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (initBuffer.length >= k) {
|
|
65
|
+
// Pick first center randomly
|
|
66
|
+
centroids.push([...initBuffer[0]]);
|
|
67
|
+
centroidCounts.push(1);
|
|
68
|
+
centroidDistSums.push(0);
|
|
69
|
+
// Pick remaining centers using D^2 weighting
|
|
70
|
+
while (centroids.length < k) {
|
|
71
|
+
const distances = initBuffer.map((pt) => {
|
|
72
|
+
let minDistSq = Infinity;
|
|
73
|
+
for (const c of centroids) {
|
|
74
|
+
const dSq = euclideanDistanceSq(pt, c);
|
|
75
|
+
if (dSq < minDistSq)
|
|
76
|
+
minDistSq = dSq;
|
|
77
|
+
}
|
|
78
|
+
return minDistSq;
|
|
79
|
+
});
|
|
80
|
+
const totalDistSq = distances.reduce((a, b) => a + b, 0);
|
|
81
|
+
let r = Math.random() * totalDistSq;
|
|
82
|
+
let selectedIdx = 0;
|
|
83
|
+
for (let i = 0; i < distances.length; i++) {
|
|
84
|
+
r -= distances[i];
|
|
85
|
+
if (r <= 0) {
|
|
86
|
+
selectedIdx = i;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
centroids.push([...initBuffer[selectedIdx]]);
|
|
91
|
+
centroidCounts.push(1);
|
|
92
|
+
centroidDistSums.push(0);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Mini-Batch Gradient Updates
|
|
97
|
+
if (centroids.length === k) {
|
|
98
|
+
for (const vec of numericVectors) {
|
|
99
|
+
totalSamples++;
|
|
100
|
+
let bestCluster = 0;
|
|
101
|
+
let bestDistSq = Infinity;
|
|
102
|
+
for (let ci = 0; ci < k; ci++) {
|
|
103
|
+
const dSq = euclideanDistanceSq(vec, centroids[ci]);
|
|
104
|
+
if (dSq < bestDistSq) {
|
|
105
|
+
bestDistSq = dSq;
|
|
106
|
+
bestCluster = ci;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
totalInertia += bestDistSq;
|
|
110
|
+
const dist = Math.sqrt(bestDistSq);
|
|
111
|
+
centroidDistSums[bestCluster] = (centroidDistSums[bestCluster] || 0) + dist;
|
|
112
|
+
centroidCounts[bestCluster] = (centroidCounts[bestCluster] || 0) + 1;
|
|
113
|
+
// Online Learning rate
|
|
114
|
+
const count = centroidCounts[bestCluster];
|
|
115
|
+
const lr = 1.0 / count;
|
|
116
|
+
const center = centroids[bestCluster];
|
|
117
|
+
for (let dim = 0; dim < vec.length; dim++) {
|
|
118
|
+
center[dim] = center[dim] * (1 - lr) + vec[dim] * lr;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (centroids.length === 0 || !targetCols) {
|
|
124
|
+
throw new Error("Insufficient numeric data to form clusters.");
|
|
125
|
+
}
|
|
126
|
+
const centroidResults = [];
|
|
127
|
+
for (let ci = 0; ci < k; ci++) {
|
|
128
|
+
const size = centroidCounts[ci] || 0;
|
|
129
|
+
const pct = totalSamples > 0 ? (size / totalSamples) * 100 : 0;
|
|
130
|
+
const avgDist = size > 0 ? centroidDistSums[ci] / size : 0;
|
|
131
|
+
const coords = {};
|
|
132
|
+
for (let d = 0; d < targetCols.length; d++) {
|
|
133
|
+
coords[targetCols[d]] = Math.round((centroids[ci][d] || 0) * 1000) / 1000;
|
|
134
|
+
}
|
|
135
|
+
centroidResults.push({
|
|
136
|
+
cluster_id: ci + 1,
|
|
137
|
+
size,
|
|
138
|
+
percentage: Math.round(pct * 10) / 10,
|
|
139
|
+
coordinates: coords,
|
|
140
|
+
avg_distance: Math.round(avgDist * 1000) / 1000,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// Format table rows
|
|
144
|
+
const formattedRows = centroidResults.map((c) => {
|
|
145
|
+
const rowObj = {
|
|
146
|
+
cluster_id: `Cluster ${c.cluster_id}`,
|
|
147
|
+
size: c.size,
|
|
148
|
+
share: `${c.percentage.toFixed(1)}%`,
|
|
149
|
+
avg_dist: c.avg_distance,
|
|
150
|
+
};
|
|
151
|
+
for (const [col, val] of Object.entries(c.coordinates)) {
|
|
152
|
+
rowObj[col] = val;
|
|
153
|
+
}
|
|
154
|
+
return rowObj;
|
|
155
|
+
});
|
|
156
|
+
return {
|
|
157
|
+
k,
|
|
158
|
+
columns: targetCols,
|
|
159
|
+
total_samples: totalSamples,
|
|
160
|
+
inertia: Math.round(totalInertia * 100) / 100,
|
|
161
|
+
centroids: centroidResults,
|
|
162
|
+
formattedRows,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
export async function* clusterAssignTransform(batchIterator, result) {
|
|
166
|
+
const { k, columns, centroids } = result;
|
|
167
|
+
const centroidVectors = centroids.map((c) => columns.map((col) => c.coordinates[col] || 0));
|
|
168
|
+
for await (const batch of batchIterator) {
|
|
169
|
+
if (batch.rows.length === 0) {
|
|
170
|
+
yield batch;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const updatedRows = [];
|
|
174
|
+
for (const row of batch.rows) {
|
|
175
|
+
const newRow = { ...row };
|
|
176
|
+
const vec = [];
|
|
177
|
+
let valid = true;
|
|
178
|
+
for (const col of columns) {
|
|
179
|
+
const raw = row[col];
|
|
180
|
+
const num = typeof raw === "number" ? raw : parseFloat(String(raw));
|
|
181
|
+
if (isNaN(num)) {
|
|
182
|
+
valid = false;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
vec.push(num);
|
|
186
|
+
}
|
|
187
|
+
if (valid) {
|
|
188
|
+
let bestCluster = 0;
|
|
189
|
+
let bestDistSq = Infinity;
|
|
190
|
+
for (let ci = 0; ci < k; ci++) {
|
|
191
|
+
const dSq = euclideanDistanceSq(vec, centroidVectors[ci]);
|
|
192
|
+
if (dSq < bestDistSq) {
|
|
193
|
+
bestDistSq = dSq;
|
|
194
|
+
bestCluster = ci;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
newRow["_cluster_id"] = bestCluster + 1;
|
|
198
|
+
newRow["_cluster_distance"] = Math.round(Math.sqrt(bestDistSq) * 1000) / 1000;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
newRow["_cluster_id"] = null;
|
|
202
|
+
newRow["_cluster_distance"] = null;
|
|
203
|
+
}
|
|
204
|
+
updatedRows.push(newRow);
|
|
205
|
+
}
|
|
206
|
+
yield {
|
|
207
|
+
...batch,
|
|
208
|
+
rows: updatedRows,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=cluster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../src/analytics/cluster.ts"],"names":[],"mappings":"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"}
|