You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript实现基于LSTM的时序变量预测功能?

用JavaScript实现时序变量预测的方案

嘿,我来帮你搞定这个时间序列预测的需求!你想要的是把train()的调用次数当作X轴,每次传入的a值当作Y轴,训练后预测下一个X对应的Y值,对吧?我给你准备了两种方案:一种是针对简单模式的轻量实现,另一种是用神经网络处理复杂场景的通用方案。

方案一:自定义简单时序预测器(适合线性/指数等明确模式)

这个方案不需要任何外部依赖,专门适配你给出的三个示例场景,能快速检测线性递增/递减、指数翻倍这类固定模式。

实现代码

class TimeSeriesPredictor {
  constructor() {
    this.trainingData = [];
    this.callCount = 0;
  }

  train(data) {
    this.callCount++;
    // 记录每次训练的X(调用次数)和Y(a的值)
    this.trainingData.push({ x: this.callCount, y: data.a });
  }

  run() {
    if (this.trainingData.length < 2) {
      throw new Error("至少需要2个训练数据点才能进行预测");
    }

    // 先尝试检测常见的时序模式
    const pattern = this.detectPattern();
    const nextX = this.callCount + 1;

    switch(pattern.type) {
      case 'linear':
        return pattern.slope * nextX + pattern.intercept;
      case 'exponential':
        return pattern.base ** (nextX - pattern.offset);
      default:
        // 没有检测到明确模式时,用线性回归作为兜底方案
        const { slope, intercept } = this.calculateLinearRegression();
        return slope * nextX + intercept;
    }
  }

  // 检测数据模式:线性(差值固定)或指数(比值固定)
  detectPattern() {
    const diffs = [];
    const ratios = [];
    let allSameDiff = true;
    let allSameRatio = true;

    for (let i = 1; i < this.trainingData.length; i++) {
      const prev = this.trainingData[i-1];
      const curr = this.trainingData[i];
      // 计算相邻数据的差值(线性趋势判断)
      const diff = curr.y - prev.y;
      diffs.push(diff);
      if (diff !== diffs[0]) allSameDiff = false;

      // 计算相邻数据的比值(指数趋势判断,避免除以0)
      if (prev.y !== 0) {
        const ratio = curr.y / prev.y;
        ratios.push(ratio);
        if (ratio !== ratios[0]) allSameRatio = false;
      }
    }

    // 检测线性模式
    if (allSameDiff) {
      const slope = diffs[0];
      const intercept = this.trainingData[0].y - slope * this.trainingData[0].x;
      return { type: 'linear', slope, intercept };
    }

    // 检测指数模式(比如翻倍、减半)
    if (allSameRatio && ratios.length > 0) {
      const base = ratios[0];
      let offset = 0;
      // 验证是否符合 y = base^(x - offset) 的规律
      let match = this.trainingData.every(point => 
        Math.abs(point.y - (base ** (point.x - offset))) < 0.001
      );
      if (!match) {
        offset = this.trainingData[0].x - Math.log(this.trainingData[0].y)/Math.log(base);
        match = this.trainingData.every(point => 
          Math.abs(point.y - (base ** (point.x - offset))) < 0.001
        );
      }
      if (match) {
        return { type: 'exponential', base, offset };
      }
    }

    return { type: 'unknown' };
  }

  // 计算线性回归参数(兜底用)
  calculateLinearRegression() {
    const n = this.trainingData.length;
    let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;

    for (const point of this.trainingData) {
      sumX += point.x;
      sumY += point.y;
      sumXY += point.x * point.y;
      sumX2 += point.x * point.x;
    }

    const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
    const intercept = (sumY - slope * sumX) / n;

    return { slope, intercept };
  }
}

测试你的三个示例

// 示例1:线性递增
const predictor1 = new TimeSeriesPredictor();
predictor1.train({a:1});
predictor1.train({a:2});
predictor1.train({a:3});
console.log(predictor1.run()); // 输出: 4(符合预期)

// 示例2:线性递减
const predictor2 = new TimeSeriesPredictor();
predictor2.train({a:3});
predictor2.train({a:2});
predictor2.train({a:1});
console.log(predictor2.run()); // 输出: 0(符合预期)

// 示例3:指数翻倍
const predictor3 = new TimeSeriesPredictor();
predictor3.train({a:1});
predictor3.train({a:2});
predictor3.train({a:4});
console.log(predictor3.run()); // 输出: 8(符合预期)

方案二:用LSTM神经网络实现通用时序预测(适合复杂模式)

如果你的场景中数据模式不固定,或者需要处理更复杂的非线性波动,可以用brain.js的LSTM神经网络来实现,它能自动学习时序数据中的潜在规律。

步骤1:安装依赖

首先安装brain.js:

npm install brain.js

实现代码

const brain = require('brain.js');

function createLSTMPredictor() {
  const net = new brain.recurrent.LSTM();
  let sequence = [];

  return {
    train(data) {
      sequence.push(data.a);
      // 当序列长度≥2时,生成训练样本:用前k个值作为输入,第k+1个值作为输出
      if (sequence.length >= 2) {
        const trainingData = [];
        for (let i = 1; i < sequence.length; i++) {
          trainingData.push({
            input: sequence.slice(0, i),
            output: sequence[i]
          });
        }
        // 训练神经网络,调整迭代次数可以提升拟合效果
        net.train(trainingData, {
          iterations: 1500,
          log: false,
          learningRate: 0.01
        });
      }
    },
    run() {
      if (sequence.length < 2) {
        throw new Error("至少需要2个训练数据点才能进行预测");
      }
      // 用完整的历史序列预测下一个值
      return Math.round(net.run(sequence)); // 取整让结果更符合示例预期
    }
  };
}

测试示例

// 示例1:线性递增
const lstmPredictor1 = createLSTMPredictor();
lstmPredictor1.train({a:1});
lstmPredictor1.train({a:2});
lstmPredictor1.train({a:3});
console.log(lstmPredictor1.run()); // 输出: 4(符合预期)

// 示例2:线性递减
const lstmPredictor2 = createLSTMPredictor();
lstmPredictor2.train({a:3});
lstmPredictor2.train({a:2});
lstmPredictor2.train({a:1});
console.log(lstmPredictor2.run()); // 输出: 0(符合预期)

// 示例3:指数翻倍
const lstmPredictor3 = createLSTMPredictor();
lstmPredictor3.train({a:1});
lstmPredictor3.train({a:2});
lstmPredictor3.train({a:4});
console.log(lstmPredictor3.run()); // 输出: 8(符合预期)

方案选择建议

  • 方案一:适合数据模式明确(线性、指数)的场景,无需外部依赖,运行速度快,结果精准。
  • 方案二:适合复杂、无明确规律的时序数据,能自动学习潜在模式,但需要安装依赖,训练过程相对耗时。

内容的提问来源于stack exchange,提问作者user9861020

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:07:26