class Statsample::TimeSeries::Arima::KF::LogLikelihood

Attributes

aic[R]

Gives AIC(Akaike Information Criterion) www.scss.tcd.ie/Rozenn.Dahyot/ST7005/13AICBIC.pdf

log_likelihood[R]

Gives log likelihood value of an ARMA(p, q) process on given parameters

sigma[R]

Gives sigma value of an ARMA(p,q) process on given parameters

Public Class Methods

new(params, timeseries, p, q) click to toggle source
# File lib/statsample-timeseries/arima/likelihood.rb, line 17
def initialize(params, timeseries, p, q)
  @params = params
  @timeseries = timeseries.to_a
  @p = p
  @q = q
  ll
end

Public Instance Methods

ll() click to toggle source

Log likelihood link function.

iteratively minimized by simplex algorithm via KalmanFilter.ks Not meant to be used directly. Will make it private later.

# File lib/statsample-timeseries/arima/likelihood.rb, line 28
def ll
  params, timeseries = @params, @timeseries
  p, q = @p, @q

  phi = []
  theta = []
  phi = params[0...p] if p > 0
  theta = params[(p)...(p + q)] if q > 0

  [phi, theta].each do |v|
    if v.size>0 and v.map(&:abs).inject(:+) > 1
      return
    end
  end

  m = [p, q].max
  h = Matrix.column_vector(Array.new(m,0))
  m.times do |i|
    h[i,0] = phi[i] if i< p
    h[i,0] = h[i,0] + theta[i] if i < q
  end

  t = Matrix.zero(m)
  #set_column is available in utility.rb
  t = t.set_column(0, phi)
  if m > 1
    t[0...(m-1), 1...m] = Matrix.I(m-1)
    #chances of extra constant 0 values as unbalanced column, so:
    t = Matrix.columns(t.column_vectors)
  end

  g = Matrix[[1]]
  a_t = Matrix.column_vector(Array.new(m,0))
  n = timeseries.size
  z = Matrix.row_vector(Array.new(m,0))
  z[0,0] = 1
  p_t = Matrix.I(m)
  v_t, f_t = Array.new(n,0), Array.new(n, 0)

  n.times do |i|
    v_t[i] = (z * a_t).map { |x| timeseries[i] - x }[0,0]
    f_t[i] = (z * p_t * (z.transpose)).map { |x| x + 1 }[0,0]

    k_t = ((t * p_t * z.transpose) + h).map { |x| x.quo f_t[i] }

    a_t = (t * a_t) + (k_t * v_t[i])
    l_t = t - k_t * z
    j_t = h - k_t

    p_t = (t * p_t * (l_t.transpose)) + (h * (j_t.transpose))
  end

  pot = v_t.map(&:square).zip(f_t).map { |x,y| x / y}.inject(:+)
  sigma_2 = pot.to_f / n.to_f

  f_t_log_sum = f_t.map { |x| Math.log(x) }.inject(:+)
  @log_likelihood = -0.5 * (n*Math.log(2*Math::PI) + n*Math.log(sigma_2) + f_t_log_sum + n)
  
  @sigma = sigma_2
  @aic = -(2 * @log_likelihood - 2*(p+q+1))
  #puts ("ll = #{-ll}")
  return @log_likelihood
end
to_s() click to toggle source
# File lib/statsample-timeseries/arima/likelihood.rb, line 92
def to_s
  sprintf("LogLikelihood(p = %d, q = %d) on params: [%s]",
          @p, @q, @params.join(', '))
end