1. Being stupid - need help

Hi,

I translated 2 routines "HoltWinterspredictAdd" and "HoltWinterspredictMult" from [https://github.com/antoinevastel/zodiac-ts/blob/master/index.js].

-- Calculates the mean squared error 
public function MeanSquaredError(sequence truth, sequence prediction) 
  atom rss = 0.0 
  for i = 1 to length(truth) do 
    rss += msqrt(truth[i] - prediction[i]) 
  end for 
  return abs(rss / length(truth)) 
end function 
 
public function HoltWinterspredictMult(sequence data, atom alpha, atom delta, atom gamma, integer seasonLength) 
  integer datalen = length(data) 
  sequence A = repeat(0.0, datalen) 
  sequence B = repeat(0.0, datalen) 
  sequence S = repeat(0.0, datalen) 
  A[seasonLength] = 0.0 
  atom averageFirstSeason = 0.0 
  for i = 1 to seasonLength do 
      averageFirstSeason += data[i] 
  end for 
  B[seasonLength] = averageFirstSeason/seasonLength 
  for i = 1 to seasonLength+1 do 
    S[i] = data[i]/(averageFirstSeason/seasonLength) 
  end for 
  for i = seasonLength+1 to datalen do 
    B[i] = alpha * (data[i]/S[i - seasonLength]) + (1.0-alpha)*(B[i-1]+A[i-1]) 
    A[i] = gamma * (B[i]-B[i-1])  + (1.0-gamma)*A[i-1] 
    S[i] = delta * (data[i]/B[i]) + (1.0-delta)*S[i-seasonLength] 
  end for 
  sequence forecast = repeat(0.0, datalen + seasonLength) 
  for i = seasonLength+1 to datalen do 
    forecast[i] = (A[i-1] + B[i-1])*S[i - seasonLength] 
  end for 
  for i = datalen to datalen + seasonLength do 
    forecast[i] = (B[datalen-1] + (i - datalen-1) * A[datalen-1]) * S[i - seasonLength] 
  end for 
  A = {} B = {} S = {}   
  atom sse = MeanSquaredError(data, forecast) 
  return {sse, forecast} 
end function 
 
public public function HoltWinterspredictAdd(sequence data, atom alpha, atom delta, atom gamma, integer seasonLength) 
  integer datalen = length(data) 
  sequence A = repeat(0.0, datalen) 
  sequence B = repeat(0.0, datalen) 
  sequence S = repeat(0.0, datalen) 
  A[seasonLength] = 0.0 
  atom averageFirstSeason = 0.0 
  for i = 1 to seasonLength do 
    averageFirstSeason += data[i] 
  end for 
  B[seasonLength] = averageFirstSeason/seasonLength+1 
  for i = 1 to seasonLength+1 do 
    S[i] = data[i] - averageFirstSeason/seasonLength 
  end for 
  for i = seasonLength+1 to datalen do 
    B[i] = alpha * (data[i] - S[i - seasonLength]) + (1.0-alpha) * (B[i-1]+A[i-1]) 
    A[i] = gamma * (B[i]-B[i-1])  + (1.0-gamma) * A[i-1] 
    S[i] = delta * (data[i] - B[i]) + (1.0-delta) * S[i-seasonLength] 
  end for 
  sequence forecast = repeat(0.0, datalen + seasonLength) 
  for i = seasonLength+1 to datalen do 
    forecast[i] = A[i-1] + B[i-1] + S[i - seasonLength] 
  end for 
  for i = datalen to datalen + seasonLength do 
    forecast[i] = B[datalen-1] + ((i - datalen) * A[datalen-1]) + S[i - seasonLength] 
  end for 
  A = {} B = {} S = {} 
  atom sse = MeanSquaredError(data, forecast) 
  return {sse, forecast} 
end function 

the functions are tested via:

atom alpha = 0.4 
atom gamma = 0.2 
atom delta = 0.5 
atom ret 
sequence result 
sequence data = {61.5, 63.2, 55.8, 71.4, 70, 71.4, 63.9, 78.9, 78.3, 78.6, 71.9, 87, 86.2, 87.5, 80.1, 92.5} 
{ret, result} = HoltWinterspredictAdd(data, alpha, delta, gamma, 4) 
sequence expectedResult = {0.0, 0.0, 0.0, 0.0, 61.5, 67.28, 62.537600000000005, 79.80115200000003, 73.13719104, 77.04783918080001,71.025120930816, 87.94969470636033,83.61671728317809,85.7372107163745,79.93725983621758,96.31433531356754,91.95095302251006, 
                           92.64088086972602,85.36367192818317,100.17738187172976} 
 
 
 
{ret, result} = HoltWinterspredictMult(data, alpha, delta, gamma, 4) 
sequence expectedResult = {0, 0, 0, 0,61.5, 67.39278048780487, 61.81707875270145, 81.53022450414605,73.0764828139659, 77.07844011856474,69.47490699048109, 90.35656320643135,83.73280606463544, 85.74340016330459,77.7770276222308, 98.90911323239595,92.39012665258913, 92.99431396647569,83.54705489973043, 101.37471727927124} 

when i run the functions, i get almost the correct expected results and i have no idea where my error is. So I need help - can any one venture a try?
I use phix and thank you in advance
Richard

new topic     » topic index » view message » categorize

2. Re: Being stupid - need help

Hi, I may be being equally stupid, and hopefully this will stimulate some thought rather than just a solution, but your mean squared error formula seems to be different to the .js one

-- Calculates the mean squared error  
public function MeanSquaredError(sequence truth, sequence prediction)  
  atom rss = 0.0  
  for i = 1 to length(truth) do  
    rss += msqrt(truth[i] - prediction[i])  
  end for  
  return abs(rss / length(truth))  
end function  
exports.HoltWintersSmoothing.prototype.computeMeanSquaredError = function() 
{  
	var SSE = 0.0; 
	var n = 0; 
	for(var i = 0; i < this.data.length; ++i) 
	{ 
		if(this.data[i] != null && this.forecast[i] != null) 
		{ 
			SSE += Math.pow(this.data[i] - this.forecast[i], 2);	 
			n++; 
		}  
		 
	} 
	return 1/(n-1)*SSE; 
}; 

I might have tried

-- Calculates the mean squared error  
public function MeanSquaredError(sequence truth, sequence prediction)  
  atom rss = 0.0  
  integer n = 0 
  for i = 1 to length(truth) do  
    if truth[i] !=0 and prediction[i] !=0 then   --assumes that truth and prediction are same lenghts/elements 
          rss += power(truth[i] - prediction[i], 2)  
          n += 1 
    end if 
  end for  
  return 1/(n-1) * rss     --better check that n>1 
end function  

Anyway just a thought.

Chris

new topic     » goto parent     » topic index » view message » categorize

3. Re: Being stupid - need help

thank for your answer Chris. Yes you are correct, the MSE is different, since i think the one supplied is not correct. the MSE has no influence on the calculation of the prediction, but yes, I should augment it with your suggestions.
The prediction results of the functions seem to be correct, but they are slightly off and i can't find out why. That drives me really mad.

Richard

new topic     » goto parent     » topic index » view message » categorize

4. Re: Being stupid - need help

The other things to ask of course, are rounding errors, and which is the correct answer, yours or the .js script.

Chris

new topic     » goto parent     » topic index » view message » categorize

5. Re: Being stupid - need help

read it and weep smile (Seems to pass your tests 100% anyway - changing 0-based indexing to 1-based is a bit of a black art)

-- Calculates the mean squared error  
public function MeanSquaredError(sequence truth, prediction) 
    integer n = length(truth) 
    atom rss = sum(sq_power(sq_sub(truth,prediction[1..n]),2))/(n-1) 
    return rss 
end function 
 
public function HoltWinterspredictMult(sequence data, atom alpha, delta, gamma, integer seasonLength) 
    integer datalen = length(data) 
    sequence {A,B,S} @= repeat(0.0, datalen) 
    atom averageFirstSeason = sum(data[1..seasonLength])/seasonLength 
    B[seasonLength] = averageFirstSeason 
    S[1..seasonLength] = sq_div(data[1..seasonLength],averageFirstSeason) 
    for i=seasonLength+1 to datalen do 
        B[i] = alpha*(data[i]/S[i-seasonLength])+(1-alpha)*(B[i-1]+A[i-1]) 
        A[i] = gamma*(B[i]-B[i-1])+(1-gamma)*A[i-1] 
        S[i] = delta*(data[i]/B[i])+(1-delta)*S[i-seasonLength] 
    end for 
    sequence forecast = repeat(0.0, datalen+seasonLength) 
    for i=seasonLength+1 to datalen do 
        forecast[i] = (A[i-1]+B[i-1])*S[i-seasonLength] 
    end for 
    for i=datalen+1 to datalen+seasonLength do 
        forecast[i] = (B[datalen]+(i-datalen)*A[datalen])*S[i-seasonLength] 
    end for 
    {A,B,S} @= {} 
    atom sse = MeanSquaredError(data, forecast) 
    return {sse, forecast} 
end function 
 
public function HoltWinterspredictAdd(sequence data, atom alpha, delta, gamma, integer seasonLength) 
    integer datalen = length(data) 
    sequence {A,B,S} @= repeat(0.0, datalen) 
    atom averageFirstSeason = sum(data[1..seasonLength])/seasonLength 
    B[seasonLength] = averageFirstSeason 
    S[1..seasonLength] = sq_sub(data[1..seasonLength],averageFirstSeason) 
    for i=seasonLength+1 to datalen do 
        B[i] = alpha*(data[i]-S[i-seasonLength])+(1-alpha)*(B[i-1]+A[i-1]) 
        A[i] = gamma*(B[i]-B[i-1])+(1-gamma)*A[i-1] 
        S[i] = delta*(data[i]-B[i])+(1-delta)*S[i-seasonLength] 
    end for 
    sequence forecast = repeat(0.0, datalen+seasonLength) 
    for i=seasonLength+1 to datalen do 
        forecast[i] = A[i-1]+B[i-1]+S[i-seasonLength] 
    end for 
    for i=datalen+1 to datalen+seasonLength do 
        forecast[i] = B[datalen]+((i-datalen)*A[datalen])+S[i-seasonLength] 
    end for 
    {A,B,S} @= {} 
    atom sse = MeanSquaredError(data, forecast) 
    return {sse, forecast} 
end function 
new topic     » goto parent     » topic index » view message » categorize

6. Re: Being stupid - need help

Ok Pete,

I am weeping T_T.

Thanx for the code, I learned a lot from it - writing phix and not some mixture.

Richard

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu