def test_htces(self):
        forecast_demand = Forecast(self.__orders_ex)

        ses_forecast = [
            i for i in forecast_demand.simple_exponential_smoothing(
                *(self.__smoothing_level_constant, ))
        ]

        sum_squared_error = forecast_demand.sum_squared_errors(
            ses_forecast, self.__smoothing_level_constant)

        standard_error = forecast_demand.standard_error(
            sum_squared_error, len(self.__orders_ex),
            self.__smoothing_level_constant)
        total_orders = 0

        for order in self.__orders_ex[:self.__initial_estimate_period]:
            total_orders += order

        avg_orders = total_orders / self.__initial_estimate_period

        evo_mod = OptimiseSmoothingLevelGeneticAlgorithm(
            orders=self.__orders_ex,
            average_order=avg_orders,
            smoothing_level=self.__smoothing_level_constant,
            population_size=10,
            standard_error=standard_error,
            recombination_type='two_point')

        ses_evo_forecast = evo_mod.simple_exponential_smoothing_evo(
            smoothing_level_constant=self.__smoothing_level_constant,
            initial_estimate_period=self.__initial_estimate_period)
        self.assertEqual(7, len(ses_evo_forecast))
Пример #2
0
    def test_optimise_smoothing_level_genetic_algorithm(self):
        total_orders = 0
        for order in self.__orders_ex[:12]:
            total_orders += order
        avg_orders = total_orders / 12
        f = Forecast(self.__orders_ex, avg_orders)
        alpha = [0.2, 0.3, 0.4, 0.5, 0.6]
        s = [i for i in f.simple_exponential_smoothing(*alpha)]
        sum_squared_error = f.sum_squared_errors(s, 0.5)
        standard_error = f.standard_error(sum_squared_error, len(self.__orders_ex), 0.5, 2)
        evo_mod = OptimiseSmoothingLevelGeneticAlgorithm(orders=self.__orders_ex,
                                                         average_order=avg_orders,
                                                         smoothing_level=0.5,
                                                         population_size=10,
                                                         standard_error=standard_error,
                                                         recombination_type='single_point')
        pop = evo_mod.initial_population()

        self.assertGreaterEqual(len(pop), 2)
        self.assertNotAlmostEqual(pop[0], 20.72, places=3)
        self.assertNotAlmostEqual(pop[1], 0.73, places=3)
Пример #3
0
def simple_exponential_smoothing_forecast(demand: list = None, smoothing_level_constant: float = 0.5,
                                          forecast_length: int = 5, initial_estimate_period: int = 6, **kwargs) -> dict:
    """ Performs a simple exoponential smoothing forecast on

    Args:
        forecast_length (int):              Number of periods to extend the forecast.
        demand (list):                      Original historical demand.
        smoothing_level_constant (float):   Alpha value
        initial_estimate_period (int):      Number of period to use to derive an average for the initial estimate.
        **ds (pd.DataFrame):                Data frame with raw data.
        **optimise (bool)                   Optimisation flag for exponential smoothing forecast.

    Returns:
        dict:       Simple exponential forecast

    Examples:

    >>> from supplychainpy.model_demand import simple_exponential_smoothing_forecast
    >>> orders = [165, 171, 147, 143, 164, 160, 152, 150, 159, 169, 173, 203, 169, 166, 162, 147, 188, 161, 162,
    ...           169, 185, 188, 200, 229, 189, 218, 185, 199, 210, 193, 211, 208, 216, 218, 264, 304]
    >>> ses = simple_exponential_smoothing_forecast(demand=orders, alpha=0.5, forecast_length=6, initial_period=18)


    """
    ds = kwargs.get('ds', 'UNKNOWN')
    if ds is not UNKNOWN:
        orders = list(kwargs.get('ds', "UNKNOWN"))
    else:
        orders = [int(i) for i in demand]
    forecast_demand = Forecast(orders)

    # optimise, population_size, genome_length, mutation_probability, recombination_types
    if len(kwargs) != 0:
        optimise_flag = kwargs.get('optimise', "UNKNOWN")
        if optimise_flag is not UNKNOWN:

            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(orders), smoothing_level_constant)
            total_orders = 0

            for order in orders[:initial_estimate_period]:
                total_orders += order

            avg_orders = total_orders / initial_estimate_period

            evo_mod = OptimiseSmoothingLevelGeneticAlgorithm(orders=orders,
                                                             average_order=avg_orders,
                                                             smoothing_level=smoothing_level_constant,
                                                             population_size=10,
                                                             standard_error=standard_error,
                                                             recombination_type='single_point')

            ses_evo_forecast = evo_mod.simple_exponential_smoothing_evo(
                smoothing_level_constant=smoothing_level_constant,
                initial_estimate_period=initial_estimate_period)

            return ses_evo_forecast
        else:
            return _ses_forecast(smoothing_level_constant=smoothing_level_constant,
                                 forecast_demand=forecast_demand,
                                 forecast_length=forecast_length)
    else:
        return _ses_forecast(smoothing_level_constant=smoothing_level_constant,
                             forecast_demand=forecast_demand,
                             forecast_length=forecast_length)
