Skip to content

Buggy interaction in Learner.predict() when used via API #621

Description

@desilinguist

There's a bug in Learner.predict() that only surfaces via the API for probabilistic learners.

from skll import Learner
from skll.data import NDJReader

l = Learner('SGDClassifier', probability=True)
train_fs = NDJReader.for_path('examples/iris/train/example_iris_features.jsonlines').read() 
test_fs = NDJReader.for_path('examples/iris/test/example_iris_features.jsonlines').read()
l.train(train_fs, grid_search=False)

Now, if I want to get the most likely labels in memory but write out the class probabilities to disk, I can actually do it the way the API is written:

labels = learner.predict(test_fs, class_labels=True, prediction_prefix='blah')

Doing so actually raises the following error because we try to write out the probabilities even though we end up only computing labels in the code (due to class_labels being True):

/work/skll/skll/learner/__init__.py in predict(self, examples, prediction_prefix, append, class_labels)
   1448                     for example_id, class_probs in zip(example_ids, yhat):
   1449                         print('\t'.join([str(example_id)] +
-> 1450                                         [str(x) for x in class_probs]),
   1451                               file=predictionfh)
   1452                 else:

TypeError: 'numpy.int64' object is not iterable

We should either explicitly disallow this case (it's a little weird to want labels in memory but probabilities on disk) or fix the code so that this work correctly.

The latter would mean:

  1. If learner.probability is True, always write out probabilities else write out the class labels.
  2. If class_labels is True, return class labels else return the class indices.

Thoughts?

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions