-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
146 changed files
with
30,452 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import initChangepoint, { | ||
ChangepointDetector, | ||
} from "./dist/@bsull/augurs/changepoint.js"; | ||
|
||
await initChangepoint(); | ||
|
||
self.onmessage = (e) => { | ||
const { y } = e.data; | ||
const cpd = new ChangepointDetector("normal-gamma"); | ||
const cps = cpd.detectChangepoints(y); | ||
self.postMessage(cps); | ||
}; | ||
self.postMessage("ready"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import uPlot from "./dist/uPlot/uPlot.esm.js"; | ||
|
||
import { getSize } from "./helpers.js"; | ||
import { legendAsTooltipPlugin } from "./plugins.js"; | ||
|
||
function setUpPlot(data) { | ||
const opts = { | ||
...getSize(), | ||
series: [ | ||
{}, | ||
...data.slice(1).map((_, i) => { | ||
return { | ||
label: `${i + 1}`, | ||
stroke: "black", | ||
width: 1, | ||
}; | ||
}), | ||
], | ||
plugins: [legendAsTooltipPlugin()], | ||
}; | ||
const u = uPlot(opts, data, document.getElementById("clustering-plot")); | ||
window.addEventListener("resize", () => { | ||
u.setSize(getSize()); | ||
}); | ||
return u; | ||
} | ||
|
||
class ClusteringWorker { | ||
constructor() { | ||
this.worker = new Worker("./clustering.worker.js", { type: "module" }); | ||
this.dataPromise = fetch("./outlier.data.json").then((res) => res.json()); | ||
this.dataPromise.then((data) => { | ||
this.data = data.data; | ||
}); | ||
} | ||
|
||
static create = () => { | ||
return new Promise((resolve, reject) => { | ||
const worker = new ClusteringWorker(); | ||
worker.worker.onmessage = (e) => { | ||
if (e.data === "ready") { | ||
worker.dataPromise.then(() => resolve(worker)); | ||
} else { | ||
reject(); | ||
} | ||
} | ||
}) | ||
} | ||
|
||
cluster = async (dtwOpts, dbscanOpts) => { | ||
return new Promise((resolve, reject) => { | ||
const start = performance.now(); | ||
this.worker.postMessage({ | ||
dtwOpts, | ||
dbscanOpts, | ||
data: this.data.slice(1).map(arr => new Float64Array(arr)), | ||
}); | ||
this.worker.onmessage = (e) => { | ||
const elapsed = (performance.now() - start).toFixed(0); | ||
resolve({ clusterLabels: e.data, elapsed }); | ||
}; | ||
}); | ||
} | ||
} | ||
|
||
async function main() { | ||
const worker = await ClusteringWorker.create(); | ||
|
||
const u = setUpPlot(worker.data); | ||
async function runClustering(dtwOpts, dbscanOpts) { | ||
const { clusterLabels, elapsed } = await worker.cluster(dtwOpts, dbscanOpts); | ||
clusterLabels.forEach((cluster, i) => { | ||
const seriesIdx = i + 1; | ||
u.delSeries(seriesIdx); | ||
u.addSeries({ | ||
label: `${i} (cluster ${cluster})`, | ||
stroke: cluster === -1 ? "black" : cluster === 0 ? "blue" : cluster === 1 ? "red" : "yellow", | ||
width: 1, | ||
}, seriesIdx); | ||
}); | ||
u.redraw() | ||
document.getElementById("clustering-title").innerText = `Clustering with DBSCAN - done in ${elapsed}ms`; | ||
} | ||
const dtwOpts = { window: 2 }; | ||
const dbscanOpts = { epsilon: 5000, minClusterSize: 2 }; | ||
runClustering(dtwOpts, dbscanOpts); | ||
|
||
document.getElementById("clustering-dtw-window").addEventListener("change", function() { | ||
dtwOpts.window = parseFloat(this.value); | ||
runClustering(dtwOpts, dbscanOpts); | ||
}); | ||
document.getElementById("clustering-dbscan-epsilon").addEventListener("change", function() { | ||
dbscanOpts.epsilon = parseFloat(this.value); | ||
runClustering(dtwOpts, dbscanOpts); | ||
}); | ||
document.getElementById("clustering-dbscan-min-cluster-size").addEventListener("change", function() { | ||
dbscanOpts.minClusterSize = parseInt(this.value); | ||
runClustering(dtwOpts, dbscanOpts); | ||
}); | ||
} | ||
|
||
export default main; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import initDtw, { Dtw } from "./dist/@bsull/augurs/dtw.js"; | ||
import initClustering, { | ||
DbscanClusterer, | ||
} from "./dist/@bsull/augurs/clustering.js"; | ||
|
||
await Promise.all([initDtw(), initClustering()]); | ||
|
||
self.onmessage = (e) => { | ||
const { dtwOpts, dbscanOpts, data } = e.data; | ||
const dtw = Dtw.euclidean(dtwOpts); | ||
const distanceMatrix = dtw.distanceMatrix(data); | ||
const clusterer = new DbscanClusterer(dbscanOpts); | ||
const labels = clusterer.fit(distanceMatrix); | ||
self.postMessage(labels); | ||
}; | ||
self.postMessage("ready"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Prophet Stan model, compiled to WASM | ||
|
||
This is a WASM-compiled version of the [Prophet](https://facebook.github.io/prophet/) Stan model, for use with the [@bsull/augurs](https://github.com/grafana/augurs) library. | ||
|
||
## Usage | ||
|
||
```js | ||
import { Prophet } from '@bsull/augurs'; | ||
import { optimizer } from '@bsull/augurs-prophet-wasmstan'; | ||
|
||
// Create some fake data. | ||
// `ds` must be timestamps since the epoch, in seconds. | ||
const ds = [1704067200, 1704871384, 1705675569, 1706479753, 1707283938, 1708088123, | ||
1708892307, 1709696492, 1710500676, 1711304861, 1712109046, 1712913230, | ||
]; | ||
const y = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]; | ||
const trainingData = { ds, y }; | ||
|
||
// Create a Prophet model and fit it to the training data. | ||
const prophet = new Prophet(); | ||
prophet.fit(trainingdata); | ||
// Predict for the training set. | ||
prophet.predict(); | ||
// Predict for a new time point. | ||
prophet.predict({ ds: [ 1713717414 ]}) | ||
``` | ||
|
||
See the documentation for `@bsull/augurs` for more details. | ||
|
||
## Troubleshooting | ||
|
||
### Webpack | ||
|
||
The generated Javascript bindings in this package may require some additional Webpack configuration to work. | ||
Adding this to your `webpack.config.js` should be enough: | ||
|
||
```javascript | ||
{ | ||
experiments: { | ||
// Required to load WASM modules. | ||
asyncWebAssembly: true, | ||
}, | ||
resolve: { | ||
fallback: { | ||
fs: false, | ||
}, | ||
}, | ||
} | ||
``` |
15 changes: 15 additions & 0 deletions
15
demo/dist/@bsull/augurs-prophet-wasmstan/interfaces/augurs-prophet-wasmstan-optimizer.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export namespace AugursProphetWasmstanOptimizer { | ||
/** | ||
* Optimize the initial parameters given the data, returning the | ||
* optimal values under maximum likelihood estimation. | ||
*/ | ||
export function optimize(init: Inits, data: DataJson, opts: OptimizeOpts): OptimizeOutput; | ||
} | ||
import type { Inits } from './augurs-prophet-wasmstan-types.js'; | ||
export { Inits }; | ||
import type { DataJson } from './augurs-prophet-wasmstan-types.js'; | ||
export { DataJson }; | ||
import type { OptimizeOpts } from './augurs-prophet-wasmstan-types.js'; | ||
export { OptimizeOpts }; | ||
import type { OptimizeOutput } from './augurs-prophet-wasmstan-types.js'; | ||
export { OptimizeOutput }; |
Oops, something went wrong.