modify kmeans, add retailing functions
modify the kmeans to mini-batch k-means "ml/kmeans" add PI値 "retail/purchase-index", 平均客単価 "retail/average-spend"
This commit is contained in:
parent
93d192a995
commit
faa546d474
2 changed files with 124 additions and 71 deletions
55
server.ts
55
server.ts
|
|
@ -6,7 +6,7 @@
|
|||
import express from 'express';
|
||||
import * as math from 'mathjs';
|
||||
import * as _ from 'lodash';
|
||||
import { KMeans, Point } from './kmeans';
|
||||
import { KMeans, KMeansOptions } from './kmeans';
|
||||
import { getWeekNumber, getSameWeekDayLastYear } from './time-helper';
|
||||
|
||||
const app = express();
|
||||
|
|
@ -223,18 +223,19 @@ class AnalyticsEngine {
|
|||
}
|
||||
|
||||
// K-means wrapper (uses imported KMeans class)
|
||||
kmeans(matrix: DataMatrix, nClusters: number): { clusters: number[][][], centroids: number[][] } {
|
||||
validateMatrix(matrix);
|
||||
if (matrix.data[0].length !== 2) {
|
||||
throw new Error('K-means implementation currently only supports 2D data.');
|
||||
}
|
||||
const points = matrix.data.map(row => ({ x: row[0], y: row[1] }));
|
||||
const kmeans = new KMeans(points, nClusters);
|
||||
const result = kmeans.run();
|
||||
const centroids = result.clusters.map(c => [c.centroid.x, c.centroid.y]);
|
||||
const clusters = result.clusters.map(c => c.points.map(p => [p.x, p.y]));
|
||||
return { clusters, centroids };
|
||||
}
|
||||
kmeans(matrix: DataMatrix, nClusters: number, options: KMeansOptions = {}): { clusters: number[][][], centroids: number[][] } {
|
||||
validateMatrix(matrix);
|
||||
const points: number[][] = matrix.data;
|
||||
|
||||
// Use the new MiniBatchKMeans class
|
||||
const kmeans = new KMeans(points, nClusters, options);
|
||||
const result = kmeans.run();
|
||||
|
||||
const centroids = result.clusters.map(c => c.centroid);
|
||||
const clusters = result.clusters.map(c => c.points);
|
||||
|
||||
return { clusters, centroids };
|
||||
}
|
||||
|
||||
// Time helper wrapper functions
|
||||
getWeekNumber(dateString: string): number {
|
||||
|
|
@ -266,6 +267,20 @@ class AnalyticsEngine {
|
|||
if (salePrice === 0) throw new Error('Sale price cannot be zero');
|
||||
return (salePrice - cost) / salePrice;
|
||||
}
|
||||
|
||||
averageSpendPerCustomer(totalRevenue: number, numberOfCustomers: number): number {
|
||||
if (numberOfCustomers === 0) {
|
||||
throw new Error('Number of customers cannot be zero');
|
||||
}
|
||||
return totalRevenue / numberOfCustomers;
|
||||
}
|
||||
|
||||
purchaseIndex(totalItemsSold: number, numberOfCustomers: number): number {
|
||||
if (numberOfCustomers === 0) {
|
||||
throw new Error('Number of customers cannot be zero');
|
||||
}
|
||||
return (totalItemsSold / numberOfCustomers) * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize analytics engine
|
||||
|
|
@ -325,7 +340,9 @@ createRoute(app, 'post', '/api/series/rolling', (req) => {
|
|||
});
|
||||
|
||||
// Machine learning routes
|
||||
createRoute(app, 'post', '/api/ml/kmeans', (req) => analytics.kmeans(req.body.matrix, req.body.nClusters));
|
||||
createRoute(app, 'post', '/api/ml/kmeans', (req) => {
|
||||
return analytics.kmeans(req.body.matrix, req.body.nClusters, req.body.options);
|
||||
});
|
||||
|
||||
// Time helper routes
|
||||
createRoute(app, 'post', '/api/time/week-number', (req) => {
|
||||
|
|
@ -344,6 +361,16 @@ createRoute(app, 'post', '/api/retail/lift-value', (req) => analytics.liftValue(
|
|||
createRoute(app, 'post', '/api/retail/cost-ratio', (req) => analytics.costRatio(req.body.cost, req.body.salePrice));
|
||||
createRoute(app, 'post', '/api/retail/gross-margin', (req) => analytics.grossMarginRate(req.body.salePrice, req.body.cost));
|
||||
|
||||
createRoute(app, 'post', '/api/retail/average-spend', (req) => {
|
||||
const { totalRevenue, numberOfCustomers } = req.body;
|
||||
return analytics.averageSpendPerCustomer(totalRevenue, numberOfCustomers);
|
||||
});
|
||||
|
||||
createRoute(app, 'post', '/api/retail/purchase-index', (req) => {
|
||||
const { totalItemsSold, numberOfCustomers } = req.body;
|
||||
return analytics.purchaseIndex(totalItemsSold, numberOfCustomers);
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// ERROR HANDLING
|
||||
// ========================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue