1. Being stupid - need help
- Posted by begin Apr 26, 2020
- 1136 views
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
2. Re: Being stupid - need help
- Posted by ChrisB (moderator) Apr 27, 2020
- 1072 views
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
3. Re: Being stupid - need help
- Posted by begin Apr 27, 2020
- 1066 views
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
4. Re: Being stupid - need help
- Posted by ChrisB (moderator) Apr 27, 2020
- 1073 views
The other things to ask of course, are rounding errors, and which is the correct answer, yours or the .js script.
Chris
5. Re: Being stupid - need help
- Posted by petelomax Apr 27, 2020
- 1055 views
read it and weep (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
6. Re: Being stupid - need help
- Posted by begin Apr 27, 2020
- 1053 views
Ok Pete,
I am weeping T_T.
Thanx for the code, I learned a lot from it - writing phix and not some mixture.
Richard