diff --git a/python/vowpalwabbit/pyvw.py b/python/vowpalwabbit/pyvw.py index 9e44a0ae801..9ffe5738d64 100644 --- a/python/vowpalwabbit/pyvw.py +++ b/python/vowpalwabbit/pyvw.py @@ -8,6 +8,27 @@ class SearchTask(): """Search task class""" def __init__(self, vw, sch, num_actions): + """ + Parameters + ---------- + + vw : vw object + sch : search object + num_actions : integer + The number of actions with the object can be initialized with + + Returns + ------- + + self : SearchTask + + See Also + -------- + + pyvw.vw + + """ + self.vw = vw self.sch = sch self.bogus_example = [self.vw.example("1 | x")] @@ -40,27 +61,109 @@ def run(): self.bogus_example) # this will cause our ._run hook to get called def learn(self, data_iterator): - """Train search task by providing an iterator of examples""" + """Train search task by providing an iterator of examples. + + Parameters + ---------- + + data_iterator: iterable objects + Consists of examples to be learned + + Returns + ------- + + self : SearchTask + + """ for my_example in data_iterator.__iter__(): self._call_vw(my_example, isTest=False) def example(self, initStringOrDict=None, labelType=pylibvw.vw.lDefault): - """Create an example - initStringOrDict can specify example as VW formatted string, or a dictionary - labelType can specify the desire label type""" + """Create an example initStringOrDict can specify example as VW + formatted string, or a dictionary labelType can specify the desire + label type + + Parameters + ---------- + + initStringOrDict : str/dict + Example in either string or dictionary form + labelType : integer + - 0 : lDEFAULT + - 1 : lBINARY + - 2 : lMULTICLASS + - 3 : lCOST_SENSITIVE + - 4 : lCONTEXTUAL_BANDIT + - 5 : lMAX + - 6 : lCONDITIONAL_CONTEXTUAL_BANDIT + The integer is used to map the corresponding labelType using the + above available options + + Returns + ------- + + out : Example + + """ if self.sch.predict_needs_example(): return self.vw.example(initStringOrDict, labelType) else: return self.vw.example(None, labelType) def predict(self, my_example, useOracle=False): - """Return prediction""" + """Predict on the example + + Parameters + ---------- + + my_example : Example + example used for prediction + useOracle : bool + + Returns + ------- + + out : integer + Prediction on the example + """ self._call_vw(my_example, isTest=True, useOracle=useOracle) return self._output def get_prediction(ec, prediction_type): - """Get specified type of prediction from example""" + """Get specified type of prediction from example + + Parameters + ---------- + + ec : Example + prediction_type : integer + - 0: pSCALAR + - 1: pSCALARS + - 2: pACTION_SCORES + - 3: pACTION_PROBS + - 4: pMULTICLASS + - 5: pMULTILABELS + - 6: pPROB + - 7: pMULTICLASSPROBS + - 8: pDECISION_SCORES + + Examples + -------- + + >>> from vowpalwabbit import pyvw + >>> import pylibvw + >>> vw = pyvw.vw(quiet=True) + >>> ex = vw.example('1 |a two features |b more features here') + >>> pyvw.get_prediction(ex, 0) + 0.0 + + Returns + ------- + + out : integer/list + Prediction according to parameter prediction_type + """ switch_prediction_type = { pylibvw.vw.pSCALAR: ec.get_simplelabel_prediction, pylibvw.vw.pSCALARS: ec.get_scalars, @@ -80,15 +183,31 @@ class vw(pylibvw.vw): object; you're probably best off using this directly and ignoring the pylibvw.vw structure entirely.""" def __init__(self, arg_str=None, **kw): - """Initialize the vw object. The (optional) argString is the - same as the command line arguments you'd use to run vw (eg,"--audit"). - you can also use key/value pairs as in: - pyvw.vw(audit=True, b=24, k=True, c=True, l2=0.001) - or a combination, for instance: - pyvw.vw("--audit", b=26) - value in a pair could also be a list of values, for instance: - pyvw.vw("-q", ["ab", "ac"]) - will be translated into passing two -q keys""" + """Initialize the vw object. + + Parameters + ---------- + + arg_str : str + The command line arguments to initialize VW with, + for example "--audit". By default is None. + + **kw : Using key/value pairs for different options available + + Examples + -------- + + >>> from vowpalwabbit import vw + >>> vw1 = pyvw.vw('--audit') + >>> vw2 = pyvw.vw(audit=True, b=24, k=True, c=True, l2=0.001) + >>> vw3 = pyvw.vw("--audit", b=26) + >>> vw4 = pyvw.vw("-q", ["ab", "ac"]) + + Returns + ------- + + self : vw + """ def format_input_pair(key, val): if type(val) is bool and not val: s = '' @@ -121,7 +240,45 @@ def format_input(key, val): def parse(self, str_ex, labelType=pylibvw.vw.lDefault): """Returns a collection of examples for a multiline example learner or a single - example for a single example learner.""" + example for a single example learner. + + Parameters + ---------- + + str_ex : str/list of str + string representing examples. If the string is multiline then each + line is considered as an example. In case of list, each string + element is considered as an example + labelType : integer + - 0 : lDEFAULT + - 1 : lBINARY + - 2 : lMULTICLASS + - 3 : lCOST_SENSITIVE + - 4 : lCONTEXTUAL_BANDIT + - 5 : lMAX + - 6 : lCONDITIONAL_CONTEXTUAL_BANDIT + The integer is used to map the corresponding labelType using the + above available options + + Examples + -------- + + >>> from vowpalwabbit import pyvw + >>> model = pyvw.vw(quiet=True) + >>> ex = model.parse("0:0.1:0.75 | a:0.5 b:1 c:2") + >>> len(ex) + 1 + >>> model = vw(quiet=True, cb_adf=True) + >>> ex = model.parse(["| a:1 b:0.5", "0:0.1:0.75 | a:0.5 b:1 c:2"]) + >>> len(ex) # Shows the multiline example is parsed + 2 + + Returns + ------- + + ec : list + list of examples parsed + """ if not (isinstance(str_ex, list) or isinstance(str_ex, str)): raise TypeError( 'Unsupported type. List or string object must be passed.') @@ -143,7 +300,14 @@ def parse(self, str_ex, labelType=pylibvw.vw.lDefault): return ec def finish_example(self, ex): - """Should only be used in conjunction with the parse method""" + """Should only be used in conjunction with the parse method + + Parameters + ---------- + + ex : Example + example to be finished + """ if isinstance(ex, example): if self._is_multiline(): @@ -168,14 +332,34 @@ def num_weights(self): return pylibvw.vw.num_weights(self) def get_weight(self, index, offset=0): - """Given an (integer) index (and an optional offset), return - the weight for that position in the (learned) weight vector.""" + """Get the weight at a particular position in the (learned) weight vector. + + Parameters + ---------- + + index : integer + position in the learned weight vector + offset : integer + By default is 0 + + Returns + ------- + + weight : float + Weight at the given index + + """ return pylibvw.vw.get_weight(self, index, offset) def learn(self, ec): - """Perform an online update; ec can either be an example - object or a string (in which case it is parsed and then - learned on) or list which is iterated over.""" + """Perform an online update + + Parameters + ---------- + + ec : example/str/list + examples on which the model gets updated + """ # If a string was given, parse it before passing to learner. new_example = False if isinstance(ec, str): @@ -197,11 +381,23 @@ def learn(self, ec): self.finish_example(ec) def predict(self, ec, prediction_type=None): - """Just make a prediction on this example; ec can either be an example - object or a string (in which case it is parsed and then predicted on). + """Just make a prediction on the example - if prediction_type is provided the matching return type is used - otherwise the the learner's prediction type will determine the output.""" + Parameters + ---------- + + ec : Example/list/str + examples to be predicted + prediction_type : optional, by default is None + if provided then the matching return type is + used otherwise the the learner's prediction type will determine the + output. + + Returns + ------- + + prediction : Prediction made on each examples + """ new_example = False if isinstance(ec, dict): @@ -251,7 +447,32 @@ def finish(self): self.finished = True def example(self, stringOrDict=None, labelType=pylibvw.vw.lDefault): - """TODO: document""" + """Create an example initStringOrDict can specify example as VW + formatted string, or a dictionary labelType can specify the desire + label type + + Parameters + ---------- + + initStringOrDict : str/dict + Example in either string or dictionary form + labelType : integer + - 0 : lDEFAULT + - 1 : lBINARY + - 2 : lMULTICLASS + - 3 : lCOST_SENSITIVE + - 4 : lCONTEXTUAL_BANDIT + - 5 : lMAX + - 6 : lCONDITIONAL_CONTEXTUAL_BANDIT + The integer is used to map the corresponding labelType using the + above available options + + Returns + ------- + + out : Example + + """ return example(self, stringOrDict, labelType) def __del__(self): @@ -266,38 +487,50 @@ def predict(examples, condition=None, allowed=None, learner_id=0): - """The basic (via-reduction) prediction mechanism. Several - variants are supported through this overloaded function: - - 'examples' can be a single example (interpreted as - non-LDF mode) or a list of examples (interpreted as - LDF mode). it can also be a lambda function that - returns a single example or list of examples, and in - that list, each element can also be a lambda function - that returns an example. this is done for lazy - example construction (aka speed). - - 'my_tag' should be an integer id, specifying this prediction - - 'oracle' can be a single label (or in LDF mode a single - array index in 'examples') or a list of such labels if - the oracle policy is indecisive; if it is None, then - the oracle doesn't care - - 'condition' should be either: (1) a (tag,char) pair, indicating - to condition on the given tag with identifier from the char; - or (2) a (tag,len,char) triple, indicating to condition on - tag, tag-1, tag-2, ..., tag-len with identifiers char, - char+1, char+2, ..., char+len. or it can be a (heterogenous) - list of such things. - - 'allowed' can be None, in which case all actions are allowed; - or it can be list of valid actions (in LDF mode, this should - be None and you should encode the valid actions in 'examples') - - 'learner_id' specifies the underlying learner id - - Returns a single prediction. + """The basic (via-reduction) prediction mechanism + + Parameters + ---------- + + examples : Example/list + can be a single example (interpreted as + non-LDF mode) or a list of examples (interpreted as + LDF mode). it can also be a lambda function that + returns a single example or list of examples, and in + that list, each element can also be a lambda function + that returns an example. this is done for lazy + example construction (aka speed). + + my_tag : integer + should be an integer id, specifying this prediction + + oracle : label/list + can be a single label (or in LDF mode a single + array index in 'examples') or a list of such labels if + the oracle policy is indecisive; if it is None, then + the oracle doesn't care + + condition : Optional, by default is None + should be either: (1) a (tag,char) pair, indicating + to condition on the given tag with identifier from the char; + or (2) a (tag,len,char) triple, indicating to condition on + tag, tag-1, tag-2, ..., tag-len with identifiers char, + char+1, char+2, ..., char+len. or it can be a (heterogenous) + list of such things. + + allowed : optional, by default id None + can be None, in which case all actions are allowed; + or it can be list of valid actions (in LDF mode, this should + be None and you should encode the valid actions in 'examples') + + learner_id : integer + specifies the underlying learner id + + Returns + ------- + + out : integer + a single prediction. """ P = sch.get_predictor(my_tag) @@ -397,10 +630,23 @@ class namespace_id(): in a particular example. Mostly used internally, you shouldn't really need to touch this.""" def __init__(self, ex, id): - """Given an example and an id, construct a namespace_id. The - id can either be an integer (in which case we take it to be an - index into ex.indices[]) or a string (in which case we take - the first character as the namespace id).""" + """Given an example and an id, construct a namespace_id. + + Parameters + ---------- + + ex : Example + example used to create a namespace id + id : integer/str + The id can either be an integer (in which case we take it to be an + index into ex.indices[]) or a string (in which case we take + the first character as the namespace id). + + Returns + ------- + + self : namespace_id + """ if isinstance(id, int): # you've specified a namespace by index if id < 0 or id >= ex.num_namespaces(): raise Exception('namespace ' + str(id) + ' out of bounds') @@ -426,10 +672,25 @@ class example_namespace(): indexing like ex['x'][0] to get the 0th feature in namespace 'x' in example ex.""" def __init__(self, ex, ns, ns_hash=None): - """Construct an example_namespace given an example and a - target namespace (ns should be a namespace_id)""" + """Construct an example_namespace + + Parameters + ---------- + + ex : Example + examples from which namespace is to be extracted + ns : namespace_id + Target namespace + ns_hash : Optional, by default is None + The hash of the namespace + + Returns + ------- + + self : example_namespace + """ if not isinstance(ns, namespace_id): - raise TypeError + raise TypeError("ns should an instance of namespace_id.") self.ex = ex self.ns = ns self.ns_hash = None @@ -452,7 +713,17 @@ def iter_features(self): def push_feature(self, feature, v=1.): """Add an unhashed feature to the current namespace (fails if - setup has already run on this example).""" + setup has already run on this example). + + Parameters + ---------- + + feature : integer/str + Feature to be pushed to current namespace + v : float + Feature value, by default is 1.0 + + """ if self.ns_hash is None: self.ns_hash = self.ex.vw.hash_space(self.ns) self.ex.push_feature(self.ns, feature, v, self.ns_hash) @@ -464,11 +735,19 @@ def pop_feature(self): return self.ex.pop_feature(self.ns) def push_features(self, ns, featureList): - """Push a list of features to a given namespace. Each feature - in the list can either be an integer (already hashed) or a - string (to be hashed) and may be paired with a value or not - (if not, the value is assumed to be 1.0). See example.push_features - for examples.""" + """Push a list of features to a given namespace. + + Parameters + ---------- + + ns : namespace + namespace to which feature list is to be pushed + featureList : list + Each feature in the list can either be an integer (already hashed) + or a string (to be hashed) and may be paired with a value or not + (if not, the value is assumed to be 1.0). + See example.push_features for examples. + """ self.ex.push_features(self.ns, featureList) @@ -604,7 +883,9 @@ def __init__(self, **kwargs): if kwargs.get('label', False): action = kwargs['label'] - warnings.warn("label has been deprecated. Please use 'action' instead.", DeprecationWarning) + warnings.warn( + "label has been deprecated. Please use 'action' instead.", + DeprecationWarning) self.label = action self.action = action self.cost = cost @@ -620,7 +901,8 @@ def __init__(self, self.costs.append(wc) def __str__(self): - return ' '.join(["{}:{}:{}".format(c.action, c.cost, c.probability) for c in self.costs]) + return ' '.join(["{}:{}:{}".format(c.action, c.cost, c.probability) + for c in self.costs]) class example(pylibvw.example): @@ -632,13 +914,44 @@ def __init__(self, vw, initStringOrDictOrRawExample=None, labelType=pylibvw.vw.lDefault): - """Construct a new example from vw. If initString is None, you - get an "empty" example which you can construct by hand (see, eg, - example.push_features). If initString is a string, then this - string is parsed as it would be from a VW data file into an - example (and "setup_example" is run). if it is a dict, then we add all features in that dictionary. - finally, if it's a function, we (repeatedly) execute it fn() until it's not a function any more - (for lazy feature computation).""" + """Construct a new example from vw. + + Parameters + ---------- + + vw : vw + vw model + initStringOrDictOrRawExample : dict/string/None + If initString is None, you get an "empty" example which you + can construct by hand (see, eg, example.push_features). + If initString is a string, then this string is parsed as + it would be from a VW data file into an example (and + "setup_example" is run). if it is a dict, then we add all + features in that dictionary. finally, if it's a function, + we (repeatedly) execute it fn() until it's not a function + any more(for lazy feature computation). By default is None + labelType : integer + - 0 : lDEFAULT + - 1 : lBINARY + - 2 : lMULTICLASS + - 3 : lCOST_SENSITIVE + - 4 : lCONTEXTUAL_BANDIT + - 5 : lMAX + - 6 : lCONDITIONAL_CONTEXTUAL_BANDIT + The integer is used to map the corresponding labelType using the + above available options + + Returns + ------- + + self : Example + + See Also + -------- + + pyvw.vw + + """ while hasattr(initStringOrDictOrRawExample, '__call__'): initStringOrDictOrRawExample = initStringOrDictOrRawExample() @@ -671,8 +984,21 @@ def __init__(self, self.labelType = labelType def get_ns(self, id): - """Construct a namespace_id from either an integer or string - (or, if a namespace_id is fed it, just return it directly).""" + """Construct a namespace_id + + Parameters + ---------- + + id : namespace_id/str/integer + id used to create namespace + + Returns + ------- + + out : namespace_id + namespace_id created using parameter passed(if id was namespace_id, + just return it directly) + """ if isinstance(id, namespace_id): return id else: @@ -684,8 +1010,23 @@ def __getitem__(self, id): return example_namespace(self, self.get_ns(id)) def feature(self, ns, i): - """Get the i-th hashed feature id in a given namespace (i can - range from 0 to self.num_features_in(ns)-1)""" + """Get the i-th hashed feature id in a given namespace + + Parameters + ---------- + + ns : namespace + namespace used to get the feature + i : integer + to get i-th hashed feature id in a given ns. It must range from + 0 to self.num_features_in(ns)-1 + + Returns + ------- + + f : integer + i-th hashed feature-id in a given ns + """ ns = self.get_ns(ns) # guaranteed to be a single character f = pylibvw.example.feature(self, ns.ord_ns, i) if self.setup_done: @@ -693,14 +1034,35 @@ def feature(self, ns, i): return f def feature_weight(self, ns, i): - """Get the value(weight) associated with a given feature id in - a given namespace (i can range from 0 to - self.num_features_in(ns)-1)""" + """Get the value(weight) associated with a given feature id + + Parameters + ---------- + + ns : namespace + namespace used to get the feature id + i : integer + to get the weight of i-th feature in the given ns. It must range + from 0 to self.num_features_in(ns)-1 + + Returns + ------- + + out : float + weight(value) of the i-th feature of given ns + """ return pylibvw.example.feature_weight(self, self.get_ns(ns).ord_ns, i) def set_label_string(self, string): - """Give this example a new label, formatted as a string (ala - the VW data file format).""" + """Give this example a new label + + Parameters + ---------- + + string : str + a new label to this example, formatted as a string (ala the VW data + file format) + """ pylibvw.example.set_label_string(self, self.vw, string, self.labelType) def setup_example(self): @@ -708,15 +1070,16 @@ def setup_example(self): features constructed, etc.), do so.""" if self.setup_done: raise Exception( - 'trying to setup_example on an example that is already setup') + 'Trying to setup_example on an example that is already setup') self.vw.setup_example(self) self.setup_done = True def unsetup_example(self): - """If this example has been setup, reverse that process so you can continue editing the examples.""" + """If this example has been setup, reverse that process so you can + continue editing the examples.""" if not self.setup_done: raise Exception( - 'trying to unsetup_example that has not yet been setup') + 'Trying to unsetup_example that has not yet been setup') self.vw.unsetup_example(self) self.setup_done = False @@ -728,21 +1091,66 @@ def learn(self): self.vw.learn(self) def sum_feat_sq(self, ns): - """Return the total sum feature-value squared for a given - namespace.""" + """Get the total sum feature-value squared for a given + namespace + + Parameters + ---------- + + ns : namespace + Get the total sum feature-value squared of this namespace + + Returns + ------- + + sum_sq : float + Total sum feature-value squared of the given ns + """ return pylibvw.example.sum_feat_sq(self, self.get_ns(ns).ord_ns) def num_features_in(self, ns): - """Return the total number of features in a given namespace.""" + """Get the total number of features in a given namespace + + Parameters + ---------- + + ns : namespace + Get the total features of this namespace + + Returns + ------- + + num_features : integer + Total number of features in the given ns + """ return pylibvw.example.num_features_in(self, self.get_ns(ns).ord_ns) def get_feature_id(self, ns, feature, ns_hash=None): - """Return the hashed feature id for a given feature in a given + """Get the hashed feature id for a given feature in a given namespace. feature can either be an integer (already a feature - id) or a string, in which case it is hashed. Note that if - --hash all is on, then get_feature_id(ns,"5") != + id) or a string, in which case it is hashed. + + Parameters + ---------- + + ns : namespace + namespace used to get the feature + feature : integer/string + If integer the already a feature else will be hashed + ns_hash : Optional, by default is None + The hash of the namespace + + Returns + ------- + + out : integer + Hashed feature id + + .. note:: + If --hash all is on, then get_feature_id(ns,"5") != get_feature_id(ns, 5). If you've already hashed the namespace, - you can optionally provide that value to avoid re-hashing it.""" + you can optionally provide that value to avoid re-hashing it. + """ if isinstance(feature, int): return feature if isinstance(feature, str): @@ -753,56 +1161,127 @@ def get_feature_id(self, ns, feature, ns_hash=None): str(type(feature))) def push_hashed_feature(self, ns, f, v=1.): - """Add a hashed feature to a given namespace.""" + """Add a hashed feature to a given namespace. + + Parameters + ---------- + + ns : namespace + namespace in which the feature is to be pushed + f : integer + feature + v : float + The value of the feature, be default is 1.0 + """ if self.setup_done: self.unsetup_example() pylibvw.example.push_hashed_feature(self, self.get_ns(ns).ord_ns, f, v) def push_feature(self, ns, feature, v=1., ns_hash=None): - """Add an unhashed feature to a given namespace.""" + """Add an unhashed feature to a given namespace + + Parameters + ---------- + + ns : namespace + namespace in which the feature is to be pushed + f : integer + feature + v : float + The value of the feature, be default is 1.0 + ns_hash : Optional, by default is None + The hash of the namespace + """ f = self.get_feature_id(ns, feature, ns_hash) self.push_hashed_feature(ns, f, v) def pop_feature(self, ns): - """Remove the top feature from a given namespace; returns True - if a feature was removed, returns False if there were no - features to pop.""" + """Remove the top feature from a given namespace + + Parameters + ---------- + + ns : namespace + namespace from which feature is popped + + Returns + ------- + + out : bool + True if feature was removed else False as no feature was there to + pop + """ if self.setup_done: self.unsetup_example() return pylibvw.example.pop_feature(self, self.get_ns(ns).ord_ns) def push_namespace(self, ns): - """Push a new namespace onto this example. You should only do - this if you're sure that this example doesn't already have the - given namespace.""" + """Push a new namespace onto this example. + You should only do this if you're sure that this example doesn't + already have the given namespace + + Parameters + ---------- + + ns : namespace + namespace which is to be pushed onto example + + """ if self.setup_done: self.unsetup_example() pylibvw.example.push_namespace(self, self.get_ns(ns).ord_ns) def pop_namespace(self): - """Remove the top namespace from an example; returns True if a - namespace was removed, or False if there were no namespaces - left.""" + """Remove the top namespace from an example + + Returns + ------- + + out : bool + True if namespace was removed else False as no namespace was there + to pop + """ if self.setup_done: self.unsetup_example() return pylibvw.example.pop_namespace(self) def ensure_namespace_exists(self, ns): - """Check to see if a namespace already exists. If it does, do - nothing. If it doesn't, add it.""" + """Check to see if a namespace already exists. + + Parameters + ---------- + + ns : namespace + If namespace exists does, do nothing. If it doesn't, add it. + """ if self.setup_done: self.unsetup_example() return pylibvw.example.ensure_namespace_exists(self, self.get_ns(ns).ord_ns) def push_features(self, ns, featureList): - """Push a list of features to a given namespace. Each feature - in the list can either be an integer (already hashed) or a - string (to be hashed) and may be paired with a value or not - (if not, the value is assumed to be 1.0). - - Examples: - ex.push_features('x', ['a', 'b']) - ex.push_features('y', [('c', 1.), 'd']) - - space_hash = vw.hash_space( 'x' ) - feat_hash = vw.hash_feature( 'a', space_hash ) - ex.push_features('x', [feat_hash]) # note: 'x' should match the space_hash! + """Push a list of features to a given namespace. + + Parameters + ---------- + + ns : namespace + namespace in which the features are pushed + featureList : list + Each feature in the list can either be an integer + (already hashed) or a string (to be hashed) and may be + paired with a value or not (if not, the value is assumed to be 1.0 + + Examples + -------- + + >>> from vowpalwabbit import pyvw + >>> vw = pyvw.vw(quiet=True) + >>> ex = vw.example('1 |a two features |b more features here') + >>> ex.push_features('x', ['a', 'b']) + >>> ex.push_features('y', [('c', 1.), 'd']) + >>> space_hash = vw.hash_space('x') + >>> feat_hash = vw.hash_feature('a', space_hash) + >>> ex.push_features('x', [feat_hash]) #'x' should match the space_hash! + >>> ex.num_features_in('x') + 3 + >>> ex.num_features_in('y') + 2 """ ns = self.get_ns(ns) self.ensure_namespace_exists(ns) @@ -813,11 +1292,14 @@ def push_features(self, ns, featureList): # if isinstance(feature, int) or isinstance(feature, str): # f = feature # v = 1. - # elif isinstance(feature, tuple) and len(feature) == 2 and (isinstance(feature[0], int) or isinstance(feature[0], str)) and (isinstance(feature[1], int) or isinstance(feature[1], float)): + # elif isinstance(feature, tuple) and len(feature) == 2 and + # (isinstance(feature[0], int) or isinstance(feature[0], str)) + # and (isinstance(feature[1], int) or isinstance(feature[1], float)): # f = feature[0] # v = feature[1] # else: - # raise Exception('malformed feature to push of type: ' + str(type(feature))) + # raise Exception('malformed feature to push of type: ' + # + str(type(feature))) # self.push_feature(ns, f, v, ns_hash) def iter_features(self): @@ -833,5 +1315,13 @@ def iter_features(self): def get_label(self, label_class=simple_label): """Given a known label class (default is simple_label), get - the corresponding label structure for this example.""" + the corresponding label structure for this example. + + Parameters + ---------- + + label_class : label classes + Get the label of the example of label_class type, by default is + simple_label + """ return label_class(self)