From cfe1af3676fbf51338586b6ca61e3a18cdbb6f12 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 14 Nov 2017 16:12:50 +0100 Subject: [PATCH] Scrab exp. smoothing. wrong --- .../ExponentialSmoothing.php | 554 +----------------- Utils/Parser/Markdown/Markdown.php | 8 +- 2 files changed, 27 insertions(+), 535 deletions(-) diff --git a/Business/Finance/Forecasting/ExponentialSmoothing/ExponentialSmoothing.php b/Business/Finance/Forecasting/ExponentialSmoothing/ExponentialSmoothing.php index b18f2a8da..c4710d4db 100644 --- a/Business/Finance/Forecasting/ExponentialSmoothing/ExponentialSmoothing.php +++ b/Business/Finance/Forecasting/ExponentialSmoothing/ExponentialSmoothing.php @@ -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() + { } } \ No newline at end of file diff --git a/Utils/Parser/Markdown/Markdown.php b/Utils/Parser/Markdown/Markdown.php index bf38d30ce..94276dff8 100644 --- a/Utils/Parser/Markdown/Markdown.php +++ b/Utils/Parser/Markdown/Markdown.php @@ -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] === ' ') {