From ebf0e70d84ee7e9081a44640fd2a7ef4003e1bce Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Fri, 14 Apr 2017 12:42:12 -0700 Subject: [PATCH 01/14] Partial encoder docs --- docs/README.md | 6 +- docs/source/api/algorithms/encoders.rst | 12 ++- src/nupic/encoders/adaptivescalar.py | 8 +- src/nupic/encoders/base.py | 30 ++++---- src/nupic/encoders/date.py | 71 +++++++++-------- .../encoders/random_distributed_scalar.py | 77 ++++++++++--------- 6 files changed, 110 insertions(+), 94 deletions(-) diff --git a/docs/README.md b/docs/README.md index 43368978dc..9352a17014 100644 --- a/docs/README.md +++ b/docs/README.md @@ -67,17 +67,17 @@ nupic │   │   ├── secondOrder │   │   │   └── makeDataset.py [TODO] ├── encoders -│   ├── adaptivescalar.py [TODO] +│   ├── adaptivescalar.py [OK] │   ├── base.py [TODO] │   ├── category.py [TODO] │   ├── coordinate.py [TODO] -│   ├── date.py [TODO] +│   ├── date.py [OK] │   ├── delta.py [TODO] │   ├── geospatial_coordinate.py [TODO] │   ├── logenc.py [TODO] │   ├── multi.py [TODO] │   ├── pass_through_encoder.py [TODO] -│   ├── random_distributed_scalar.py [TODO] +│   ├── random_distributed_scalar.py [OK] │   ├── scalar.py [TODO] │   ├── scalarspace.py [TODO] │   ├── sdrcategory.py [TODO] diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index 7b5aa88553..bbb0899119 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -11,21 +11,27 @@ Scalar Encoder ^^^^^^^^^^^^^^ .. autoclass:: nupic.encoders.scalar.ScalarEncoder - :members: :show-inheritance: +Adaptive Scalar Encoder +^^^^^^^^^^^^^^^^^^^^^^^ + +.. autoclass:: nupic.encoders.adaptivescalar.AdaptiveScalarEncoder + :show-inheritance: + + Random Distributed Scalar Encoder ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: nupic.encoders.random_distributed_scalar.RandomDistributedScalarEncoder - :members: + :members: mapBucketIndexToNonZeroBits :show-inheritance: DateEncoder ^^^^^^^^^^^ .. autoclass:: nupic.encoders.date.DateEncoder - :members: + :members: getScalars :show-inheritance: CoordinateEncoder diff --git a/src/nupic/encoders/adaptivescalar.py b/src/nupic/encoders/adaptivescalar.py index 6f8f70fb55..c4cc102b5b 100644 --- a/src/nupic/encoders/adaptivescalar.py +++ b/src/nupic/encoders/adaptivescalar.py @@ -47,14 +47,16 @@ class AdaptiveScalarEncoder(ScalarEncoder): **Note:** the sliding window may record duplicates of the values in the dataset, and therefore does not reflect the statistical distribution of the input data and may not be used to calculate the median, mean etc. + + For params, see :class:`~.nupic.encoders.scalar.ScalarEncoder`. + + :raises: Exception if input is periodic. + """ def __init__(self, w, minval=None, maxval=None, periodic=False, n=0, radius=0, resolution=0, name=None, verbosity=0, clipInput=True, forced=False): - """ - [overrides nupic.encoders.scalar.ScalarEncoder.__init__] - """ self._learningEnabled = True if periodic: #Adaptive scalar encoders take non-periodic inputs only diff --git a/src/nupic/encoders/base.py b/src/nupic/encoders/base.py index cc0813a2a4..36536bf6bf 100644 --- a/src/nupic/encoders/base.py +++ b/src/nupic/encoders/base.py @@ -50,7 +50,8 @@ def _isSequence(obj): class Encoder(object): - """An encoder converts a value to a sparse distributed representation. + """ + An encoder converts a value to a sparse distributed representation. This is the base class for encoders that are compatible with the OPF. The OPF requires that values can be represented as a scalar value for use in places @@ -93,12 +94,13 @@ def getWidth(self): def encodeIntoArray(self, inputData, output): """ Encodes inputData and puts the encoded value into the numpy output array, - which is a 1-D array of length returned by getWidth(). + which is a 1-D array of length returned by :meth:`~.getWidth`. Note: The numpy output array is reused, so clear it before updating it. :param inputData: Data to encode. This should be validated by the encoder. - :param output: numpy 1-D array of same length returned by getWidth() + :param output: numpy 1-D array of same length returned by + :meth:`~.getWidth`. """ raise NotImplementedError() @@ -106,7 +108,7 @@ def encodeIntoArray(self, inputData, output): def setLearning(self, learningEnabled): """Set whether learning is enabled. - :param learningEnabled: whether learning should be enabled + :param learningEnabled: (bool) whether learning should be enabled """ # TODO: (#1943) Make sure subclasses don't rely on this and remove it. # Default behavior should be a noop. @@ -120,7 +122,7 @@ def setFieldStats(self, fieldName, fieldStatistics): max for the underlying encoders if this information is available. :param fieldName: name of the field this encoder is encoding, provided by - multiencoder + :class:`~.nupic.encoders.multi.MultiEncoder`. :param fieldStatistics: dictionary of dictionaries with the first level being the fieldname and the second index the statistic ie: @@ -130,12 +132,12 @@ def setFieldStats(self, fieldName, fieldStatistics): def encode(self, inputData): - """Convenience wrapper for encodeIntoArray. + """Convenience wrapper for :meth:`.encodeIntoArray`. This may be less efficient because it allocates a new numpy array every call. - :param inputData: undocumented + :param inputData: input data to be encoded :return: a numpy array with the encoded representation of inputData """ output = numpy.zeros((self.getWidth(),), dtype=defaultDtype) @@ -255,7 +257,7 @@ def getScalars(self, inputData): """ Returns a numpy array containing the sub-field scalar value(s) for each sub-field of the inputData. To get the associated field names for each of - the scalar values, call getScalarNames(). + the scalar values, call :meth:`~.getScalarNames()`. For a simple scalar encoder, the scalar value is simply the input unmodified. For category encoders, it is the scalar representing the category string @@ -264,7 +266,7 @@ def getScalars(self, inputData): The intent of the scalar representation of a sub-field is to provide a baseline for measuring error differences. You can compare the scalar value - of the inputData with the scalar value returned from topDownCompute() on a + of the inputData with the scalar value returned from :meth:`.topDownCompute` on a top-down representation to evaluate prediction accuracy, for example. :param inputData: The data from the source. This is typically a object with @@ -286,7 +288,7 @@ def getScalars(self, inputData): def getEncodedValues(self, inputData): """ - Returns the input in the same format as is returned by topDownCompute(). + Returns the input in the same format as is returned by :meth:`.topDownCompute`. For most encoder types, this is the same as the input data. For instance, for scalar and category types, this corresponds to the numeric and string values, respectively, from the inputs. For datetime encoders, this @@ -298,7 +300,7 @@ def getEncodedValues(self, inputData): :param inputData: The input data in the format it is received from the data source :return: A list of values, in the same format and in the same order as they - are returned by topDownCompute. + are returned by :meth:`.topDownCompute`. """ retVals = [] @@ -494,7 +496,7 @@ def decode(self, encoded, parentFieldName=''): in many cases might be a union of one or more inputs. If instead, you want to figure the *most likely* single input scalar value - that would have generated a specific encoded output, use the topDownCompute() + that would have generated a specific encoded output, use the :meth:`.topDownCompute` method. If you want to pretty print the return value from this method, use the @@ -727,7 +729,7 @@ def closenessScores(self, expValues, actValues, fractional=True): Compute closeness scores between the expected scalar value(s) and actual scalar value(s). The expected scalar values are typically those obtained from the getScalars() method. The actual scalar values are typically those - returned from the topDownCompute() method. + returned from :meth:`.topDownCompute`. This method returns one closeness score for each value in expValues (or actValues which must be the same length). The closeness score ranges from @@ -744,7 +746,7 @@ def closenessScores(self, expValues, actValues, fractional=True): :param expValues: Array of expected scalar values, typically obtained from getScalars() :param actValues: Array of actual values, typically obtained from - topDownCompute() + :meth:`.topDownCompute` :return: Array of closeness scores, one per item in expValues (or actValues). diff --git a/src/nupic/encoders/date.py b/src/nupic/encoders/date.py index 9ba3a60948..90d1118dc3 100644 --- a/src/nupic/encoders/date.py +++ b/src/nupic/encoders/date.py @@ -30,38 +30,47 @@ class DateEncoder(Encoder): - """A date encoder encodes a date according to encoding parameters - specified in its constructor. - The input to a date encoder is a datetime.datetime object. The output - is the concatenation of several sub-encodings, each of which encodes - a different aspect of the date. Which sub-encodings are present, and - details of those sub-encodings, are specified in the DateEncoder - constructor. + """ + A date encoder encodes a date according to encoding parameters specified in + its constructor. The input to a date encoder is a datetime.datetime object. + The output is the concatenation of several sub-encodings, each of which + encodes a different aspect of the date. Which sub-encodings are present, and + details of those sub-encodings, are specified in the DateEncoder constructor. Each parameter describes one attribute to encode. By default, the attribute is not encoded. - season (season of the year; units = day): - (int) width of attribute; default radius = 91.5 days (1 season) - (tuple) season[0] = width; season[1] = radius + :param season: (int | tuple) Season of the year, where units = day. + + - (int) width of attribute; default radius = 91.5 days (1 season) + - (tuple) season[0] = width; season[1] = radius + + :param dayOfWeek: (int | tuple) Day of week, where monday = 0, units = 1 day. + + - (int) width of attribute; default radius = 1 day + - (tuple) dayOfWeek[0] = width; dayOfWeek[1] = radius + + :param weekend: (int) Is a weekend or not. A block of bits either 0s or 1s. - dayOfWeek (monday = 0; units = day) - (int) width of attribute; default radius = 1 day - (tuple) dayOfWeek[0] = width; dayOfWeek[1] = radius + - (int) width of attribute - weekend (boolean: 0, 1) - (int) width of attribute + :param holiday: (int) Is a holiday or not, boolean: 0, 1 - holiday (boolean: 0, 1) - (int) width of attribute + - (int) width of attribute - timeOfday (midnight = 0; units = hour) - (int) width of attribute: default radius = 4 hours - (tuple) timeOfDay[0] = width; timeOfDay[1] = radius + :param timeOfday: (int | tuple) Time of day, where midnight = 0, units = hour. - customDays TODO: what is it? + - (int) width of attribute: default radius = 4 hours + - (tuple) timeOfDay[0] = width; timeOfDay[1] = radius - forced (default True) : if True, skip checks for parameters' settings; see encoders/scalar.py for details + :param customDays: (tuple) A way to custom encode specific days of the week. + + - [0] (int) Width of attribute + - [1] (str | list) Either a string representing a day of the week like + "Monday" or "mon", or a list of these strings. + + :param forced: (default True) if True, skip checks for parameters' settings. + See :class:`~.nupic.encoders.scalar.ScalarEncoder` for details. """ @@ -320,19 +329,15 @@ def getEncodedValues(self, input): def getScalars(self, input): - """ See method description in base.py - - Parameters: - ----------------------------------------------------------------------- - input: A datetime object representing the time being encoded - - Returns: A numpy array of the corresponding scalar values in - the following order: + """ + See method description in :meth:`~.nupic.encoders.base.Encoder.getScalars`. - [season, dayOfWeek, weekend, holiday, timeOfDay] + :param input: (datetime) representing the time being encoded - Note: some of these fields might be omitted if they were not - specified in the encoder + :returns: A numpy array of the corresponding scalar values in the following + order: season, dayOfWeek, weekend, holiday, timeOfDay. Some of + these fields might be omitted if they were not specified in the + encoder. """ return numpy.array(self.getEncodedValues(input)) diff --git a/src/nupic/encoders/random_distributed_scalar.py b/src/nupic/encoders/random_distributed_scalar.py index 334b9fb0e5..af9f5b1932 100644 --- a/src/nupic/encoders/random_distributed_scalar.py +++ b/src/nupic/encoders/random_distributed_scalar.py @@ -65,6 +65,8 @@ class RandomDistributedScalarEncoder(Encoder): Properties 1 and 2 lead to the following overlap rules for buckets i and j: + .. code-block:: python + If abs(i-j) < w then: overlap(i,j) = w - abs(i-j) else: @@ -74,48 +76,47 @@ class RandomDistributedScalarEncoder(Encoder): the object. Specifically, as new buckets are created and the min/max range is extended, the representation for previously in-range sscalars and previously created buckets must not change. + + :param resolution: A floating point positive number denoting the resolution + of the output representation. Numbers within + [offset-resolution/2, offset+resolution/2] will fall into + the same bucket and thus have an identical representation. + Adjacent buckets will differ in one bit. resolution is a + required parameter. + + :param w: Number of bits to set in output. w must be odd to avoid centering + problems. w must be large enough that spatial pooler + columns will have a sufficiently large overlap to avoid + false matches. A value of w=21 is typical. + + :param n: Number of bits in the representation (must be > w). n must be + large enough such that there is enough room to select + new representations as the range grows. With w=21 a value + of n=400 is typical. The class enforces n > 6*w. + + :param name: An optional string which will become part of the description. + + :param offset: A floating point offset used to map scalar inputs to bucket + indices. The middle bucket will correspond to numbers in the + range [offset - resolution/2, offset + resolution/2). If set + to None, the very first input that is encoded will be used + to determine the offset. + + :param seed: The seed used for numpy's random number generator. If set to -1 + the generator will be initialized without a fixed seed. + + :param verbosity: An integer controlling the level of debugging output. A + value of 0 implies no output. verbosity=1 may lead to + one-time printouts during construction, serialization or + deserialization. verbosity=2 may lead to some output per + encode operation. verbosity>2 may lead to significantly + more output. + """ def __init__(self, resolution, w=21, n=400, name=None, offset=None, seed=42, verbosity=0): - """Constructor - - @param resolution A floating point positive number denoting the resolution - of the output representation. Numbers within - [offset-resolution/2, offset+resolution/2] will fall into - the same bucket and thus have an identical representation. - Adjacent buckets will differ in one bit. resolution is a - required parameter. - - @param w Number of bits to set in output. w must be odd to avoid centering - problems. w must be large enough that spatial pooler - columns will have a sufficiently large overlap to avoid - false matches. A value of w=21 is typical. - - @param n Number of bits in the representation (must be > w). n must be - large enough such that there is enough room to select - new representations as the range grows. With w=21 a value - of n=400 is typical. The class enforces n > 6*w. - - @param name An optional string which will become part of the description. - - @param offset A floating point offset used to map scalar inputs to bucket - indices. The middle bucket will correspond to numbers in the - range [offset - resolution/2, offset + resolution/2). If set - to None, the very first input that is encoded will be used - to determine the offset. - - @param seed The seed used for numpy's random number generator. If set to -1 - the generator will be initialized without a fixed seed. - - @param verbosity An integer controlling the level of debugging output. A - value of 0 implies no output. verbosity=1 may lead to - one-time printouts during construction, serialization or - deserialization. verbosity=2 may lead to some output per - encode operation. verbosity>2 may lead to significantly - more output. - """ # Validate inputs if (w <= 0) or (w%2 == 0): raise ValueError("w must be an odd positive integer") @@ -218,7 +219,7 @@ def mapBucketIndexToNonZeroBits(self, index): index does not exist, it is created. If the index falls outside our range we clip it. - @param index The bucket index to get non-zero bits for. + :param index The bucket index to get non-zero bits for. @returns numpy array of indices of non-zero bits for specified index. """ if index < 0: From d484db586744a6a5821cfe2d414177b3ac49ebd6 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 10:51:18 -0700 Subject: [PATCH 02/14] Fixed wronge module name in docs --- docs/source/api/data/field-meta.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/api/data/field-meta.rst b/docs/source/api/data/field-meta.rst index be3f697f85..4a278284db 100644 --- a/docs/source/api/data/field-meta.rst +++ b/docs/source/api/data/field-meta.rst @@ -1,13 +1,13 @@ Field Meta ^^^^^^^^^^ -.. automodule:: nupic.data.fieldmeta +.. automodule:: nupic.data.field_meta -.. autoclass:: nupic.data.fieldmeta.FieldMetaInfo +.. autoclass:: nupic.data.field_meta.FieldMetaInfo :members: -.. autoclass:: nupic.data.fieldmeta.FieldMetaType +.. autoclass:: nupic.data.field_meta.FieldMetaType :members: -.. autoclass:: nupic.data.fieldmeta.FieldMetaSpecial +.. autoclass:: nupic.data.field_meta.FieldMetaSpecial :members: From 59b1e59724ab838db7083d42abf7db51699b21e1 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 10:51:40 -0700 Subject: [PATCH 03/14] Added EncoderResult docs and Encoder module --- docs/source/api/algorithms/encoders.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index bbb0899119..e67589b5ef 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -1,12 +1,19 @@ Encoders -------- -Encoder -^^^^^^^ +.. automodule:: nupic.encoders.base + +Base Encoder +^^^^^^^^^^^^ .. autoclass:: nupic.encoders.base.Encoder :members: +Encoder Result +^^^^^^^^^^^^^^ + +.. autoclass:: nupic.encoders.base.EncoderResult + Scalar Encoder ^^^^^^^^^^^^^^ From 15f1a5f2411abde1b776e4ee45a854fec3b2efda Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 10:52:09 -0700 Subject: [PATCH 04/14] Full rst docstrings for Encoder --- src/nupic/encoders/base.py | 266 ++++++++++++++++++------------------- 1 file changed, 127 insertions(+), 139 deletions(-) diff --git a/src/nupic/encoders/base.py b/src/nupic/encoders/base.py index 36536bf6bf..2420bb5a16 100644 --- a/src/nupic/encoders/base.py +++ b/src/nupic/encoders/base.py @@ -30,16 +30,31 @@ defaultDtype = numpy.uint8 - -# Tuple to represent the results of computations in different forms. -# value: A representation of the encoded value in the same format as the input -# (i.e. float for scalars, string for categories) -# scalar: A representation of the encoded value as a number. All encoded values -# are represented as some form of numeric value before being encoded -# (e.g. for categories, this is the internal index used by the encoder) -# encoding: The bit-string representation of the value EncoderResult = namedtuple("EncoderResult", ['value', 'scalar', 'encoding']) +""" Tuple to represent the results of computations in different forms. + +.. py:attribute:: value + + A representation of the encoded value in the same format as the input + (i.e. float for scalars, string for categories). This is the value for + the sub-field in a format that is consistent with the type specified by + :meth:`.getDecoderOutputFieldTypes`. Note that this value is not + necessarily numeric. + +.. py:attribute:: scalar + + The scalar representation of value (e.g. for categories, this is the + internal index used by the encoder). This number is consistent with what + is returned by :meth:`.getScalars`. This value is always an int or + float, and can be used for numeric comparisons. + +.. py:attribute:: encoding + This is the encoded bit-array (numpy array) that represents ``value``. + That is, if ``value`` was passed to :meth:`.encode`, an identical + bit-array should be returned. + +""" def _isSequence(obj): @@ -71,8 +86,8 @@ class Encoder(object): subclasses: - :func:`~nupic.encoders.base.Encoder.getDecoderOutputFieldTypes` - must be - implemented by leaf encoders. Returns :class:`nupic.data.fieldmeta.FieldMetaType`.XXXXX - (e.g., :class:`nupic.data.fieldmeta.FieldMetaType`.float) + implemented by leaf encoders. Returns :class:`~nupic.data.field_meta.FieldMetaType`.XXXXX + (e.g., :class:`~nupic.data.field_meta.FieldMetaType`.float) - :func:`~nupic.encoders.base.Encoder.getWidth` - returns the output width, in bits - :func:`~nupic.encoders.base.Encoder.encodeIntoArray` - encodes input and @@ -86,7 +101,7 @@ class Encoder(object): def getWidth(self): """Should return the output width, in bits. - :return: output width in bits + :return: (int) output width in bits """ raise NotImplementedError() @@ -94,13 +109,13 @@ def getWidth(self): def encodeIntoArray(self, inputData, output): """ Encodes inputData and puts the encoded value into the numpy output array, - which is a 1-D array of length returned by :meth:`~.getWidth`. + which is a 1-D array of length returned by :meth:`.getWidth`. Note: The numpy output array is reused, so clear it before updating it. :param inputData: Data to encode. This should be validated by the encoder. :param output: numpy 1-D array of same length returned by - :meth:`~.getWidth`. + :meth:`.getWidth`. """ raise NotImplementedError() @@ -126,7 +141,7 @@ def setFieldStats(self, fieldName, fieldStatistics): :param fieldStatistics: dictionary of dictionaries with the first level being the fieldname and the second index the statistic ie: - fieldStatistics['pounds']['min'] + ``fieldStatistics['pounds']['min']`` """ pass @@ -177,9 +192,9 @@ def getDecoderOutputFieldTypes(self): """ Returns a sequence of field types corresponding to the elements in the decoded output field array. The types are defined by - :class:`nupic.data.fieldmeta.FieldMetaType`. + :class:`~nupic.data.field_meta.FieldMetaType`. - :return: list of :class:`nupic.data.fieldmeta.FieldMetaType` objects + :return: list of :class:`~nupic.data.field_meta.FieldMetaType` objects """ if hasattr(self, '_flattenedFieldTypeList') and \ self._flattenedFieldTypeList is not None: @@ -188,7 +203,7 @@ def getDecoderOutputFieldTypes(self): fieldTypes = [] # NOTE: we take care of the composites, but leaf encoders must override - # this method and return a list of one fieldmeta.FieldMetaType.XXXX + # this method and return a list of one field_meta.FieldMetaType.XXXX # element corresponding to the encoder's decoder output field type for (name, encoder, offset) in self.encoders: subTypes = encoder.getDecoderOutputFieldTypes() @@ -231,8 +246,8 @@ def _getInputValue(self, obj, fieldName): def getEncoderList(self): """ :return: a reference to each sub-encoder in this encoder. They are - returned in the same order as they are for getScalarNames() and - getScalars(). + returned in the same order as they are for :meth:`.getScalarNames` + and :meth:`.getScalars`. """ if hasattr(self, '_flattenedEncoderList') and \ @@ -256,8 +271,8 @@ def getEncoderList(self): def getScalars(self, inputData): """ Returns a numpy array containing the sub-field scalar value(s) for - each sub-field of the inputData. To get the associated field names for each of - the scalar values, call :meth:`~.getScalarNames()`. + each sub-field of the ``inputData``. To get the associated field names for + each of the scalar values, call :meth:`.getScalarNames()`. For a simple scalar encoder, the scalar value is simply the input unmodified. For category encoders, it is the scalar representing the category string @@ -266,8 +281,8 @@ def getScalars(self, inputData): The intent of the scalar representation of a sub-field is to provide a baseline for measuring error differences. You can compare the scalar value - of the inputData with the scalar value returned from :meth:`.topDownCompute` on a - top-down representation to evaluate prediction accuracy, for example. + of the inputData with the scalar value returned from :meth:`.topDownCompute` + on a top-down representation to evaluate prediction accuracy, for example. :param inputData: The data from the source. This is typically a object with members @@ -288,19 +303,21 @@ def getScalars(self, inputData): def getEncodedValues(self, inputData): """ - Returns the input in the same format as is returned by :meth:`.topDownCompute`. - For most encoder types, this is the same as the input data. - For instance, for scalar and category types, this corresponds to the numeric - and string values, respectively, from the inputs. For datetime encoders, this - returns the list of scalars for each of the sub-fields (timeOfDay, dayOfWeek, etc.) + Returns the input in the same format as is returned by + :meth:`.topDownCompute`. For most encoder types, this is the same as the + input data. For instance, for scalar and category types, this corresponds to + the numeric and string values, respectively, from the inputs. For datetime + encoders, this returns the list of scalars for each of the sub-fields + (timeOfDay, dayOfWeek, etc.) - This method is essentially the same as getScalars() except that it returns - strings + This method is essentially the same as :meth:`.getScalars` except that it + returns strings. - :param inputData: The input data in the format it is received from the data source + :param inputData: The input data in the format it is received from the data + source :return: A list of values, in the same format and in the same order as they - are returned by :meth:`.topDownCompute`. + are returned by :meth:`.topDownCompute`. """ retVals = [] @@ -324,9 +341,9 @@ def getEncodedValues(self, inputData): def getBucketIndices(self, inputData): """ - Returns an array containing the sub-field bucket indices for - each sub-field of the inputData. To get the associated field names for each of - the buckets, call getScalarNames(). + Returns an array containing the sub-field bucket indices for each sub-field + of the inputData. To get the associated field names for each of the buckets, + call :meth:`.getScalarNames`. :param inputData: The data from the source. This is typically a object with members. @@ -349,11 +366,11 @@ def getBucketIndices(self, inputData): def scalarsToStr(self, scalarValues, scalarNames=None): """ Return a pretty print string representing the return values from - getScalars and getScalarNames(). + :meth:`.getScalars` and :meth:`.getScalarNames`. :param scalarValues: input values to encode to string :param scalarNames: optional input of scalar names to convert. If None, gets - scalar names from getScalarNames() + scalar names from :meth:`.getScalarNames` :return: string representation of scalar values """ @@ -372,15 +389,15 @@ def scalarsToStr(self, scalarValues, scalarNames=None): def getDescription(self): """ - This returns a list of tuples, each containing (name, offset). - The 'name' is a string description of each sub-field, and offset is the bit - offset of the sub-field for that encoder. + **Must be overridden by subclasses.** + + This returns a list of tuples, each containing (``name``, ``offset``). + The ``name`` is a string description of each sub-field, and ``offset`` is + the bit offset of the sub-field for that encoder. For now, only the 'multi' and 'date' encoders have multiple (name, offset) pairs. All other encoders have a single pair, where the offset is 0. - **Must be overridden by subclasses.** - :return: list of tuples containing (name, offset) """ raise Exception("getDescription must be implemented by all subclasses") @@ -390,8 +407,8 @@ def getFieldDescription(self, fieldName): """ Return the offset and length of a given field within the encoded output. - :param fieldName: Name of the field - :return: tuple(offset, width) of the field within the encoded output + :param fieldName: Name of the field + :return: tuple(``offset``, ``width``) of the field within the encoded output """ # Find which field it's in @@ -416,7 +433,7 @@ def encodedBitDescription(self, bitOffset, formatted=False): :param bitOffset: Offset of the bit to get the description of :param formatted: If True, the bitOffset is w.r.t. formatted output, which includes separators - :return: tuple(fieldName, offsetWithinField) + :return: tuple(``fieldName``, ``offsetWithinField``) """ # Find which field it's in @@ -448,7 +465,7 @@ def encodedBitDescription(self, bitOffset, formatted=False): def pprintHeader(self, prefix=""): """ Pretty-print a header that labels the sub-fields of the encoded - output. This can be used in conjuction with pprint. + output. This can be used in conjuction with :meth:`.pprint`. :param prefix: printed before the header if specified """ @@ -496,53 +513,59 @@ def decode(self, encoded, parentFieldName=''): in many cases might be a union of one or more inputs. If instead, you want to figure the *most likely* single input scalar value - that would have generated a specific encoded output, use the :meth:`.topDownCompute` - method. + that would have generated a specific encoded output, use the + :meth:`.topDownCompute` method. If you want to pretty print the return value from this method, use the - decodedToStr() method. + :meth:`.decodedToStr` method. :param encoded: The encoded output that you want decode :param parentFieldName: The name of the encoder which is our parent. This name is prefixed to each of the field names within this encoder to form the keys of the dict() in the retval. - :return: tuple(fieldsDict, fieldOrder) (see below for details) + :return: tuple(``fieldsDict``, ``fieldOrder``) - fieldsDict is a dict() where the keys represent field names - (only 1 if this is a simple encoder, > 1 if this is a multi - or date encoder) and the values are the result of decoding each - field. If there are no bits in encoded that would have been - generated by a field, it won't be present in the dict. The - key of each entry in the dict is formed by joining the passed in - parentFieldName with the child encoder name using a '.'. + ``fieldsDict`` is a dict() where the keys represent field names + (only 1 if this is a simple encoder, > 1 if this is a multi + or date encoder) and the values are the result of decoding each + field. If there are no bits in encoded that would have been + generated by a field, it won't be present in the dict. The + key of each entry in the dict is formed by joining the passed in + parentFieldName with the child encoder name using a '.'. - Each 'value' in fieldsDict consists of (ranges, desc), where - ranges is a list of one or more (minVal, maxVal) ranges of - input that would generate bits in the encoded output and 'desc' - is a pretty print description of the ranges. For encoders like - the category encoder, the 'desc' will contain the category - names that correspond to the scalar values included in the - ranges. + Each 'value' in ``fieldsDict`` consists of (ranges, desc), where + ranges is a list of one or more (minVal, maxVal) ranges of + input that would generate bits in the encoded output and 'desc' + is a pretty print description of the ranges. For encoders like + the category encoder, the 'desc' will contain the category + names that correspond to the scalar values included in the + ranges. - The fieldOrder is a list of the keys from fieldsDict, in the - same order as the fields appear in the encoded output. + ``fieldOrder`` is a list of the keys from ``fieldsDict``, in the + same order as the fields appear in the encoded output. - TODO: when we switch to Python 2.7 or 3.x, use OrderedDict + TODO: when we switch to Python 2.7 or 3.x, use OrderedDict Example retvals for a scalar encoder: - {'amount': ( [[1,3], [7,10]], '1-3, 7-10' )} - {'amount': ( [[2.5,2.5]], '2.5' )} + .. code-block:: python + + {'amount': ( [[1,3], [7,10]], '1-3, 7-10' )} + {'amount': ( [[2.5,2.5]], '2.5' )} Example retval for a category encoder: - {'country': ( [[1,1], [5,6]], 'US, GB, ES' )} + .. code-block:: python + + {'country': ( [[1,1], [5,6]], 'US, GB, ES' )} Example retval for a multi encoder: - {'amount': ( [[2.5,2.5]], '2.5' ), - 'country': ( [[1,1], [5,6]], 'US, GB, ES' )} + .. code-block:: python + + {'amount': ( [[2.5,2.5]], '2.5' ), + 'country': ( [[1,1], [5,6]], 'US, GB, ES' )} """ @@ -578,7 +601,8 @@ def decode(self, encoded, parentFieldName=''): def decodedToStr(self, decodeResults): """ - Return a pretty print string representing the return value from decode(). + Return a pretty print string representing the return value from + :meth:`.decode`. """ (fieldsDict, fieldsOrder) = decodeResults @@ -598,16 +622,16 @@ def decodedToStr(self, decodeResults): def getBucketValues(self): """ + **Must be overridden by subclasses.** + Returns a list of items, one for each bucket defined by this encoder. Each item is the value assigned to that bucket, this is the same as the - EncoderResult.value that would be returned by getBucketInfo() for that - bucket and is in the same format as the input that would be passed to - encode(). + :attr:`.EncoderResult.value` that would be returned by + :meth:`.getBucketInfo` for that bucket and is in the same format as the + input that would be passed to :meth:`.encode`. - This call is faster than calling getBucketInfo() on each bucket individually - if all you need are the bucket values. - - **Must be overridden by subclasses.** + This call is faster than calling :meth:`.getBucketInfo` on each bucket + individually if all you need are the bucket values. :return: list of items, each item representing the bucket value for that bucket. @@ -617,31 +641,15 @@ def getBucketValues(self): def getBucketInfo(self, buckets): """ - Returns a list of EncoderResult namedtuples describing the inputs for - each sub-field that correspond to the bucket indices passed in 'buckets'. - To get the associated field names for each of the values, call getScalarNames(). + Returns a list of :class:`.EncoderResult` namedtuples describing the inputs + for each sub-field that correspond to the bucket indices passed in + ``buckets``. To get the associated field names for each of the values, call + :meth:`.getScalarNames`. :param buckets: The list of bucket indices, one for each sub-field encoder. These bucket indices for example may have been retrieved - from the getBucketIndices() call. - :return: A list of EncoderResult namedtuples. Each EncoderResult has - three attributes: - - -# value: This is the value for the sub-field - in a format that is consistent with the type - specified by getDecoderOutputFieldTypes(). - Note that this value is not necessarily - numeric. - -# scalar: The scalar representation of value. This - number is consistent with what is returned - by getScalars(). This value is always an - int or float, and can be used for - numeric comparisons - -# encoding This is the encoded bit-array (numpy array) - that represents 'value'. That is, if 'value' - was passed to encode(), an identical - bit-array should be returned - + from the :meth:`.getBucketIndices` call. + :return: A list of :class:`.EncoderResult`. """ # Fall back topdown compute if self.encoders is None: @@ -669,35 +677,16 @@ def getBucketInfo(self, buckets): def topDownCompute(self, encoded): """ - Returns a list of EncoderResult namedtuples describing the top-down - best guess inputs for each sub-field given the encoded output. These are the - values which are most likely to generate the given encoded output. - To get the associated field names for each of the values, call - getScalarNames(). - - :param encoded: The encoded output. Typically received from the topDown outputs - from the spatial pooler just above us. - - :return: A list of EncoderResult namedtuples. Each EncoderResult has - three attributes: - - -# value: This is the best-guess value for the sub-field - in a format that is consistent with the type - specified by getDecoderOutputFieldTypes(). - Note that this value is not necessarily - numeric. + Returns a list of :class:`.EncoderResult` namedtuples describing the + top-down best guess inputs for each sub-field given the encoded output. + These are the values which are most likely to generate the given encoded + output. To get the associated field names for each of the values, call + :meth:`.getScalarNames`. - -# scalar: The scalar representation of this best-guess - value. This number is consistent with what - is returned by getScalars(). This value is - always an int or float, and can be used for - numeric comparisons. + :param encoded: The encoded output. Typically received from the topDown + outputs from the spatial pooler just above us. - -# encoding This is the encoded bit-array (numpy array) - that represents the best-guess value. - That is, if 'value' was passed to - encode(), an identical bit-array should be - returned. + :return: A list of :class:`.EncoderResult` """ # Fallback topdown compute if self.encoders is None: @@ -728,23 +717,23 @@ def closenessScores(self, expValues, actValues, fractional=True): """ Compute closeness scores between the expected scalar value(s) and actual scalar value(s). The expected scalar values are typically those obtained - from the getScalars() method. The actual scalar values are typically those - returned from :meth:`.topDownCompute`. + from the :meth:`.getScalars` method. The actual scalar values are typically + those returned from :meth:`.topDownCompute`. This method returns one closeness score for each value in expValues (or actValues which must be the same length). The closeness score ranges from 0 to 1.0, 1.0 being a perfect match and 0 being the worst possible match. If this encoder is a simple, single field encoder, then it will expect - just 1 item in each of the expValues and actValues arrays. Multi-encoders - will expect 1 item per sub-encoder. + just 1 item in each of the ``expValues`` and ``actValues`` arrays. + Multi-encoders will expect 1 item per sub-encoder. Each encoder type can define it's own metric for closeness. For example, a category encoder may return either 1 or 0, if the scalar matches exactly or not. A scalar encoder might return a percentage match, etc. :param expValues: Array of expected scalar values, typically obtained from - getScalars() + :meth:`.getScalars` :param actValues: Array of actual values, typically obtained from :meth:`.topDownCompute` @@ -782,7 +771,7 @@ def getDisplayWidth(self): """ Calculate width of display for bits plus blanks between fields. - :return: width of display for bits plus blanks between fields + :return: (int) width of display for bits plus blanks between fields """ width = self.getWidth() + len(self.getDescription()) - 1 return width @@ -790,10 +779,9 @@ def getDisplayWidth(self): def formatBits(self, inarray, outarray, scale=1, blank=255, leftpad=0): """ - Copy one array to another, inserting blanks - between fields (for display) - If leftpad is one, then there is a dummy value at element 0 - of the arrays, and we should start our counting from 1 rather than 0 + Copy one array to another, inserting blanks between fields (for display). + If ``leftpad`` is one, then there is a dummy value at element 0 + of the arrays, and we should start our counting from 1 rather than 0. :param inarray: TODO: document :param outarray: TODO: document From 20b7fc9a027d1dd1128c9c4acb0292fd6fcfadea Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 11:38:22 -0700 Subject: [PATCH 05/14] category encoders docstrings --- src/nupic/encoders/category.py | 18 ++++++++++-------- src/nupic/encoders/sdrcategory.py | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/nupic/encoders/category.py b/src/nupic/encoders/category.py index 8ba69c9d01..3f0e5836dc 100644 --- a/src/nupic/encoders/category.py +++ b/src/nupic/encoders/category.py @@ -33,22 +33,24 @@ class CategoryEncoder(Encoder): - """Encodes a list of discrete categories (described by strings), that aren't + """ + Encodes a list of discrete categories (described by strings), that aren't related to each other, so we never emit a mixture of categories. The value of zero is reserved for "unknown category" - Internally we use a ScalarEncoder with a radius of 1, but since we only encode - integers, we never get mixture outputs. + Internally we use a :class:`.ScalarEncoder` with a radius of 1, but since we + only encode integers, we never get mixture outputs. - The SDRCategoryEncoder uses a different method to encode categories""" + The :class:`.SDRCategoryEncoder` uses a different method to encode categories. + :param categoryList: list of discrete string categories + :param forced: if True, skip checks for parameters' settings; see + :class:`.ScalarEncoder` for details. (default False) + """ - def __init__(self, w, categoryList, name="category", verbosity=0, forced=False): - """params: - forced (default False) : if True, skip checks for parameters' settings; see encoders/scalar.py for details - """ + def __init__(self, w, categoryList, name="category", verbosity=0, forced=False): self.encoders = None self.verbosity = verbosity diff --git a/src/nupic/encoders/sdrcategory.py b/src/nupic/encoders/sdrcategory.py index 8abea3adec..62a3269ca8 100644 --- a/src/nupic/encoders/sdrcategory.py +++ b/src/nupic/encoders/sdrcategory.py @@ -30,29 +30,29 @@ class SDRCategoryEncoder(Encoder): - """Encodes a list of discrete categories (described by strings), that aren't + """ + Encodes a list of discrete categories (described by strings), that aren't related to each other. Each encoding is an SDR in which w out of n bits are turned on. - Unknown categories are encoded as a single + Unknown categories are encoded as a single value. - Internally we use a ScalarEncoder with a radius of 1, but since we only encode - integers, we never get mixture outputs. + Internally we use a :class:`.ScalarEncoder` with a radius of 1, but since we + only encode integers, we never get mixture outputs. - The SDRCategoryEncoder uses a different method to encode categories""" + The :class:`.CategoryEncoder` uses a different method to encode categories + + :param categoryList: list of discrete string categories, if ``None`` then + categories will automatically be added as they are + encountered + :param forced: if True, skip checks for parameters' settings; see + :class:`.ScalarEncoder` for details. (default False) + """ def __init__(self, n, w, categoryList = None, name="category", verbosity=0, encoderSeed=1, forced=False): - """ - n is total bits in output - w is the number of bits that are turned on for each rep - categoryList is a list of strings that define the categories. - If "none" then categories will automatically be added as they are encountered. - forced (default False) : if True, skip checks for parameters' settings; see encoders/scalar.py for details - """ - self.n = n self.w = w From 0ab4ef917d3219452119fa814ea30a40cc3de496 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 11:38:40 -0700 Subject: [PATCH 06/14] coordinate and geo encoder docstrings --- src/nupic/encoders/coordinate.py | 21 +++++++--------- src/nupic/encoders/geospatial_coordinate.py | 28 +++++++++------------ 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/nupic/encoders/coordinate.py b/src/nupic/encoders/coordinate.py index dc24714506..b8e5179aa1 100644 --- a/src/nupic/encoders/coordinate.py +++ b/src/nupic/encoders/coordinate.py @@ -41,24 +41,21 @@ class CoordinateEncoder(Encoder): It uses the following algorithm: 1. Find all the coordinates around the input coordinate, within the - specified radius. + specified radius. 2. For each coordinate, use a uniform hash function to - deterministically map it to a real number between 0 and 1. This is the - "order" of the coordinate. + deterministically map it to a real number between 0 and 1. This is the + "order" of the coordinate. 3. Of these coordinates, pick the top W by order, where W is the - number of active bits desired in the SDR. + number of active bits desired in the SDR. 4. For each of these W coordinates, use a uniform hash function to - deterministically map it to one of the bits in the SDR. Make this bit active. - 5. This results in a final SDR with exactly W bits active - (barring chance hash collisions). + deterministically map it to one of the bits in the SDR. Make this bit + active. + 5. This results in a final SDR with exactly W bits active (barring chance hash + collisions). + """ def __init__(self, w=21, n=1000, name=None, verbosity=0): - """ - See `nupic.encoders.base.Encoder` for more information. - - @param name An optional string which will become part of the description - """ # Validate inputs if (w <= 0) or (w % 2 == 0): raise ValueError("w must be an odd positive integer") diff --git a/src/nupic/encoders/geospatial_coordinate.py b/src/nupic/encoders/geospatial_coordinate.py index a1cbd4a4d2..861eca637b 100644 --- a/src/nupic/encoders/geospatial_coordinate.py +++ b/src/nupic/encoders/geospatial_coordinate.py @@ -40,6 +40,10 @@ class GeospatialCoordinateEncoder(CoordinateEncoder): Given a GPS coordinate and a speed reading, the Geospatial Coordinate Encoder returns an SDR representation of that position. + + :param: scale (int) Scale of the map, as measured by distance between two + coordinates (in meters per dimensional unit) + :param: timestep (int) Time between readings (in seconds) """ def __init__(self, @@ -49,14 +53,6 @@ def __init__(self, n=1000, name=None, verbosity=0): - """ - See `nupic.encoders.base.Encoder` for more information. - - @param scale (int) Scale of the map, as measured by - distance between two coordinates - (in meters per dimensional unit) - @param timestep (int) Time between readings (in seconds) - """ super(GeospatialCoordinateEncoder, self).__init__(w=w, n=n, name=name, @@ -80,9 +76,9 @@ def encodeIntoArray(self, inputData, output): """ See `nupic.encoders.base.Encoder` for more information. - @param inputData (tuple) Contains speed (float), longitude (float), + :param: inputData (tuple) Contains speed (float), longitude (float), latitude (float), altitude (float) - @param output (numpy.array) Stores encoded SDR in this numpy array + :param: output (numpy.array) Stores encoded SDR in this numpy array """ altitude = None if len(inputData) == 4: @@ -99,10 +95,10 @@ def coordinateForPosition(self, longitude, latitude, altitude=None): """ Returns coordinate for given GPS position. - @param longitude (float) Longitude of position - @param latitude (float) Latitude of position - @param altitude (float) Altitude of position - @return (numpy.array) Coordinate that the given GPS position + :param: longitude (float) Longitude of position + :param: latitude (float) Latitude of position + :param: altitude (float) Altitude of position + :returns: (numpy.array) Coordinate that the given GPS position maps to """ coords = PROJ(longitude, latitude) @@ -122,8 +118,8 @@ def radiusForSpeed(self, speed): Tries to get the encodings of consecutive readings to be adjacent with some overlap. - @param speed (float) Speed (in meters per second) - @return (int) Radius for given speed + :param: speed (float) Speed (in meters per second) + :returns: (int) Radius for given speed """ overlap = 1.5 coordinatesPerTimestep = speed * self.timestep / self.scale From 0ab9e9af4592520fbc147186702cb1f1de5722cb Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 11:38:51 -0700 Subject: [PATCH 07/14] delta encoder docstrings --- src/nupic/encoders/delta.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nupic/encoders/delta.py b/src/nupic/encoders/delta.py index 26ec5f2318..9395f83901 100644 --- a/src/nupic/encoders/delta.py +++ b/src/nupic/encoders/delta.py @@ -28,9 +28,9 @@ class DeltaEncoder(AdaptiveScalarEncoder): """ - This is an implementation of a delta encoder. The delta encoder encodes differences between - successive scalar values instead of encoding the actual values. It returns an actual value when - decoding and not a delta. + This is an implementation of a delta encoder. The delta encoder encodes + differences between successive scalar values instead of encoding the actual + values. It returns an actual value when decoding and not a delta. """ From ad70a9e47737f2863f3d0b69291570cc68a84fa4 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 11:39:01 -0700 Subject: [PATCH 08/14] log encoder docstrings --- src/nupic/encoders/logenc.py | 39 +++++++++++------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/nupic/encoders/logenc.py b/src/nupic/encoders/logenc.py index 1ad76c137e..5e224a1055 100644 --- a/src/nupic/encoders/logenc.py +++ b/src/nupic/encoders/logenc.py @@ -30,37 +30,22 @@ class LogEncoder(Encoder): """ - This class wraps the ScalarEncoder class. + This class wraps the :class:`.ScalarEncoder`. A Log encoder represents a floating point value on a logarithmic scale. - valueToEncode = log10(input) - - w -- number of bits to set in output - minval -- minimum input value. must be greater than 0. Lower values are - reset to this value - maxval -- maximum input value (input is strictly less if periodic == True) - periodic -- If true, then the input value "wraps around" such that minval = - maxval For a periodic value, the input must be strictly less than - maxval, otherwise maxval is a true upper bound. - - Exactly one of n, radius, resolution must be set. "0" is a special - value that means "not set". - - n -- number of bits in the representation (must be > w) - radius -- inputs separated by more than this distance in log space will have - non-overlapping representations - resolution -- The minimum change in scaled value needed to produce a change - in encoding. This should be specified in log space. For - example, the scaled values 10 and 11 will be distinguishable - in the output. In terms of the original input values, this - means 10^1 (1) and 10^1.1 (1.25) will be distinguishable. - name -- an optional string which will become part of the description - verbosity -- level of debugging output you want the encoder to provide. - clipInput -- if true, non-periodic inputs smaller than minval or greater - than maxval will be clipped to minval/maxval - forced -- (default False), if True, skip some safety checks + .. code-block:: python + valueToEncode = log10(input) + + :param resolution: The minimum change in scaled value needed to produce a + change in encoding. This should be specified in log space. + For example, the scaled values 10 and 11 will be + distinguishable in the output. In terms of the original + input values, this means 10^1 (1) and 10^1.1 (1.25) will be + distinguishable. + :param radius: inputs separated by more than this distance in log space will + have non-overlapping representations """ def __init__(self, From 2bd583a4bbb27c9e661762b66d268a964026d740 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 11:39:07 -0700 Subject: [PATCH 09/14] Update docs TODO and encoder index page --- docs/README.md | 14 +++++++------- docs/source/api/algorithms/encoders.rst | 24 ++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index dbdd46fa27..d9929e3959 100644 --- a/docs/README.md +++ b/docs/README.md @@ -94,19 +94,19 @@ nupic │   └── utils.py [TODO] ├── encoders │   ├── adaptivescalar.py [OK] -│   ├── base.py [TODO] -│   ├── category.py [TODO] -│   ├── coordinate.py [TODO] +│   ├── base.py [OK] +│   ├── category.py [OK] +│   ├── coordinate.py [OK] │   ├── date.py [OK] -│   ├── delta.py [TODO] -│   ├── geospatial_coordinate.py [TODO] -│   ├── logenc.py [TODO] +│   ├── delta.py [OK] +│   ├── geospatial_coordinate.py [OK] +│   ├── logenc.py [OK] │   ├── multi.py [TODO] │   ├── pass_through_encoder.py [TODO] │   ├── random_distributed_scalar.py [OK] │   ├── scalar.py [TODO] │   ├── scalarspace.py [TODO] -│   ├── sdrcategory.py [TODO] +│   ├── sdrcategory.py [OK] │   ├── sparse_pass_through_encoder.py [TODO] │   └── utils.py [TODO] ├── frameworks diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index e67589b5ef..1d18e280a4 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -14,6 +14,15 @@ Encoder Result .. autoclass:: nupic.encoders.base.EncoderResult +Category Encoders +^^^^^^^^^^^^^^^^^ + +.. autoclass:: nupic.encoders.category.CategoryEncoder + :show-inheritance: + +.. autoclass:: nupic.encoders.sdrcategory.SDRCategoryEncoder + :show-inheritance: + Scalar Encoder ^^^^^^^^^^^^^^ @@ -45,15 +54,26 @@ CoordinateEncoder ^^^^^^^^^^^^^^^^^ .. autoclass:: nupic.encoders.coordinate.CoordinateEncoder - :members: + :show-inheritance: GeospatialCoordinateEncoder ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: nupic.encoders.geospatial_coordinate.GeospatialCoordinateEncoder - :members: + :members: coordinateForPosition, radiusForSpeed + :show-inheritance: + +DeltaEncoder +^^^^^^^^^^^^ +.. autoclass:: nupic.encoders.delta.DeltaEncoder + :show-inheritance: + +Logarithm Encoder +^^^^^^^^^^^^^^^^^ +.. autoclass:: nupic.encoders.logenc.LogEncoder + :show-inheritance: MultiEncoder ^^^^^^^^^^^^ From 019982eea468f0843d315a67ab274831a7eff67b Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 11:49:48 -0700 Subject: [PATCH 10/14] Added docstrings for multi-encoder --- docs/README.md | 2 +- docs/source/api/algorithms/encoders.rst | 2 +- src/nupic/encoders/multi.py | 71 +++++++++++++++---------- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/docs/README.md b/docs/README.md index d9929e3959..5b31b84ca7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -101,7 +101,7 @@ nupic │   ├── delta.py [OK] │   ├── geospatial_coordinate.py [OK] │   ├── logenc.py [OK] -│   ├── multi.py [TODO] +│   ├── multi.py [OK] │   ├── pass_through_encoder.py [TODO] │   ├── random_distributed_scalar.py [OK] │   ├── scalar.py [TODO] diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index 1d18e280a4..4880186544 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -79,5 +79,5 @@ MultiEncoder ^^^^^^^^^^^^ .. autoclass:: nupic.encoders.multi.MultiEncoder - :members: + :members: addEncoder, addMultipleEncoders :show-inheritance: diff --git a/src/nupic/encoders/multi.py b/src/nupic/encoders/multi.py index 069e220272..6a837cf85a 100644 --- a/src/nupic/encoders/multi.py +++ b/src/nupic/encoders/multi.py @@ -60,19 +60,22 @@ class MultiEncoder(Encoder): - """A MultiEncoder encodes a dictionary or object with - multiple components. A MultiEncode contains a number - of sub-encoders, each of which encodes a separate component.""" - # TODO expand this docstring to explain how the multiple encoders are combined + """ + A MultiEncoder encodes a dictionary or object with multiple components. A + MultiEncoder contains a number of sub-encoders, each of which encodes a + separate component. + :param encoderDefinitions: a dict of dicts, mapping field names to the field + params dict. Sent directly to :meth:`.addMultipleEncoders`. + """ - def __init__(self, encoderDescriptions=None): + def __init__(self, encoderDefinitions=None): self.width = 0 self.encoders = [] self.description = [] self.name = '' - if encoderDescriptions is not None: - self.addMultipleEncoders(encoderDescriptions) + if encoderDefinitions is not None: + self.addMultipleEncoders(encoderDefinitions) def setFieldStats(self, fieldName, fieldStatistics ): @@ -81,6 +84,12 @@ def setFieldStats(self, fieldName, fieldStatistics ): def addEncoder(self, name, encoder): + """ + Adds one encoder. + + :param name: (string) name of encoder, should be unique + :param encoder: (:class:`.Encoder`) the encoder to add + """ self.encoders.append((name, encoder, self.width)) for d in encoder.getDescription(): self.description.append((d[0], d[1] + self.width)) @@ -125,30 +134,36 @@ def encodeEachField(self, inputRecord): def addMultipleEncoders(self, fieldEncodings): """ - fieldEncodings -- a dict of dicts, mapping field names to the field params - dict. - Each field params dict has the following keys - 1) data fieldname that matches the key ('fieldname') - 2) an encoder type ('type') - 3) and the encoder params (all other keys) + :param fieldEncodings: dict of dicts, mapping field names to the field + params dict. + + Each field params dict has the following keys: + + 1. ``fieldname``: data field name + 2. ``type`` an encoder type + 3. All other keys are encoder parameters For example, - fieldEncodings={ - 'dateTime': dict(fieldname='dateTime', type='DateEncoder', - timeOfDay=(5,5)), - 'attendeeCount': dict(fieldname='attendeeCount', type='ScalarEncoder', - name='attendeeCount', minval=0, maxval=250, - clipInput=True, w=5, resolution=10), - 'consumption': dict(fieldname='consumption',type='ScalarEncoder', - name='consumption', minval=0,maxval=110, - clipInput=True, w=5, resolution=5), - } - - would yield a vector with a part encoded by the DateEncoder, - and to parts seperately taken care of by the ScalarEncoder with the specified parameters. - The three seperate encodings are then merged together to the final vector, in such a way that - they are always at the same location within the vector. + + .. code-block:: python + + fieldEncodings={ + 'dateTime': dict(fieldname='dateTime', type='DateEncoder', + timeOfDay=(5,5)), + 'attendeeCount': dict(fieldname='attendeeCount', type='ScalarEncoder', + name='attendeeCount', minval=0, maxval=250, + clipInput=True, w=5, resolution=10), + 'consumption': dict(fieldname='consumption',type='ScalarEncoder', + name='consumption', minval=0,maxval=110, + clipInput=True, w=5, resolution=5), + } + + would yield a vector with a part encoded by the :class:`.DateEncoder`, and + to parts seperately taken care of by the :class:`.ScalarEncoder` with the + specified parameters. The three seperate encodings are then merged together + to the final vector, in such a way that they are always at the same location + within the vector. """ # Sort the encoders so that they end up in a controlled order From cb2b1f7ebcdfe95d47b4117192727c7177257ad0 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 11:55:34 -0700 Subject: [PATCH 11/14] Added docstrings for pass-through-encoder --- docs/README.md | 2 +- docs/source/api/algorithms/encoders.rst | 7 ++++++ src/nupic/encoders/pass_through_encoder.py | 25 ++++++++++++---------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/README.md b/docs/README.md index 5b31b84ca7..c2b09e068c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -102,7 +102,7 @@ nupic │   ├── geospatial_coordinate.py [OK] │   ├── logenc.py [OK] │   ├── multi.py [OK] -│   ├── pass_through_encoder.py [TODO] +│   ├── pass_through_encoder.py [OK] │   ├── random_distributed_scalar.py [OK] │   ├── scalar.py [TODO] │   ├── scalarspace.py [TODO] diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index 4880186544..27f566c886 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -81,3 +81,10 @@ MultiEncoder .. autoclass:: nupic.encoders.multi.MultiEncoder :members: addEncoder, addMultipleEncoders :show-inheritance: + +Pass Through Encoder +^^^^^^^^^^^^^^^^^^^^ + +.. autoclass:: nupic.encoders.pass_through_encoder.PassThroughEncoder + :members: closenessScores + :show-inheritance: diff --git a/src/nupic/encoders/pass_through_encoder.py b/src/nupic/encoders/pass_through_encoder.py index 8f9d4412d3..e974fc67da 100644 --- a/src/nupic/encoders/pass_through_encoder.py +++ b/src/nupic/encoders/pass_through_encoder.py @@ -26,20 +26,20 @@ class PassThroughEncoder(Encoder): - """Pass an encoded SDR straight to the model. + """ + Pass an encoded SDR straight to the model. Each encoding is an SDR in which w out of n bits are turned on. The input should be a 1-D array or numpy.ndarray of length n + + :param n: the total #bits in output + :param w: used to normalize the sparsity of the output, exactly w bits ON, + if None (default) - do not alter the input, just pass it further. + :param forced: if forced, encode will accept any data, and just return it back """ def __init__(self, n, w=None, name="pass_through", forced=False, verbosity=0): - """ - n -- is the total #bits in output - w -- is used to normalize the sparsity of the output, exactly w bits ON, - if None (default) - do not alter the input, just pass it further. - forced -- if forced, encode will accept any data, and just return it back. - """ self.n = n self.w = w self.verbosity = verbosity @@ -113,12 +113,15 @@ def topDownCompute(self, encoded): def closenessScores(self, expValues, actValues, **kwargs): - """Does a bitwise compare of the two bitmaps and returns a fractonal + """ + Does a bitwise compare of the two bitmaps and returns a fractonal value between 0 and 1 of how similar they are. - 1 => identical - 0 => no overlaping bits - kwargs will have the keyword "fractional", which is assumed by this encoder + - ``1`` => identical + - ``0`` => no overlaping bits + + ``kwargs`` will have the keyword "fractional", which is assumed by this + encoder. """ ratio = 1.0 esum = int(expValues.sum()) From 2662df9a27ab842dec2e41c06a52d1bf09106a21 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 12:01:16 -0700 Subject: [PATCH 12/14] Added docstrings for sparse-pass-through-encoder --- docs/README.md | 2 +- docs/source/api/algorithms/encoders.rst | 9 +++-- .../encoders/sparse_pass_through_encoder.py | 36 ++++++++++++++----- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index c2b09e068c..5149d2fbe9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -107,7 +107,7 @@ nupic │   ├── scalar.py [TODO] │   ├── scalarspace.py [TODO] │   ├── sdrcategory.py [OK] -│   ├── sparse_pass_through_encoder.py [TODO] +│   ├── sparse_pass_through_encoder.py [OK] │   └── utils.py [TODO] ├── frameworks │   ├── opf diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index 27f566c886..b0e70bfefc 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -82,9 +82,14 @@ MultiEncoder :members: addEncoder, addMultipleEncoders :show-inheritance: -Pass Through Encoder -^^^^^^^^^^^^^^^^^^^^ +Pass Through Encoders +^^^^^^^^^^^^^^^^^^^^^ + +Used to pass raw SDRs through to the algorithms when data is already encoded. .. autoclass:: nupic.encoders.pass_through_encoder.PassThroughEncoder :members: closenessScores :show-inheritance: + +.. autoclass:: nupic.encoders.sparse_pass_through_encoder.SparsePassThroughEncoder + :show-inheritance: diff --git a/src/nupic/encoders/sparse_pass_through_encoder.py b/src/nupic/encoders/sparse_pass_through_encoder.py index 142b71fd66..d83f887520 100644 --- a/src/nupic/encoders/sparse_pass_through_encoder.py +++ b/src/nupic/encoders/sparse_pass_through_encoder.py @@ -26,16 +26,36 @@ class SparsePassThroughEncoder(pass_through_encoder.PassThroughEncoder): - """Convert a bitmap encoded as array indicies to an SDR + """ + Convert a bitmap encoded as array indices to an SDR. + + Each encoding is an SDR in which ``w`` out of ``n`` bits are turned on. + The input should be an array or string of indices to turn on. + + **Note:** the value for ``n`` must equal input length * w, for example: + + .. code-block:: python + + for n=8 w=1 [0,2,5] => 101001000 + + or: + + .. code-block:: python + + for n=8 w=1 "0,2,5" => 101001000 + + and: + + .. code-block:: python + + for n=24 w=3 [0,2,5] => 111000111000000111000000000 + + or: + + .. code-block:: python - Each encoding is an SDR in which w out of n bits are turned on. - The input should be an array or string of indicies to turn on - Note: the value for n must equal input length * w - i.e. for n=8 w=1 [0,2,5] => 101001000 - or for n=8 w=1 "0,2,5" => 101001000 + for n=24 w=3 "0,2,5" => 111000111000000111000000000 - i.e. for n=24 w=3 [0,2,5] => 111000111000000111000000000 - or for n=24 w=3 "0,2,5" => 111000111000000111000000000 """ From d4f302aed5273af15a4ad8d6f6c1f708988bd830 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Tue, 2 May 2017 12:12:45 -0700 Subject: [PATCH 13/14] Finished scalar encoder docstrings --- docs/README.md | 7 ++--- docs/source/api/algorithms/encoders.rst | 40 +++++++++---------------- src/nupic/encoders/scalar.py | 36 ++++++++++++---------- src/nupic/encoders/scalarspace.py | 30 ++++++++++++------- 4 files changed, 58 insertions(+), 55 deletions(-) diff --git a/docs/README.md b/docs/README.md index 5149d2fbe9..d89499ca74 100644 --- a/docs/README.md +++ b/docs/README.md @@ -104,11 +104,10 @@ nupic │   ├── multi.py [OK] │   ├── pass_through_encoder.py [OK] │   ├── random_distributed_scalar.py [OK] -│   ├── scalar.py [TODO] -│   ├── scalarspace.py [TODO] +│   ├── scalar.py [OK] +│   ├── scalarspace.py [OK] │   ├── sdrcategory.py [OK] -│   ├── sparse_pass_through_encoder.py [OK] -│   └── utils.py [TODO] +│   └── sparse_pass_through_encoder.py [OK] ├── frameworks │   ├── opf │   │   ├── htm_prediction_model.py [TODO] diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index b0e70bfefc..181c01f901 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -23,25 +23,28 @@ Category Encoders .. autoclass:: nupic.encoders.sdrcategory.SDRCategoryEncoder :show-inheritance: -Scalar Encoder +Scalar Encoders ^^^^^^^^^^^^^^ .. autoclass:: nupic.encoders.scalar.ScalarEncoder :show-inheritance: -Adaptive Scalar Encoder -^^^^^^^^^^^^^^^^^^^^^^^ - .. autoclass:: nupic.encoders.adaptivescalar.AdaptiveScalarEncoder :show-inheritance: +.. autoclass:: nupic.encoders.random_distributed_scalar.RandomDistributedScalarEncoder + :members: mapBucketIndexToNonZeroBits + :show-inheritance: -Random Distributed Scalar Encoder -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autoclass:: nupic.encoders.scalarspace.ScalarSpaceEncoder + :show-inheritance: + +.. autoclass:: nupic.encoders.delta.DeltaEncoder + :show-inheritance: + +.. autoclass:: nupic.encoders.logenc.LogEncoder + :show-inheritance: -.. autoclass:: nupic.encoders.random_distributed_scalar.RandomDistributedScalarEncoder - :members: mapBucketIndexToNonZeroBits - :show-inheritance: DateEncoder ^^^^^^^^^^^ @@ -50,31 +53,16 @@ DateEncoder :members: getScalars :show-inheritance: -CoordinateEncoder -^^^^^^^^^^^^^^^^^ +Coordinate Encoders +^^^^^^^^^^^^^^^^^^^ .. autoclass:: nupic.encoders.coordinate.CoordinateEncoder :show-inheritance: -GeospatialCoordinateEncoder -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - .. autoclass:: nupic.encoders.geospatial_coordinate.GeospatialCoordinateEncoder :members: coordinateForPosition, radiusForSpeed :show-inheritance: -DeltaEncoder -^^^^^^^^^^^^ - -.. autoclass:: nupic.encoders.delta.DeltaEncoder - :show-inheritance: - -Logarithm Encoder -^^^^^^^^^^^^^^^^^ - -.. autoclass:: nupic.encoders.logenc.LogEncoder - :show-inheritance: - MultiEncoder ^^^^^^^^^^^^ diff --git a/src/nupic/encoders/scalar.py b/src/nupic/encoders/scalar.py index fa007fccef..5093313fed 100644 --- a/src/nupic/encoders/scalar.py +++ b/src/nupic/encoders/scalar.py @@ -60,30 +60,36 @@ class ScalarEncoder(Encoder): :param minval: The minimum value of the input signal. - :param maxval: The upper bound of the input signal. (input is strictly less if periodic == True) + :param maxval: The upper bound of the input signal. (input is strictly less if + ``periodic == True``) - :param periodic: If true, then the input value "wraps around" such that minval = maxval - For a periodic value, the input must be strictly less than maxval, - otherwise maxval is a true upper bound. + :param periodic: If true, then the input value "wraps around" such that + ``minval`` = ``maxval``. For a periodic value, the input must be + strictly less than ``maxval``, otherwise ``maxval`` is a true + upper bound. - :param n: The number of bits in the output. Must be greater than or equal to w - :param radius: Two inputs separated by more than the radius have non-overlapping - representations. Two inputs separated by less than the radius will - in general overlap in at least some of their bits. You can think - of this as the radius of the input. - :param resolution: Two inputs separated by greater than, or equal to the resolution are guaranteed - to have different representations. + :param n: The number of bits in the output. Must be greater than or equal to + ``w`` + + :param radius: Two inputs separated by more than the radius have + non-overlapping representations. Two inputs separated by less + than the radius will in general overlap in at least some of + their bits. You can think of this as the radius of the input. + + :param resolution: Two inputs separated by greater than, or equal to the + resolution are guaranteed to have different + representations. :param name: an optional string which will become part of the description :param clipInput: if true, non-periodic inputs smaller than minval or greater than maxval will be clipped to minval/maxval - :param forced: if true, skip some safety checks (for compatibility reasons), default false - + :param forced: if true, skip some safety checks (for compatibility reasons), + default false - .. note:: Radius and resolution are specified with respect to the input, not output. w - is specified with respect to the output. + .. note:: ``radius`` and ``resolution`` are specified with respect to the + input, not output. ``w`` is specified with respect to the output. **Example: day of week** diff --git a/src/nupic/encoders/scalarspace.py b/src/nupic/encoders/scalarspace.py index 811cb11e29..1dc6b8e40b 100644 --- a/src/nupic/encoders/scalarspace.py +++ b/src/nupic/encoders/scalarspace.py @@ -24,22 +24,32 @@ class ScalarSpaceEncoder(Encoder): - """An encoder that can be used to permute the encodings through different spaces - These include absolute value,delta, log space, etc. """ + An encoder that can be used to permute the encodings through different spaces + These include absolute value, delta, log space, etc. + + :param space: (string) if "absolute", an :class:`.AdaptiveScalarEncoder` is + returned. Otherwise, a :class:`.DeltaEncoder` is returned. + """ + + SPACE_ABSOLUTE = "absolute" + SPACE_DELTA = "delta" + - - SPACE_ABSOLUTE="absolute" - SPACE_DELTA="delta" def __init__(self): pass + + def __new__(self, w, minval=None, maxval=None, periodic=False, n=0, radius=0, - resolution=0, name=None, verbosity=0, clipInput=False, - space="absolute", forced=False): + resolution=0, name=None, verbosity=0, clipInput=False, + space="absolute", forced=False): self._encoder = None + if space == "absolute": - ret = AdaptiveScalarEncoder(w,minval,maxval,periodic,n,radius, - resolution,name,verbosity,clipInput, forced=forced) + ret = AdaptiveScalarEncoder(w, minval, maxval, periodic, n, radius, + resolution, name, verbosity, clipInput, + forced=forced) else: - ret = DeltaEncoder(w,minval,maxval,periodic,n,radius,resolution,name,verbosity,clipInput, forced=forced) + ret = DeltaEncoder(w, minval, maxval, periodic, n, radius, resolution, + name, verbosity, clipInput, forced=forced) return ret From 669de75642cb372b3bca8c874a55d0cff44d1ff7 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 3 May 2017 07:10:58 -0700 Subject: [PATCH 14/14] Little cleanup of encoder docs --- docs/source/api/algorithms/encoders.rst | 2 +- src/nupic/encoders/base.py | 30 +++++++++---------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/docs/source/api/algorithms/encoders.rst b/docs/source/api/algorithms/encoders.rst index 181c01f901..66d54d3652 100644 --- a/docs/source/api/algorithms/encoders.rst +++ b/docs/source/api/algorithms/encoders.rst @@ -24,7 +24,7 @@ Category Encoders :show-inheritance: Scalar Encoders -^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^ .. autoclass:: nupic.encoders.scalar.ScalarEncoder :show-inheritance: diff --git a/src/nupic/encoders/base.py b/src/nupic/encoders/base.py index 2420bb5a16..fffc9312da 100644 --- a/src/nupic/encoders/base.py +++ b/src/nupic/encoders/base.py @@ -74,27 +74,17 @@ class Encoder(object): .. note:: The Encoder superclass implements: - - :func:`~nupic.encoders.base.Encoder.encode` - returns a numpy array encoding - the input; syntactic sugar on top of encodeIntoArray. If pprint, prints the - encoding to the terminal - - :func:`~nupic.encoders.base.Encoder.pprintHeader` - prints a header - describing the encoding to the terminal - - :func:`~nupic.encoders.base.Encoder.pprint` - prints an encoding to the - terminal + - :func:`~nupic.encoders.base.Encoder.encode` + - :func:`~nupic.encoders.base.Encoder.pprintHeader` + - :func:`~nupic.encoders.base.Encoder.pprint` .. warning:: The following methods and properties must be implemented by subclasses: - - :func:`~nupic.encoders.base.Encoder.getDecoderOutputFieldTypes` - must be - implemented by leaf encoders. Returns :class:`~nupic.data.field_meta.FieldMetaType`.XXXXX - (e.g., :class:`~nupic.data.field_meta.FieldMetaType`.float) - - :func:`~nupic.encoders.base.Encoder.getWidth` - returns the output width, in - bits - - :func:`~nupic.encoders.base.Encoder.encodeIntoArray` - encodes input and - puts the encoded value into the numpy output array, which is a 1-D array of - length returned by :func:`~nupic.encoders.base.Encoder.getWidth` - - :func:`~nupic.encoders.base.Encoder.getDescription` - returns a list of - (name, offset) pairs describing the encoded output + - :func:`~nupic.encoders.base.Encoder.getDecoderOutputFieldTypes` + - :func:`~nupic.encoders.base.Encoder.getWidth` + - :func:`~nupic.encoders.base.Encoder.encodeIntoArray` + - :func:`~nupic.encoders.base.Encoder.getDescription` """ @@ -111,7 +101,7 @@ def encodeIntoArray(self, inputData, output): Encodes inputData and puts the encoded value into the numpy output array, which is a 1-D array of length returned by :meth:`.getWidth`. - Note: The numpy output array is reused, so clear it before updating it. + .. note:: The numpy output array is reused, so clear it before updating it. :param inputData: Data to encode. This should be validated by the encoder. :param output: numpy 1-D array of same length returned by @@ -284,7 +274,7 @@ def getScalars(self, inputData): of the inputData with the scalar value returned from :meth:`.topDownCompute` on a top-down representation to evaluate prediction accuracy, for example. - :param inputData: The data from the source. This is typically a object with + :param inputData: The data from the source. This is typically an object with members :return: array of scalar values """ @@ -345,7 +335,7 @@ def getBucketIndices(self, inputData): of the inputData. To get the associated field names for each of the buckets, call :meth:`.getScalarNames`. - :param inputData: The data from the source. This is typically a object with + :param inputData: The data from the source. This is typically an object with members. :return: array of bucket indices """