1
$\begingroup$

I am trying to perform a Holt-Winters forecasting for future dates in Python. There is a working code but it only predicts one point ahead so at the end of the series, I only one more point for the HoltWinters, I would like to modify this code and add 3 more months to the forecasted values.

I've been trying to figure this out and not able to solve it. I'd really appreciate any insight or what I am doing wrong:

Series data looks like this, first value is the actual data point and second is the time in epoch format:

[[111318489540.15584, 1419872032], [111319184415.82709, 1419958432], [111319382979.16595, 1420044832], [111318808170.7551, 1420131232], [111318903144.42294, 1420217632]

This is the working code for one point forecasting:

def holtWintersAnalysis(series):
  alpha = gamma = 0.1
  beta = 0.0035
  # season is currently one day
  season_length = (30*24*60*60) / series.step
  intercept = 0
  slope = 0
  pred = 0
  intercepts = list()
  slopes = list()
  seasonals = list()
  predictions = list()
  deviations = list()

  def getLastSeasonal(i):
    j = i - season_length
    if j >= 0:
      return seasonals[j]
    return 0

  def getLastDeviation(i):
    j = i - season_length
    if j >= 0:
      return deviations[j]
    return 0

  last_seasonal = 0
  last_seasonal_dev = 0
  next_last_seasonal = 0
  next_pred = None

  for i,actual in enumerate(series):
    if actual is None:
      # missing input values break all the math
      # do the best we can and move on
      intercepts.append(None)
      slopes.append(0)
      seasonals.append(0)
      predictions.append(next_pred)
      deviations.append(0)
      next_pred = None
      continue

    if i == 0:
      last_intercept = actual
      last_slope = 0
      # seed the first prediction as the first actual
      prediction = actual
    else:
      last_intercept = intercepts[-1]
      last_slope = slopes[-1]
      if last_intercept is None:
        last_intercept = actual
      prediction = next_pred

    last_seasonal = getLastSeasonal(i)
    next_last_seasonal = getLastSeasonal(i+1)
    last_seasonal_dev = getLastDeviation(i)

    intercept = holtWintersIntercept(alpha,actual,last_seasonal
            ,last_intercept,last_slope)
    slope = holtWintersSlope(beta,intercept,last_intercept,last_slope)
    seasonal = holtWintersSeasonal(gamma,actual,intercept,last_seasonal)
    next_pred = intercept + slope + next_last_seasonal
    deviation = holtWintersDeviation(gamma,actual,prediction,last_seasonal_dev)

    intercepts.append(intercept)
    slopes.append(slope)
    seasonals.append(seasonal)
    predictions.append(prediction)
    deviations.append(deviation)

  # make the new forecast series
  forecastName = "holtWintersForecast(%s)" % series.name
  forecastSeries = TimeSeries(forecastName, series.start, series.end
    , series.step, predictions)
  forecastSeries.pathExpression = forecastName

  # make the new deviation series
  deviationName = "holtWintersDeviation(%s)" % series.name
  deviationSeries = TimeSeries(deviationName, series.start, series.end
          , series.step, deviations)
  deviationSeries.pathExpression = deviationName

  results = { 'predictions': forecastSeries
        , 'deviations': deviationSeries
        , 'intercepts': intercepts
        , 'slopes': slopes
        , 'seasonals': seasonals
        }
  return results

It looks like it is looking at the data and performing holtWinters algo and appending values to a list called:

predictions

The next after this loop:

for i,actual in enumerate(series):

...

I put these lines to

 ##remove non numeric values (e.g. from the list)
 predictions=filter(None,predictions)
 #retrieve the last predicted value
 last_pred=predictions[-1]
 #remove non numeric values from the slopes list
 slopes=filter(None,slopes)
 #remove non numeric values from the intercepts list
 intercepts=filter(None,intercepts)
 #calculate the over all intercept
 over_all_intercept=float(sum(intercepts))/float(len(intercepts))
 #calculate the over all slope
 over_all_slope=float(sum(slopes))/float(len(slopes))

for hard coded 90 periods, perform forecast from the last value from the predictions list

  new_pred=list()
  n=90
  new_value=last_pred
  for i in xrange(1,n+1,1):
    new_value=new_value+over_all_intercept+over_all_slope
    new_pred.append(new_value)

append the new_pred list to the predictions list

  predictions.append(new_pred)

Then re-format the forecast series with time series data

retrieve last months data from the existing series

start = int(time.time())-2592000

set the end of the series 3 months

end = int(time.time()) + 5184000

  forecastName = "holtWintersForecast(%s)" % series.name
  forecastSeries = TimeSeries(forecastName, series.start, series.end
    , series.step, predictions)
  forecastSeries.pathExpression = forecastName

When I run though this it only, I only see future forecasting data for 14 days rather than 3 months.

Can somebody give some insight what might be going on here?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.