def _ses_forecast(smoothing_level_constant: float, forecast_demand: Forecast, forecast_length: int, orders_length: int) -> dict: """ Private function for executing the simple exponential smoothing forecast. """ forecast_breakdown = [ i for i in forecast_demand.simple_exponential_smoothing( smoothing_level_constant) ] ape = LinearRegression(forecast_breakdown) mape = forecast_demand.mean_aboslute_percentage_error_opt( forecast_breakdown) stats = ape.least_squared_error() simple_forecast = forecast_demand.simple_exponential_smoothing_forecast( forecast=forecast_breakdown, forecast_length=forecast_length) sum_squared_error = forecast_demand.sum_squared_errors( simple_forecast, smoothing_level_constant) standard_error = forecast_demand.standard_error(sum_squared_error, orders_length, smoothing_level_constant) regression_line = _regr_ln(stats=stats) log.log( logging.WARNING, "A STANDARD simple exponential smoothing forecast has been completed.") return { 'forecast_breakdown': forecast_breakdown, 'mape': mape, 'statistics': stats, 'forecast': simple_forecast, 'alpha': smoothing_level_constant, 'standard_error': standard_error, 'regression': [i for i in regression_line.get('regression')] }
def simple_exponential_smoothing_evo( self, smoothing_level_constant: float, initial_estimate_period: int, recombination_type: str = 'single_point', population_size: int = 10, forecast_length: int = 5) -> dict: """ Simple exponential smoothing using evolutionary algorithm for optimising smoothing level constant (alpha value) Args: initial_estimate_period (int): The number of previous data points required for initial level estimate. smoothing_level_constant (float): Best guess at smoothing level constant appropriate for forecast. Returns: dict: Example: """ log.log( logging.INFO, "Executing simple exponential smoothing. " "SMOOTHING_LEVEL: {} " "INITIAL_ESTIMATE_PERIOD: {} " "RECOMBINATION_TYPE: {} " "POPULATION_SIZE: {} " "FORECAST_LENGTH: {}".format(smoothing_level_constant, initial_estimate_period, recombination_type, population_size, forecast_length)) if None != self.__recombination_type: recombination_type = self.__recombination_type sum_orders = 0 for demand in self.__orders[:initial_estimate_period]: sum_orders += demand avg_orders = sum_orders / initial_estimate_period forecast_demand = Forecast(self.__orders, avg_orders) #calls simple_exponential_smoothing method from Forecast object ses_forecast = [ i for i in forecast_demand.simple_exponential_smoothing( *(smoothing_level_constant, )) ] sum_squared_error = forecast_demand.sum_squared_errors( ses_forecast, smoothing_level_constant) standard_error = forecast_demand.standard_error( sum_squared_error, len(self.__orders), smoothing_level_constant) evo_mod = OptimiseSmoothingLevelGeneticAlgorithm( orders=self.__orders, average_order=avg_orders, smoothing_level=smoothing_level_constant, population_size=population_size, standard_error=standard_error, recombination_type=recombination_type) optimal_alpha = evo_mod.initial_population() optimal_ses_forecast = [ i for i in forecast_demand.simple_exponential_smoothing( optimal_alpha[1]) ] ape = LinearRegression(optimal_ses_forecast) mape = forecast_demand.mean_aboslute_percentage_error_opt( optimal_ses_forecast) stats = ape.least_squared_error() simple_forecast = forecast_demand.simple_exponential_smoothing_forecast( forecast=optimal_ses_forecast, forecast_length=forecast_length) sum_squared_error = forecast_demand.sum_squared_errors( optimal_ses_forecast, optimal_alpha[1]) standard_error = forecast_demand.standard_error( sum_squared_error, len(self.__orders), optimal_alpha[1]) regression = { 'regression': [(stats.get('slope') * i) + stats.get('intercept') for i in range(0, 12)] } log.log( logging.INFO, "An OPTIMISED simple exponential smoothing forecast has been completed" ) return { 'forecast_breakdown': optimal_ses_forecast, 'mape': mape, 'statistics': stats, 'forecast': simple_forecast, 'optimal_alpha': optimal_alpha[1], 'standard_error': standard_error, 'regression': [i for i in regression.get('regression')] }