如何使用Holt Winters季节阻尼法计算PHP中的两个月销售预测?
霍尔特·温特斯介绍如下: 这里讨论了它的季节性阻尼版本(向下滚动页面): 简而言之,它主要关注三件事:如何使用Holt Winters季节阻尼法计算PHP中的两个月销售预测?,php,projection,ecommerce-sales,Php,Projection,Ecommerce Sales,霍尔特·温特斯介绍如下: 这里讨论了它的季节性阻尼版本(向下滚动页面): 简而言之,它主要关注三件事: 长期趋势 短期趋势 季节趋势 它也不能将这些数据平均在一起,因为你真正需要的是加权平均,季节性和短期趋势比长期趋势更重要,当然,还有金融数据趋势 给定$anYear1和$anYear2,我如何应用Holt Winters季节性阻尼方法预测$anYear2结束后的2个月?假设$anYear1是由12个数字组成的数组。假设$anYear2是一个由0到12个数字组成的数组 因此,我可以用随机
- 长期趋势
- 短期趋势
- 季节趋势
<?php
$anYear1 = array();
$anYear2 = array();
$nStop = 10; // so we need 11 and 12 of the year
for ($i = 1; $i <= 12; $i++) {
$anYear1[$i] = rand(200,500);
if ($i <= $nStop) {
// give it a natural lift like real financial data
$anYear2[$i] = rand(400,700);
}
}
$nSeasonRange = 4; // 4 months in a business quarter
Therefore, I want to create a function like so:
function forecastHoltWinters($anYear1, $anYear2, $nSeasonRange = 4) {
///////////////////
// DO MAGIC HERE //
///////////////////
// an array with 2 numbers, indicating 2 months forward from end of $anYear2
return $anForecast;
}
$anForecast = forecastHoltWinters($anYear1, $anYear2, $nSeasonRange);
echo "YEAR 1\n";
print_r($anYear1);
echo "\n\nYEAR 2\n"
print_r($anYear2);
echo "\n\nTWO MONTHS FORECAST\n";
print_r($anForecast);
我找到了一种方法来调整函数以满足我的需要
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
$anYear1 = array();
$anYear2 = array();
$nStop = 10;
for($i = 1; $i <= 12; $i++) {
$anYear1[$i] = rand(100,400);
if ($i <= $nStop) {
$anYear2[$i+12] = rand(200,600);
}
}
print_r($anYear1);
print_r($anYear2);
$anData = array_merge($anYear1,$anYear2);
print_r(forecastHoltWinters($anData));
function forecastHoltWinters($anData, $nForecast = 2, $nSeasonLength = 4, $nAlpha = 0.2, $nBeta = 0.01, $nGamma = 0.01, $nDevGamma = 0.1) {
// Calculate an initial trend level
$nTrend1 = 0;
for($i = 0; $i < $nSeasonLength; $i++) {
$nTrend1 += $anData[$i];
}
$nTrend1 /= $nSeasonLength;
$nTrend2 = 0;
for($i = $nSeasonLength; $i < 2*$nSeasonLength; $i++) {
$nTrend2 += $anData[$i];
}
$nTrend2 /= $nSeasonLength;
$nInitialTrend = ($nTrend2 - $nTrend1) / $nSeasonLength;
// Take the first value as the initial level
$nInitialLevel = $anData[0];
// Build index
$anIndex = array();
foreach($anData as $nKey => $nVal) {
$anIndex[$nKey] = $nVal / ($nInitialLevel + ($nKey + 1) * $nInitialTrend);
}
// Build season buffer
$anSeason = array_fill(0, count($anData), 0);
for($i = 0; $i < $nSeasonLength; $i++) {
$anSeason[$i] = ($anIndex[$i] + $anIndex[$i+$nSeasonLength]) / 2;
}
// Normalise season
$nSeasonFactor = $nSeasonLength / array_sum($anSeason);
foreach($anSeason as $nKey => $nVal) {
$anSeason[$nKey] *= $nSeasonFactor;
}
$anHoltWinters = array();
$anDeviations = array();
$nAlphaLevel = $nInitialLevel;
$nBetaTrend = $nInitialTrend;
foreach($anData as $nKey => $nVal) {
$nTempLevel = $nAlphaLevel;
$nTempTrend = $nBetaTrend;
$nAlphaLevel = $nAlpha * $nVal / $anSeason[$nKey] + (1.0 - $nAlpha) * ($nTempLevel + $nTempTrend);
$nBetaTrend = $nBeta * ($nAlphaLevel - $nTempLevel) + ( 1.0 - $nBeta ) * $nTempTrend;
$anSeason[$nKey + $nSeasonLength] = $nGamma * $nVal / $nAlphaLevel + (1.0 - $nGamma) * $anSeason[$nKey];
$anHoltWinters[$nKey] = ($nAlphaLevel + $nBetaTrend * ($nKey + 1)) * $anSeason[$nKey];
$anDeviations[$nKey] = $nDevGamma * abs($nVal - $anHoltWinters[$nKey]) + (1-$nDevGamma)
* (isset($anDeviations[$nKey - $nSeasonLength]) ? $anDeviations[$nKey - $nSeasonLength] : 0);
}
$anForecast = array();
$nLast = end($anData);
for($i = 1; $i <= $nForecast; $i++) {
$nComputed = round($nAlphaLevel + $nBetaTrend * $anSeason[$nKey + $i]);
if ($nComputed < 0) { // wildly off due to outliers
$nComputed = $nLast;
}
$anForecast[] = $nComputed;
}
return $anForecast;
}
我在大学里没有学微积分,真是自责!