mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 17:58:41 +00:00
Scrab exp. smoothing. wrong
This commit is contained in:
parent
ba90d72da0
commit
cfe1af3676
|
|
@ -10,6 +10,7 @@
|
|||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link http://website.orange-management.de
|
||||
* @see https://www.otexts.org/fpp/7/7
|
||||
*/
|
||||
declare(strict_types = 1);
|
||||
|
||||
|
|
@ -38,585 +39,76 @@ class ExponentialSmoothing
|
|||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function getRMSE() : float
|
||||
public function getANN()
|
||||
{
|
||||
return $this->rmse;
|
||||
}
|
||||
|
||||
public function getMSE() : float
|
||||
public function getANA()
|
||||
{
|
||||
return $this->mse;
|
||||
}
|
||||
|
||||
public function getMAE() : float
|
||||
public function getANM()
|
||||
{
|
||||
return $this->mae;
|
||||
}
|
||||
|
||||
public function getSSE() : float
|
||||
public function getAAN()
|
||||
{
|
||||
return $this->sse;
|
||||
}
|
||||
|
||||
public function getErrors() : array
|
||||
public function getAAA()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function getForecast(int $future, int $trendType = TrendType::NONE, int $seasonalType = SeasonalType::NONE, int $cycle = 12, float $damping = 1) : array
|
||||
public function getAAM()
|
||||
{
|
||||
$this->rmse = PHP_INT_MAX;
|
||||
|
||||
if ($trendType === TrendType::ALL || $seasonalType === SeasonalType::ALL) {
|
||||
$trends = [$trendType];
|
||||
if ($trendType === TrendType::ALL) {
|
||||
$trends = [TrendType::NONE, TrendType::ADDITIVE, TrendType::MULTIPLICATIVE];
|
||||
}
|
||||
|
||||
$seasonals = [$seasonalType];
|
||||
if ($seasonalType === SeasonalType::ALL) {
|
||||
$seasonals = [SeasonalType::NONE, SeasonalType::ADDITIVE, SeasonalType::MULTIPLICATIVE];
|
||||
}
|
||||
|
||||
$forecast = [];
|
||||
$bestError = PHP_INT_MAX;
|
||||
foreach ($trends as $trend) {
|
||||
foreach ($seasonals as $seasonal) {
|
||||
$tempForecast = $this->getForecast($future, $trend, $seasonal, $cycle, $damping);
|
||||
|
||||
if ($this->rmse < $bestError) {
|
||||
$bestError = $this->rmse;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $forecast;
|
||||
} elseif ($trendType === TrendType::NONE && $seasonalType === SeasonalType::NONE) {
|
||||
return $this->getNoneNone($future);
|
||||
} elseif ($trendType === TrendType::NONE && $seasonalType === SeasonalType::ADDITIVE) {
|
||||
return $this->getNoneAdditive($future, $cycle);
|
||||
} elseif ($trendType === TrendType::NONE && $seasonalType === SeasonalType::MULTIPLICATIVE) {
|
||||
return $this->getNoneMultiplicative($future, $cycle);
|
||||
} elseif ($trendType === TrendType::ADDITIVE && $seasonalType === SeasonalType::NONE) {
|
||||
return $this->getAdditiveNone($future, $damping);
|
||||
} elseif ($trendType === TrendType::ADDITIVE && $seasonalType === SeasonalType::ADDITIVE) {
|
||||
return $this->getAdditiveAdditive($future, $cycle, $damping);
|
||||
} elseif ($trendType === TrendType::ADDITIVE && $seasonalType === SeasonalType::MULTIPLICATIVE) {
|
||||
return $this->getAdditiveMultiplicative($future, $cycle, $damping);
|
||||
} elseif ($trendType === TrendType::MULTIPLICATIVE && $seasonalType === SeasonalType::NONE) {
|
||||
return $this->getMultiplicativeNone($future, $damping);
|
||||
} elseif ($trendType === TrendType::MULTIPLICATIVE && $seasonalType === SeasonalType::ADDITIVE) {
|
||||
return $this->getMultiplicativeAdditive($future, $cycle, $damping);
|
||||
} elseif ($trendType === TrendType::MULTIPLICATIVE && $seasonalType === SeasonalType::MULTIPLICATIVE) {
|
||||
return $this->getMultiplicativeMultiplicative($future, $cycle, $damping);
|
||||
}
|
||||
|
||||
throw new \Exception();
|
||||
}
|
||||
|
||||
private function dampingSum(float $damping, int $length) : float
|
||||
public function getAMN()
|
||||
{
|
||||
if (abs($damping - 1) < 0.001) {
|
||||
return $length;
|
||||
}
|
||||
|
||||
$sum = 0;
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$sum += pow($damping, $i);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
public function getNoneNone(int $future) : array
|
||||
public function getAMA()
|
||||
{
|
||||
$level = [$this->data[0]];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$level[$i] = $alpha * ($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) + (1 - $alpha) * $level[$i - 1];
|
||||
|
||||
$tempForecast[$i] = $level[$i];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getNoneAdditive(int $future, int $cycle) : array
|
||||
public function getAMM()
|
||||
{
|
||||
$level = [$this->data[0]];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
$seasonal = [];
|
||||
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$seasonal[$i] = $this->data[$i - 1] - $level[0];
|
||||
}
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$gamma = 0.00;
|
||||
|
||||
while ($gamma < 1) {
|
||||
$gamma_ = $gamma * (1 - $alpha);
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$hm = (int) floor(($i - 1) % $cycle) + 1;
|
||||
|
||||
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) - $seasonal[$i]) + (1 - $alpha) * $level[$i - 1];
|
||||
$seasonal[$i + $cycle] = $gamma_ * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) - $level[$i - 1]) + (1 - $gamma_) * $seasonal[$i];
|
||||
|
||||
$tempForecast[$i] = $level[$i] + $seasonal[$i + $hm];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$gamma += 0.01;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getNoneMultiplicative(int $future, int $cycle) : array
|
||||
public function getMNN()
|
||||
{
|
||||
$level = [$this->data[0]];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
$seasonal = [];
|
||||
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$seasonal[$i] = $this->data[$i] / $level[0];
|
||||
}
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$gamma = 0.00;
|
||||
|
||||
while ($gamma < 1) {
|
||||
$gamma_ = $gamma * (1 - $alpha);
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$hm = (int) floor(($i - 1) % $cycle) + 1;
|
||||
|
||||
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) / $seasonal[$i]) + (1 - $alpha) * $level[$i - 1];
|
||||
$seasonal[$i + $cycle] = $gamma_ * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) / $level[$i - 1]) + (1 - $gamma_) * $seasonal[$i];
|
||||
|
||||
$tempForecast[$i] = $level[$i] + $seasonal[$i + $hm];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$gamma += 0.01;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getAdditiveNone(int $future, float $damping) : array
|
||||
public function getMNA()
|
||||
{
|
||||
$level = [$this->data[0]];
|
||||
$trend = [$this->data[1] - $this->data[0]];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$beta = 0.00;
|
||||
|
||||
while ($beta < 1) {
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$level[$i] = $alpha * ($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) + (1 - $alpha) * ($level[$i - 1] + $damping * $trend[$i - 1]);
|
||||
$trend[$i] = $beta * ($level[$i] - $level[$i - 1]) + (1 - $beta) * $damping * $trend[$i - 1];
|
||||
|
||||
$tempForecast[$i] = $level[$i] + $this->dampingSum($damping, $i) * $trend[$i];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$beta += 0.01;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getAdditiveAdditive(int $future, int $cycle, float $damping) : array
|
||||
public function getMNM()
|
||||
{
|
||||
$level = [1 / $cycle * array_sum(array_slice($this->data, 0, $cycle))];
|
||||
$trend = [1 / $cycle];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
$seasonal = [];
|
||||
|
||||
$sum = 0;
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
|
||||
}
|
||||
|
||||
$trend[0] *= $sum;
|
||||
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$seasonal[$i] = $this->data[$i - 1] - $level[0];
|
||||
}
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$beta = 0.00;
|
||||
|
||||
while ($beta < 1) {
|
||||
$gamma = 0.00;
|
||||
|
||||
while ($gamma < 1) {
|
||||
$gamma_ = $gamma * (1 - $alpha);
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$hm = (int) floor(($i - 1) % $cycle) + 1;
|
||||
|
||||
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) - $seasonal[$i]) + (1 - $alpha) * ($level[$i - 1] + $damping * $trend[$i - 1]);
|
||||
$trend[$i] = $beta * ($level[$i] - $level[$i - 1]) + (1 - $beta) * $damping * $trend[$i - 1];
|
||||
$seasonal[$i + $cycle] = $gamma_ * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) - $level[$i - 1]) + (1 - $gamma_) * $seasonal[$i];
|
||||
|
||||
$tempForecast[$i] = $level[$i] + $this->dampingSum($damping, $i) * $trend[$i] + $seasonal[$i + $hm];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$gamma += 0.01;
|
||||
}
|
||||
|
||||
$beta += 0.01;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getAdditiveMultiplicative(int $future, int $cycle, float $damping) : array
|
||||
public function getMAN()
|
||||
{
|
||||
$level = [1 / $cycle * array_sum(array_slice($this->data, 0, $cycle))];
|
||||
$trend = [1 / $cycle];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
$seasonal = [];
|
||||
$gamma_ = $gamma * (1 - $alpha);
|
||||
|
||||
$sum = 0;
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
|
||||
}
|
||||
|
||||
$trend[0] *= $sum;
|
||||
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$seasonal[$i] = $this->data[$i] / $level[0];
|
||||
}
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$beta = 0.00;
|
||||
|
||||
while ($beta < 1) {
|
||||
$gamma = 0.00;
|
||||
|
||||
while ($gamma < 1) {
|
||||
$gamma_ = $gamma * (1 - $alpha);
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$hm = (int) floor(($i - 1) % $cycle) + 1;
|
||||
|
||||
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) / $seasonal[$i]) + (1 - $alpha) * ($level[$i - 1] + $damping * $trend[$i - 1]);
|
||||
$trend[$i] = $beta * ($level[$i] - $level[$i - 1]) + (1 - $beta) * $damping * $trend[$i - 1];
|
||||
$seasonal[$i + $cycle] = $gamma_ * ($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) / ($level[$i - 1] + $damping * $trend[$i - 1]) + (1 - $gamma_) * $seasonal[$i];
|
||||
|
||||
$tempForecast[] = ($level[$i] + $this->dampingSum($damping, $i) * $trend[$i - 1]) * $seasonal[$i + $hm];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$gamma += 0.01;
|
||||
}
|
||||
|
||||
$beta += 0.01;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getMultiplicativeNone(int $future, float $damping) : array
|
||||
public function getMAA()
|
||||
{
|
||||
$level = [$this->data[0]];
|
||||
$trend = [$this->data[1] / $this->data[0]];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$beta = 0.00;
|
||||
|
||||
while ($beta < 1) {
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$level[$i] = $alpha * ($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) + (1 - $alpha) * $level[$i - 1] * pow($trend[$i - 1], $damping);
|
||||
$trend[$i] = $beta * ($level[$i] / $level[$i - 1]) + (1 - $beta) * pow($trend[$i - 1], $damping);
|
||||
|
||||
$tempForecast[$i] = $level[$i] * pow($trend[$i], $this->dampingSum($damping, $i));
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$beta += 0.01;
|
||||
}
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getMultiplicativeAdditive(int $future, int $cycle, float $damping) : array
|
||||
public function getMAM()
|
||||
{
|
||||
$level = [$this->data[0]];
|
||||
$trend = [1 / $cycle];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
$seasonal = [];
|
||||
|
||||
$sum = 0;
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
|
||||
}
|
||||
|
||||
$trend[0] *= $sum;
|
||||
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$seasonal[$i] = $this->data[$i - 1] - $level[0];
|
||||
}
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$beta = 0.00;
|
||||
|
||||
while ($beta < 1) {
|
||||
$gamma = 0.00;
|
||||
|
||||
while ($gamma < 1) {
|
||||
$gamma_ = $gamma * (1 - $alpha);
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$hm = (int) floor(($i - 1) % $cycle) + 1;
|
||||
|
||||
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) - $seasonal[$i]) + (1 - $alpha) * $level[$i - 1] * pow($trend[$i - 1], $damping);
|
||||
$trend[$i] = $beta * ($level[$i] / $level[$i - 1]) + (1 - $beta) * pow($trend[$i - 1], $damping);
|
||||
$seasonal[$i + $cycle] = $gamma_ * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) - $level[$i - 1] * pow($trend[$i - 1], $damping)) + (1 - $gamma_) * $seasonal[$i];
|
||||
|
||||
$tempForecast[$i] = $level[$i] * pow($trend[$i], $this->dampingSum($damping, $i)) + $seasonal[$i + $hm];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$gamma += 0.01;
|
||||
}
|
||||
|
||||
$beta += 0.01;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
}
|
||||
|
||||
public function getMultiplicativeMultiplicative(int $future, int $cycle, float $damping) : array
|
||||
public function getMMN()
|
||||
{
|
||||
$level = [$this->data[0]];
|
||||
$trend = [1 / $cycle];
|
||||
$dataLength = count($this->data) + $future;
|
||||
$forecast = [];
|
||||
$seasonal = [];
|
||||
}
|
||||
|
||||
$sum = 0;
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$sum += ($this->data[$cycle] - $this->data[$i]) / $cycle;
|
||||
}
|
||||
public function getMMA()
|
||||
{
|
||||
}
|
||||
|
||||
$trend[0] *= $sum;
|
||||
|
||||
for ($i = 1; $i < $cycle + 1; $i++) {
|
||||
$seasonal[$i] = $this->data[$i] / $level[0];
|
||||
}
|
||||
|
||||
$alpha = 0.00;
|
||||
while ($alpha < 1) {
|
||||
$beta = 0.00;
|
||||
|
||||
while ($beta < 1) {
|
||||
$gamma = 0.00;
|
||||
|
||||
while ($gamma < 1) {
|
||||
$gamma_ = $gamma * (1 - $alpha);
|
||||
$error = [];
|
||||
$tempForecast = [];
|
||||
|
||||
for ($i = 1; $i < $dataLength; $i++) {
|
||||
$hm = (int) floor(($i - 1) % $cycle) + 1;
|
||||
|
||||
$level[$i] = $alpha * (($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) / $seasonal[$i]) + (1 - $alpha) * $level[$i - 1] * pow($trend[$i - 1], $damping);
|
||||
$trend[$i] = $beta * ($level[$i] / $level[$i - 1]) + (1 - $beta) * pow($trend[$i - 1], $damping);
|
||||
$seasonal[$i + $cycle] = $gamma_ * ($i < $dataLength - $future ? $this->data[$i - 1] : $tempForecast[$i - 1]) / ($level[$i - 1] * pow($trend[$i - 1], $damping)) + (1 - $gamma_) * $seasonal[$i];
|
||||
|
||||
$tempForecast[$i] = $level[$i] * pow($trend[$i], $this->dampingSum($damping, $i)) * $seasonal[$i + $hm];
|
||||
$error[] = $i < $dataLength - $future ? $this->data[$i] - $tempForecast[$i] : 0;
|
||||
}
|
||||
|
||||
$tempRMSE = Error::getRootMeanSquaredError($error);
|
||||
|
||||
if ($tempRMSE < $this->rmse) {
|
||||
$this->rmse = $tempRMSE;
|
||||
$forecast = $tempForecast;
|
||||
}
|
||||
|
||||
$gamma += 0.01;
|
||||
}
|
||||
|
||||
$beta += 0.01;
|
||||
}
|
||||
|
||||
$alpha += 0.01;
|
||||
}
|
||||
|
||||
$this->errors = $error;
|
||||
$this->mse = Error::getMeanSquaredError($error);
|
||||
$this->mae = Error::getMeanAbsoulteError($error);
|
||||
$this->sse = Error::getSumSquaredError($error);
|
||||
|
||||
return $forecast;
|
||||
public function getMMM()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ class Markdown
|
|||
{
|
||||
}
|
||||
|
||||
public function parse(string $raw) : string
|
||||
public static function parse(string $raw) : string
|
||||
{
|
||||
/*$raw = $this->cleanup($raw);
|
||||
$lines = explode("\n", $raw);
|
||||
|
|
@ -88,7 +88,7 @@ class Markdown
|
|||
return $raw;
|
||||
}
|
||||
|
||||
private function cleanup(string $raw) : string
|
||||
private static function cleanup(string $raw) : string
|
||||
{
|
||||
$raw = str_replace(["\r\n", "\r", "\t"], ["\n", "\n", ' '], $raw);
|
||||
$raw = trim($raw);
|
||||
|
|
@ -97,7 +97,7 @@ class Markdown
|
|||
return $raw;
|
||||
}
|
||||
|
||||
private function parseLines(array $lines) : string
|
||||
private static function parseLines(array $lines) : string
|
||||
{
|
||||
$block = array_keys(self::$blockTypes);
|
||||
$inline = array_keys(self::$inlineTypes);
|
||||
|
|
@ -111,7 +111,7 @@ class Markdown
|
|||
return '';
|
||||
}
|
||||
|
||||
private function countIndention(string $line) : int
|
||||
private static function countIndention(string $line) : int
|
||||
{
|
||||
$indent = 0;
|
||||
while (isset($line[$indent]) && $line[$indent] === ' ') {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user