Permalink
Browse files

working on integration: MeanSignedDifferenceError

  • Loading branch information...
1 parent 564916a commit c13ee4b5eae7629147fd0c9fd63b799e1e891f0a @T-002 committed Mar 15, 2013
View
12 pycast/errors/__init__.py
@@ -27,19 +27,15 @@
## absolute errors
from meansquarederror import MeanSquaredError, MSE
-
-
-## scaled errors that can be used to compare prediction accuracy on different TimeSeries
from meanabsolutedeviationerror import MeanAbsoluteDeviationError, MAD
+from meansigneddifferenceerror import MeanSignedDifferenceError, MSD
+## scaled errors that can be used to compare prediction accuracy on different TimeSeries
from meanabsolutepercentageerror import MeanAbsolutePercentageError, MAPE, GeometricMeanAbsolutePercentageError, GMAPE, MeanSignedPercentageError, MSPE
from symmetricmeanabsolutepercentageerror import SymmetricMeanAbsolutePercentageError, SMAPE
from medianabsolutepercentageerror import MedianAbsolutePercentageError, MdAPE
from weightedmeanabsolutepercentageerror import WeightedMeanAbsolutePercentageError, WMAPE
+from meanabsolutescalederror import MeanAbsoluteScaledError, MASE
-#from meaneconomicerror import MeanEconomicError, MEE, MeanSignedEconomicError, MSEE
-
-#from meanabsolutescalederror import MeanAbsoluteScaledError, MASE
-
-#from meansigneddifferenceerror import MeanSignedDifferenceError, MSD
+#from meaneconomicerror import MeanEconomicError, MEE, MeanSignedEconomicError, MSEE
View
53 pycast/errors/baseerrormeasure.py
@@ -211,4 +211,55 @@ def local_error(self, originalValue, calculatedValue):
:raise: Raises a :py:exc:`NotImplementedError` if the child class does not overwrite this method.
"""
- raise NotImplementedError
+ raise NotImplementedError
+
+ def confidence_interval(self, confidenceLevel):
+ """Calculates for which value confidenceLevel% of the errors are closer to 0.
+
+ :param float confidenceLevel: percentage of the errors that should be
+ smaller than the returned value for overestimations and larger than
+ the returned value for underestimations.
+ confidenceLevel has to be in [0.0, 1.0]
+
+ :return: return a tuple containing the underestimation and overestimation for
+ the given confidenceLevel
+ :rtype: tuple
+
+ :warning: Index is still not calculated correctly
+ """
+
+ if not (confidenceLevel >= 0 and confidenceLevel <= 1):
+ raise ValueError("Parameter percentage has to be in [0,1]")
+
+ underestimations = []
+ overestimations = []
+ for error in self._errorValues:
+ if error is None:
+ # None was in the lists causing some confidenceLevels not be calculated, not sure if that was intended, I suggested ignoring None values
+ continue
+ #Want 0 errors in both lists!
+ if error >= 0:
+ overestimations.append(error)
+ if error <= 0:
+ underestimations.append(error)
+
+ #sort and cut off at confidence level.
+ overestimations.sort()
+ underestimations.sort(reverse=True)
+
+ overIdx = int(len(overestimations) * confidenceLevel) - 1
+ underIdx = int(len(underestimations) * confidenceLevel) - 1
+
+ overestimation = 0.0
+ underestimation = 0.0
+
+ raise Exception
+ if overIdx >= 0:
+ overestimation = overestimations[overIdx]
+ else:
+ print len(overestimations), confidenceLevel
+
+ if underIdx >= 0:
+ underestimation = underestimations[underIdx]
+
+ return underestimation, overestimation
View
69 pycast/errors/meansigneddifferenceerror.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+#Copyright (c) 2012-2013 Christian Schwarz
+#
+#Permission is hereby granted, free of charge, to any person obtaining
+#a copy of this software and associated documentation files (the
+#"Software"), to deal in the Software without restriction, including
+#without limitation the rights to use, copy, modify, merge, publish,
+#distribute, sublicense, and/or sell copies of the Software, and to
+#permit persons to whom the Software is furnished to do so, subject to
+#the following conditions:
+#
+#The above copyright notice and this permission notice shall be
+#included in all copies or substantial portions of the Software.
+#
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+#EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+#MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+#LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+#OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+#WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+from pycast.errors import BaseErrorMeasure
+
+class MeanSignedDifferenceError(BaseErrorMeasure):
+ """Implements the mean signed difference error measure."""
+
+ def _calculate(self, startingPercentage, endPercentage, startDate, endDate):
+ """This is the error calculation function that gets called by :py:meth:`BaseErrorMeasure.get_error`.
+
+ Both parameters will be correct at this time.
+
+ :param Float startingPercentage: Defines the start of the interval. This has to be a value in [0.0, 100.0].
+ It represents the value, where the error calculation should be started.
+ 25.0 for example means that the first 25% of all calculated errors will be ignored.
+ :param Float endPercentage: Defines the end of the interval. This has to be a value in [0.0, 100.0].
+ It represents the vlaue, after which all error values will be ignored. 90.0 for example means that
+ the last 10% of all local errors will be ignored.
+ :param Float startDate: Epoch representing the start date used for error calculation.
+ :param Float endDate: Epoch representing the end date used in the error calculation.
+
+ :return: Returns a float representing the error.
+ :rtype: Float
+ """
+ ## get the defined subset of error values
+ errorValues = self._get_error_values(startingPercentage, endPercentage, startDate, endDate)
+
+ return sum(errorValues) / float(len(errorValues))
+
+ def local_error(self, originalValue, calculatedValue):
+ """Calculates the error between the two given values.
+
+ :param List originalValue: List containing the values of the original data.
+ :param List calculatedValue: List containing the values of the calculated TimeSeries that
+ corresponds to originalValue.
+
+ :return: Returns the error measure of the two given values.
+ :rtype: Numeric
+ """
+ if type(originalValue) == list:
+ originalValue = originalValue[0]
+ if type(calculatedValue) == list:
+ calculatedValue = calculatedValue[0]
+
+ return originalValue - calculatedValue
+
+MSD = MeanSignedDifferenceError
View
2 pycast/tests/__init__.py
@@ -39,7 +39,7 @@
#from regressiontest import RegressionTest, LinearRegressionTest
## error measure tests
-from errormeasuretest import BaseErrorMeasureTest, MeanSquaredErrorTest, SymmetricMeanAbsolutePercentageErrorTest, MeanAbsoluteDeviationErrorTest, MedianAbsolutePercentageErrorTest#, MeanAbsoluteScaledErrorTest#, MeanSignedDifferenceErrorTest
+from errormeasuretest import BaseErrorMeasureTest, MeanSquaredErrorTest, SymmetricMeanAbsolutePercentageErrorTest, MeanAbsoluteDeviationErrorTest, MedianAbsolutePercentageErrorTest, MeanAbsoluteScaledErrorTest, MeanSignedDifferenceErrorTest
from mapetest import MeanAbsolutePercentageErrorTest, GeometricMeanAbsolutePercentageErrorTest
from weightedmapetest import WeightedMeanAbsolutePercentageErrorTest
#from meetest import MeanEconomicErrorTest
View
351 pycast/tests/errormeasuretest.py
@@ -30,9 +30,9 @@
from pycast.errors import MeanSquaredError
from pycast.errors import SymmetricMeanAbsolutePercentageError
from pycast.errors import MeanAbsoluteDeviationError
-#from pycast.errors import MeanAbsoluteScaledError
+from pycast.errors import MeanAbsoluteScaledError
from pycast.errors import MedianAbsolutePercentageError
-#from pycast.errors import MeanSignedDifferenceError
+from pycast.errors import MeanSignedDifferenceError
from pycast.common.timeseries import TimeSeries
from pycast.common.pycastobject import PyCastObject
@@ -351,175 +351,178 @@ def error_calculation_test(self):
assert em.get_error() == 62.5
assert em.get_error(20.0, 50.0) == 100.0
-#class MeanAbsoluteScaledErrorTest(unittest.TestCase):
-#
-# def initialization_error_test(self):
-# """Test for the exceptions raised during initialization."""
-# MeanAbsoluteScaledError(minimalErrorCalculationPercentage=60.0, historyLength=20.0)
-#
-# try:
-# MeanAbsoluteScaledError(60.0, 0.0)
-# except ValueError:
-# pass
-# else:
-# assert False # pragma: no cover
-#
-# try:
-# MeanAbsoluteScaledError(60.0, -12.0)
-# except ValueError:
-# pass
-# else:
-# assert False # pragma: no cover
-#
-# try:
-# MeanAbsoluteScaledError(60.0, 120.0)
-# except ValueError:
-# pass
-# else:
-# assert False # pragma: no cover
-#
-# try:
-# MeanAbsoluteScaledError(60.0, 60.0)
-# except ValueError:
-# pass
-# else:
-# assert False # pragma: no cover
-#
-# def calculate_historic_means_test(self):
-# """Test the calculation of the historic means."""
-# dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
-# ## 2 2 1 4 3 3 3 3 2 5 5 3 4 1 6 5 4 2 2
-# ## Sum(History) 12 13 14 16 14 16 18 18 19 18 19 19 20 18 19
-# correctResult = [ 2.4, 2.6, 2.8, 3.2, 2.8, 3.2, 3.6, 3.6, 3.8, 3.6, 3.8, 3.8, 4.0, 3.6]
-#
-# tsOrg = TimeSeries.from_twodim_list(dataOrg)
-# mase = MeanAbsoluteScaledError(historyLength=5)
-# result = mase._get_historic_means(tsOrg)
-#
-# assert result == correctResult
-#
-# def local_error_calculation_test(self):
-# """Testing the mean absolute error calculation of the MASE."""
-# dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
-# dataFor = [[1.0, 11], [2.0, 13], [3.0, 14], [4.0, 11], [5.0, 13], [6.0, 18], [7.0, 20], [8.0, 26], [9.0, 21], [10.0, 34], [11.0, 23], [12.0, 23], [13.0, 15], [14.0, 12], [15.0, 14], [16.0, 17], [17.0, 25], [18.0, 22], [19.0, 14], [20.0, 30]]
-#
-# historyLength = 5
-# em = MeanAbsoluteScaledError(historyLength=historyLength)
-#
-# ## A history length of 5 implies that the first 6 values have to be ignored for error calculation
-# historyLength += 1
-# dataOrg = dataOrg[historyLength:]
-# dataFor = dataFor[historyLength:]
-#
-# for orgValue, forValue in zip(dataOrg, dataFor):
-# difference = orgValue[1] - forValue[1]
-# difference = abs(difference)
-#
-# assert difference == em.local_error([orgValue[1]], [forValue[1]])
-#
-# def initialization_test(self):
-# """Test for MASE initialization."""
-# dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
-# dataFor = [[1.0, 11], [2.0, 13], [3.0, 14], [4.0, 11], [5.0, 13], [6.0, 18], [7.0, 20], [8.0, 26], [9.0, 21], [10.0, 34], [11.0, 23], [12.0, 23], [13.0, 15], [14.0, 12], [15.0, 14], [16.0, 17], [17.0, 25], [18.0, 22], [19.0, 14], [20.0, 30]]
-#
-# tsOrg = TimeSeries.from_twodim_list(dataOrg)
-# tsFor = TimeSeries.from_twodim_list(dataFor)
-#
-# em = MeanAbsoluteScaledError(historyLength=5)
-# em.initialize(tsOrg, tsFor)
-#
-# assert len(em._errorValues) == len(em._historicMeans), "For each error value an historic mean has to exsist."
-#
-# try:
-# em.initialize(tsOrg, tsFor)
-# except StandardError:
-# pass
-# else:
-# assert False # pragma: no cover
-#
-# em = MeanAbsoluteScaledError(historyLength=20.0)
-# em.initialize(tsOrg, tsFor)
-#
-# assert len(em._errorValues) == len(em._historicMeans), "For each error value an historic mean has to exsist."
-# assert em._historyLength == 4, "The history is %s entries long. 4 were expected." % em._historyLength
-#
-# em = MeanAbsoluteScaledError(historyLength=40.0)
-# em.initialize(tsOrg, tsFor)
-#
-# assert len(em._errorValues) == len(em._historicMeans), "For each error value an historic mean has to exsist."
-# assert em._historyLength == 8, "The history is %s entries long. 8 were expected." % em._historyLength
-#
-# def error_calculation_test(self):
-# """Testing for the correct MASE calculation.
-#
-# History length is 5 in this test.
-# """
-# dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
-# dataFor = [[1.0, 11], [2.0, 13], [3.0, 14], [4.0, 11], [5.0, 13], [6.0, 18], [7.0, 20], [8.0, 26], [9.0, 21], [10.0, 34], [11.0, 23], [12.0, 23], [13.0, 15], [14.0, 12], [15.0, 14], [16.0, 17], [17.0, 25], [18.0, 22], [19.0, 14], [20.0, 30]]
-# ## 2 2 1 4 3 3 3 3 2 5 5 3 4 1 6 5 4 2 2
-# ## Sum(History) 12 13 14 16 14 16 18 18 19 18 19 19 20 18 19
-# ## Mean(History) ## ## ## ## ## 2.4 2.6 2.8 3.2 2.8 3.2 3.6 3.6 3.8 3.6 3.8 3.8 4.0 3.6 3.8
-# ## AD 3 0 8 3 3 2 3 2 1 2 1 6 16 2
-# ## Sum(AD) 3 3 11 14 17 19 22 24 25 27 28 34 50 52
-# ## MAD 3 1.5 3.666 3.5  3.4 3.166 3.142 3 2.777 2.7 2.545 2.833 3.571 3.714
-# ## MASE (0% - 100%) 1.25 0.625 1.527 1.458 1.416 1.319 1.309 1.25 1.157 1.125 1.06 1.18 1.602 1.547
-#
-# tsOrg = TimeSeries.from_twodim_list(dataOrg)
-# tsFor = TimeSeries.from_twodim_list(dataFor)
-#
-# historyLength = 5
-# em = MeanAbsoluteScaledError(historyLength=historyLength)
-# em.initialize(tsOrg, tsFor)
-#
-# ## check for error calculation depending on a specific endpoint
-# correctResult = [1.25, 0.625, 1.527, 1.458, 1.416, 1.319, 1.309, 1.25, 1.157, 1.125, "1.060", "1.180", 1.602, 1.547]
-# percentage = 100.0 / len(correctResult) + 0.2
-# for errVal in xrange(14):
-# endPercentage = percentage * (errVal + 1)
-#
-# ## set maximum percentage
-# if endPercentage > 100.0:
-# endPercentage = 100.0
-#
-# calcErr = str(em.get_error(endPercentage=endPercentage))[:5]
-# correctRes = str(correctResult[errVal])[:5]
-#
-# assert calcErr == correctRes
-#
-# for errVal in xrange(14):
-# endDate = dataOrg[errVal + 6][0]
-#
-# calcErr = str(em.get_error(endDate=endDate))[:5]
-# correctRes = str(correctResult[errVal])[:5]
-#
-# assert calcErr == correctRes, "%s != %s" % (calcErr, correctRes)
-#
-# em.get_error(startDate=7.0)
-#
-# try:
-# em.get_error(startDate=42.23)
-# except ValueError:
-# pass
-# else:
-# assert False # pragma: no cover
-#
-#class MeanSignedDifferenceErrorTest(unittest.TestCase):
-# def setUp(self):
-# self.ts1 = TimeSeries.from_twodim_list([[1,1],[2,20],[3,3]])
-# self.ts2 = TimeSeries.from_twodim_list([[1,10],[2,2],[3,30]])
-# self.msd = MeanSignedDifferenceError()
-# self.msd.initialize(self.ts1, self.ts2)
-#
-# def local_error_test(self):
-# self.assertEquals(-10, self.msd.local_error(10, 20))
-# self.assertEquals(10, self.msd.local_error(20, 10))
-#
-# def error_calculation_test(self):
-# self.assertEquals(self.msd.get_error(), -6)
-#
-# def confidence_interval_test(self):
-# with self.assertRaises(ValueError) as _:
-# self.msd.confidence_interval(2)
-# self.assertEquals((-9, 18), self.msd.confidence_interval(.5))
-#
-#
+class MeanAbsoluteScaledErrorTest(unittest.TestCase):
+
+ def initialization_error_test(self):
+ """Test for the exceptions raised during initialization."""
+ MeanAbsoluteScaledError(minimalErrorCalculationPercentage=60.0, historyLength=20.0)
+
+ try:
+ MeanAbsoluteScaledError(60.0, 0.0)
+ except ValueError:
+ pass
+ else:
+ assert False # pragma: no cover
+
+ try:
+ MeanAbsoluteScaledError(60.0, -12.0)
+ except ValueError:
+ pass
+ else:
+ assert False # pragma: no cover
+
+ try:
+ MeanAbsoluteScaledError(60.0, 120.0)
+ except ValueError:
+ pass
+ else:
+ assert False # pragma: no cover
+
+ try:
+ MeanAbsoluteScaledError(60.0, 60.0)
+ except ValueError:
+ pass
+ else:
+ assert False # pragma: no cover
+
+ def calculate_historic_means_test(self):
+ """Test the calculation of the historic means."""
+ dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
+ ## 2 2 1 4 3 3 3 3 2 5 5 3 4 1 6 5 4 2 2
+ ## Sum(History) 12 13 14 16 14 16 18 18 19 18 19 19 20 18 19
+ correctResult = [ 2.4, 2.6, 2.8, 3.2, 2.8, 3.2, 3.6, 3.6, 3.8, 3.6, 3.8, 3.8, 4.0, 3.6]
+
+ tsOrg = TimeSeries.from_twodim_list(dataOrg)
+ mase = MeanAbsoluteScaledError(historyLength=5)
+ result = mase._get_historic_means(tsOrg)
+
+ assert result == correctResult
+
+ def local_error_calculation_test(self):
+ """Testing the mean absolute error calculation of the MASE."""
+ dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
+ dataFor = [[1.0, 11], [2.0, 13], [3.0, 14], [4.0, 11], [5.0, 13], [6.0, 18], [7.0, 20], [8.0, 26], [9.0, 21], [10.0, 34], [11.0, 23], [12.0, 23], [13.0, 15], [14.0, 12], [15.0, 14], [16.0, 17], [17.0, 25], [18.0, 22], [19.0, 14], [20.0, 30]]
+
+ historyLength = 5
+ em = MeanAbsoluteScaledError(historyLength=historyLength)
+
+ ## A history length of 5 implies that the first 6 values have to be ignored for error calculation
+ historyLength += 1
+ dataOrg = dataOrg[historyLength:]
+ dataFor = dataFor[historyLength:]
+
+ for orgValue, forValue in zip(dataOrg, dataFor):
+ difference = orgValue[1] - forValue[1]
+ difference = abs(difference)
+
+ assert difference == em.local_error([orgValue[1]], [forValue[1]])
+
+ def initialization_test(self):
+ """Test for MASE initialization."""
+ dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
+ dataFor = [[1.0, 11], [2.0, 13], [3.0, 14], [4.0, 11], [5.0, 13], [6.0, 18], [7.0, 20], [8.0, 26], [9.0, 21], [10.0, 34], [11.0, 23], [12.0, 23], [13.0, 15], [14.0, 12], [15.0, 14], [16.0, 17], [17.0, 25], [18.0, 22], [19.0, 14], [20.0, 30]]
+
+ tsOrg = TimeSeries.from_twodim_list(dataOrg)
+ tsFor = TimeSeries.from_twodim_list(dataFor)
+
+ em = MeanAbsoluteScaledError(historyLength=5)
+ em.initialize(tsOrg, tsFor)
+
+ assert len(em._errorValues) == len(em._historicMeans), "For each error value an historic mean has to exsist."
+
+ try:
+ em.initialize(tsOrg, tsFor)
+ except StandardError:
+ pass
+ else:
+ assert False # pragma: no cover
+
+ em = MeanAbsoluteScaledError(historyLength=20.0)
+ em.initialize(tsOrg, tsFor)
+
+ assert len(em._errorValues) == len(em._historicMeans), "For each error value an historic mean has to exsist."
+ assert em._historyLength == 4, "The history is %s entries long. 4 were expected." % em._historyLength
+
+ em = MeanAbsoluteScaledError(historyLength=40.0)
+ em.initialize(tsOrg, tsFor)
+
+ assert len(em._errorValues) == len(em._historicMeans), "For each error value an historic mean has to exsist."
+ assert em._historyLength == 8, "The history is %s entries long. 8 were expected." % em._historyLength
+
+ def error_calculation_test(self):
+ """Testing for the correct MASE calculation.
+
+ History length is 5 in this test.
+ """
+ dataOrg = [[1.0, 10], [2.0, 12], [3.0, 14], [4.0, 13], [5.0, 17], [6.0, 20], [7.0, 23], [8.0, 26], [9.0, 29], [10.0, 31], [11.0, 26], [12.0, 21], [13.0, 18], [14.0, 14], [15.0, 13], [16.0, 19], [17.0, 24], [18.0, 28], [19.0, 30], [20.0, 32]]
+ dataFor = [[1.0, 11], [2.0, 13], [3.0, 14], [4.0, 11], [5.0, 13], [6.0, 18], [7.0, 20], [8.0, 26], [9.0, 21], [10.0, 34], [11.0, 23], [12.0, 23], [13.0, 15], [14.0, 12], [15.0, 14], [16.0, 17], [17.0, 25], [18.0, 22], [19.0, 14], [20.0, 30]]
+ ## 2 2 1 4 3 3 3 3 2 5 5 3 4 1 6 5 4 2 2
+ ## Sum(History) 12 13 14 16 14 16 18 18 19 18 19 19 20 18 19
+ ## Mean(History) ## ## ## ## ## 2.4 2.6 2.8 3.2 2.8 3.2 3.6 3.6 3.8 3.6 3.8 3.8 4.0 3.6 3.8
+ ## AD 3 0 8 3 3 2 3 2 1 2 1 6 16 2
+ ## Sum(AD) 3 3 11 14 17 19 22 24 25 27 28 34 50 52
+ ## MAD 3 1.5 3.666 3.5  3.4 3.166 3.142 3 2.777 2.7 2.545 2.833 3.571 3.714
+ ## MASE (0% - 100%) 1.25 0.625 1.527 1.458 1.416 1.319 1.309 1.25 1.157 1.125 1.06 1.18 1.602 1.547
+
+ tsOrg = TimeSeries.from_twodim_list(dataOrg)
+ tsFor = TimeSeries.from_twodim_list(dataFor)
+
+ historyLength = 5
+ em = MeanAbsoluteScaledError(historyLength=historyLength)
+ em.initialize(tsOrg, tsFor)
+
+ ## check for error calculation depending on a specific endpoint
+ correctResult = [1.25, 0.625, 1.527, 1.458, 1.416, 1.319, 1.309, 1.25, 1.157, 1.125, "1.060", "1.180", 1.602, 1.547]
+ percentage = 100.0 / len(correctResult) + 0.2
+ for errVal in xrange(14):
+ endPercentage = percentage * (errVal + 1)
+
+ ## set maximum percentage
+ if endPercentage > 100.0:
+ endPercentage = 100.0
+
+ calcErr = str(em.get_error(endPercentage=endPercentage))[:5]
+ correctRes = str(correctResult[errVal])[:5]
+
+ assert calcErr == correctRes
+
+ for errVal in xrange(14):
+ endDate = dataOrg[errVal + 6][0]
+
+ calcErr = str(em.get_error(endDate=endDate))[:5]
+ correctRes = str(correctResult[errVal])[:5]
+
+ assert calcErr == correctRes, "%s != %s" % (calcErr, correctRes)
+
+ em.get_error(startDate=7.0)
+
+ try:
+ em.get_error(startDate=42.23)
+ except ValueError:
+ pass
+ else:
+ assert False # pragma: no cover
+
+class MeanSignedDifferenceErrorTest(unittest.TestCase):
+ def setUp(self):
+ self.ts1 = TimeSeries.from_twodim_list([[1.0, 1.0], [2.0,20.0], [3.0, 3.0]])
+ self.ts2 = TimeSeries.from_twodim_list([[1.0,10.0], [2.0, 2.0], [3.0,30.0]])
+ self.msd = MeanSignedDifferenceError()
+ self.msd.initialize(self.ts1, self.ts2)
+
+ def local_error_test(self):
+ assert -10.0 == self.msd.local_error(10.0, 20.0)
+ assert 10.0 == self.msd.local_error(20.0, 10.0)
+
+ def error_calculation_test(self):
+ assert -6.0 == self.msd.get_error()
+
+ def confidence_interval_test(self):
+ try:
+ self.msd.confidence_interval(2)
+ except ValueError:
+ pass
+ else:
+ assert False, "ValueError not raised." # pragma: no cover
+
+ assert (-9.0, 18.0) == self.msd.confidence_interval(.5)

0 comments on commit c13ee4b

Please sign in to comment.