Class: TeaLeaves::ExponentialSmoothingForecast

Inherits:
Forecast
  • Object
show all
Defined in:
lib/tealeaves/exponential_smoothing_forecast.rb

Defined Under Namespace

Classes: AdditiveSeasonalityStrategy, MultiplicativeSeasonalityStrategy, NoSeasonalityStrategy, SeasonalityStrategy

Instance Attribute Summary collapse

Attributes inherited from Forecast

#one_step_ahead_forecasts

Instance Method Summary collapse

Methods inherited from Forecast

#errors

Constructor Details

#initialize(time_series, period, opts = {}) ⇒ ExponentialSmoothingForecast

Returns a new instance of ExponentialSmoothingForecast.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 73

def initialize(time_series, period, opts={})
  @time_series = time_series
  @period = period
  @alpha = opts[:alpha]
  @beta  = opts[:beta]
  @gamma = opts[:gamma]
  @trend = opts[:trend]
  @seasonality = opts[:seasonality]
  @seasonality_strategy = case @seasonality
                          when :none
                            NoSeasonalityStrategy.new(@period, opts[:gamma])
                          when :additive
                            AdditiveSeasonalityStrategy.new(@period, opts[:gamma])
                          when :multiplicative
                            MultiplicativeSeasonalityStrategy.new(@period, opts[:gamma])
                          end

  calculate_one_step_ahead_forecasts
end

Instance Attribute Details

#alphaObject (readonly)

Returns the value of attribute alpha.



71
72
73
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 71

def alpha
  @alpha
end

#betaObject (readonly)

Returns the value of attribute beta.



71
72
73
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 71

def beta
  @beta
end

#gammaObject (readonly)

Returns the value of attribute gamma.



71
72
73
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 71

def gamma
  @gamma
end

#model_parametersObject (readonly)

Returns the value of attribute model_parameters.



98
99
100
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 98

def model_parameters
  @model_parameters
end

#seasonalityObject (readonly)

Returns the value of attribute seasonality.



71
72
73
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 71

def seasonality
  @seasonality
end

#trendObject (readonly)

Returns the value of attribute trend.



71
72
73
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 71

def trend
  @trend
end

Instance Method Details

#improve(opts) ⇒ Object



93
94
95
96
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 93

def improve(opts)
  new_opts = {:alpha => @alpha, :beta => @beta, :gamma => @gamma, :trend => @trend, :seasonality => @seasonality}.merge(opts)
  self.class.new(@time_series, @period, new_opts)
end

#initial_levelObject



100
101
102
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 100

def initial_level
  @initial_level ||= @time_series.take(@period).inject(&:+).to_f / @period
end

#initial_parametersObject



114
115
116
117
118
119
120
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 114

def initial_parameters
  { :level => initial_level,
    :trend => initial_trend,
    :seasonality => initial_seasonal_indices,
    :index => @seasonality_strategy.start_index
  }
end

#initial_seasonal_indicesObject



109
110
111
112
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 109

def initial_seasonal_indices
  operation = @seasonality == :multiplicative ? :/ : :-
  @time_series.take(@period).map {|v| v.to_f.send(operation, initial_level) }
end

#initial_trendObject



104
105
106
107
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 104

def initial_trend
  period_1, period_2 = @time_series.each_slice(@period).take(2)
  period_1.zip(period_2).map {|(a,b)| (b - a) / @period.to_f }.inject(&:+) / @period
end

#mean_squared_errorObject

Returns the mean squared error of the forecast.



131
132
133
134
135
136
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 131

def mean_squared_error
  return @mean_squared_error if @mean_squared_error

  numerator = errors.drop(@seasonality_strategy.start_index).map {|i| i ** 2 }.inject(&:+)
  @mean_squared_error = numerator / (errors.size - @seasonality_strategy.start_index).to_f
end

#predict(n = nil) ⇒ Object



122
123
124
125
126
127
128
# File 'lib/tealeaves/exponential_smoothing_forecast.rb', line 122

def predict(n=nil)
  if n.nil?
    forecast(@model_parameters).first
  else
    (1..n).map {|i| forecast(@model_parameters, i).first }
  end
end