Пример #4
0
def holts_trend_corrected_exponential_smoothing_forecast(demand: list, alpha: float, gamma: float,
                                                         forecast_length: int = 4, initial_period: int = 6, **kwargs):
    if len(kwargs) != 0:
        if kwargs['optimise']:

            total_orders = 0

            for order in demand[:initial_period]:
                total_orders += order

            avg_orders = total_orders / initial_period
            forecast_demand = Forecast(demand)

            processed_demand = [{'t': index, 'demand': order} for index, order in enumerate(demand, 1)]
            stats = LinearRegression(processed_demand)

            log_stats = stats.least_squared_error(slice_end=6)

            htces_forecast = [i for i in
                              forecast_demand.holts_trend_corrected_exponential_smoothing(alpha=alpha, gamma=gamma,
                                                                                          intercept=log_stats.get(
                                                                                              'intercept'),
                                                                                          slope=log_stats.get(
                                                                                              'slope'))]

            sum_squared_error = forecast_demand.sum_squared_errors_indi_htces(squared_error=[htces_forecast],
                                                                              alpha=alpha, gamma=gamma)

            standard_error = forecast_demand.standard_error(sum_squared_error, len(demand), (alpha, gamma), 2)

            evo_mod = OptimiseSmoothingLevelGeneticAlgorithm(orders=demand,
                                                             average_order=avg_orders,
                                                             population_size=10,
                                                             standard_error=standard_error,
                                                             recombination_type='single_point')

            optimal_alpha = evo_mod.initial_population(individual_type='htces')

            log.log(logging.WARNING,
                    'An optimal alpha {} and optimal gamma {} have been found.'.format(optimal_alpha[1][0],
                                                                                       optimal_alpha[1][1]))

            htces_forecast = [i for i in
                              forecast_demand.holts_trend_corrected_exponential_smoothing(alpha=optimal_alpha[1][0],
                                                                                          gamma=optimal_alpha[1][1],
                                                                                          intercept=log_stats.get(
                                                                                              'intercept'),
                                                                                          slope=log_stats.get('slope'))]

            holts_forecast = forecast_demand.holts_trend_corrected_forecast(forecast=htces_forecast,
                                                                            forecast_length=forecast_length)
            log.log(logging.INFO, 'An OPTIMAL Holts trend exponential smoothing forecast has been generated.')
            sum_squared_error_opt = forecast_demand.sum_squared_errors_indi_htces(squared_error=[htces_forecast],
                                                                                  alpha=optimal_alpha[1][0],
                                                                                  gamma=optimal_alpha[1][1])

            standard_error_opt = forecast_demand.standard_error(sum_squared_error_opt, len(demand),
                                                                (optimal_alpha[1][0], optimal_alpha[1][1]), 2)

            ape = LinearRegression(htces_forecast)
            mape = forecast_demand.mean_aboslute_percentage_error_opt(htces_forecast)
            stats = ape.least_squared_error()
            regression_line = deepcopy(regr_ln(stats=stats))
            return {'forecast_breakdown': htces_forecast, 'forecast': holts_forecast, 'mape': mape, 'statistics': stats,
                    'optimal_alpha': optimal_alpha[1][0],
                    'optimal_gamma': optimal_alpha[1][1],
                    'SSE': sum_squared_error_opt,
                    'standard_error': standard_error_opt,
                    'original_standard_error': standard_error,
                    'regression': [i for i in regression_line.get('regression')]}

    else:

        forecast_demand = Forecast(demand)
        processed_demand = [{'t': index, 'demand': order} for index, order in enumerate(demand, 1)]
        stats = LinearRegression(processed_demand)
        log_stats = stats.least_squared_error(slice_end=6)
        htces_forecast = [i for i in
                          forecast_demand.holts_trend_corrected_exponential_smoothing(alpha=alpha, gamma=gamma,
                                                                                      intercept=log_stats.get(
                                                                                          'intercept'),
                                                                                      slope=log_stats.get(
                                                                                          'slope'))]

        holts_forecast = forecast_demand.holts_trend_corrected_forecast(forecast=htces_forecast,
                                                                        forecast_length=forecast_length)

        log.log(logging.INFO, 'A STANDARD Holts trend exponential smoothing forecast has been generated.')

        sum_squared_error = forecast_demand.sum_squared_errors_indi_htces(squared_error=[htces_forecast],
                                                                          alpha=alpha, gamma=gamma)

        ape = LinearRegression(htces_forecast)
        mape = forecast_demand.mean_aboslute_percentage_error_opt(htces_forecast)
        stats = ape.least_squared_error()
        regression_line = regr_ln(stats=stats)
        log.log(logging.WARNING, "A STANDARD Holts trend exponential smoothing forecast has been completed.")
        return {'forecast_breakdown': htces_forecast,
                'forecast': holts_forecast,
                'mape': mape,
                'statistics': stats,
                'sum_squared_errors': sum_squared_error,
                'regression': [i for i in regression_line.get('regression')]}