如何在React中调用Excel的FORECAST.ETS与FORECAST.LINEAR函数?
无需依赖Excel,直接用TypeScript实现FORECAST.ETS和FORECAST.LINEAR
不需要创建Excel文件再调用函数,这绝对不是唯一方式。你可以直接基于这两个函数的算法逻辑,用TypeScript手写实现,或者借助轻量的统计类工具函数完成需求。
1. 实现FORECAST.LINEAR(线性预测)
FORECAST.LINEAR的核心是简单线性回归,公式为 y = a + bx,其中:
b = (nΣxy - ΣxΣy) / (nΣx² - (Σx)²)a = (Σy - bΣx) / n
TypeScript实现代码:
/** * 实现Excel的FORECAST.LINEAR函数 * @param x 要预测的目标x值 * @param knownYs 已知的y值数组 * @param knownXs 对应的已知x值数组 * @returns 预测的y值 */ function forecastLinear(x: number, knownYs: number[], knownXs: number[]): number { const n = knownYs.length; if (n !== knownXs.length || n === 0) { throw new Error("已知x和y数组长度必须相等且不为空"); } let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0; for (let i = 0; i < n; i++) { sumX += knownXs[i]; sumY += knownYs[i]; sumXY += knownXs[i] * knownYs[i]; sumX2 += knownXs[i] ** 2; } const denominator = n * sumX2 - sumX ** 2; if (denominator === 0) { throw new Error("x值不能全部相同,无法计算线性回归"); } const b = (n * sumXY - sumX * sumY) / denominator; const a = (sumY - b * sumX) / n; return a + b * x; }
2. 实现FORECAST.ETS(指数平滑预测)
FORECAST.ETS基于三重指数平滑(ETS AAA模型),处理带趋势和季节性的时间序列数据。逻辑相对复杂,核心是计算三个平滑系数(水平、趋势、季节性),然后生成预测值。
以下是简化的TypeScript实现(适配默认的Excel参数:自动检测季节性,置信区间95%):
/** * 实现Excel的FORECAST.ETS函数(简化版,支持AAA模型) * @param targetDate 要预测的目标时间点(需转换为数值,比如时间戳或序列数) * @param knownYs 已知的y值数组 * @param knownDates 对应的已知时间点数组(需转换为数值) * @param seasonality 季节性周期,Excel默认自动检测,这里可手动传入,比如12代表月度季节性 * @returns 预测的y值 */ function forecastETS( targetDate: number, knownYs: number[], knownDates: number[], seasonality: number = 1 ): number { const n = knownYs.length; if (n !== knownDates.length || n < 2) { throw new Error("已知数据长度必须至少为2,且时间和值数组长度相等"); } // 计算时间间隔(假设时间序列是均匀的,Excel默认处理均匀间隔) const interval = knownDates[1] - knownDates[0]; const targetIndex = (targetDate - knownDates[0]) / interval; // 三重指数平滑系数(Excel默认自动优化,这里用经验值) const alpha = 0.3; // 水平平滑系数 const beta = 0.1; // 趋势平滑系数 const gamma = 0.1; // 季节性平滑系数 // 初始化水平、趋势、季节性值 let level = knownYs[0]; let trend = knownYs[1] - knownYs[0]; const seasonals: number[] = []; for (let i = 0; i < seasonality; i++) { seasonals.push(knownYs[i] - level); } // 迭代计算平滑值 for (let i = seasonality; i < n; i++) { const currentY = knownYs[i]; const seasonalIndex = i % seasonality; const predictedY = level + trend + seasonals[seasonalIndex]; // 更新水平 const newLevel = alpha * (currentY - seasonals[seasonalIndex]) + (1 - alpha) * (level + trend); // 更新趋势 const newTrend = beta * (newLevel - level) + (1 - beta) * trend; // 更新季节性 seasonals[seasonalIndex] = gamma * (currentY - newLevel) + (1 - gamma) * seasonals[seasonalIndex]; level = newLevel; trend = newTrend; } // 计算预测值 const forecastSeasonalIndex = Math.floor(targetIndex) % seasonality; return level + trend * (targetIndex - n + 1) + seasonals[forecastSeasonalIndex]; }
额外说明
- 如果你不想手动实现,可以用成熟的统计类工具函数(比如轻量的
stats.js),直接调用对应的线性回归、指数平滑方法,避免重复造轮子。 - 上述实现是核心逻辑的简化,和Excel原生函数的精度可能有细微差异(比如Excel会自动优化平滑系数、处理异常值),如果需要完全对齐,可以参考微软公开的FORECAST.ETS算法文档调整细节。
内容的提问来源于stack exchange,提问作者JVHE
相关产品推荐
相关产品推荐

