Release 0.4

The Mercurial changelog and the list of closed tickets provide more information on what has happened, including bugs that have been fixed.

Recommendation and Prediction API

To support more types of recommenders easily, we have changed the way the dynamic recommendation and prediction components and their APIs work (#109, #110). These changes are backwards-incompatible; client code and implementations need to be updated for 0.4.

  • Introduced ItemScorer, an generalization of prediction that scores items for users.
  • Made RatingPredictor an ItemScorer, and deleted its predict(...) methods in favor of the item scorer methods. It now serves as a type-level indicator that a scorer returns predicted preferences as scores.
  • Removed dynamic interfaces in favor of putting the history-based methods directly in the ItemScorer and ItemRecommender interfaces. An added canUseHistory() method on each interface indicates whether the history will be used or ignored. This greatly simplifies the inheritence hierarchy for recommender components.
  • Changed the behavior of item recommenders when a null exclude set is provided. Previously, this was equivalent to the empty set. It is now equivalent to a default exclude set which will be recommender-specific but generally a set of items the user is unlikely to need recommended (such as all items they have rated). All recommenders have been updated with this change.

    The old design was easier to slightly implement but made less sense from a client API perspective. The new design, where null is the default exclude set, makes the API cleaner (the fully-general method can use default exclude sets). The loosened specification of default exclude sets also gives us greater flexbility for LensKit to be used as a basis for novel recommendation approaches.

Incompatible data structure changes

To clean up APIs, we made a couple notable incompatible changes to layout and data structures. These are all compile errors; no subtle behavior changes that the compiler won't catch here.

  • Moved UserHistory and related classes to the org.grouplens.lenskit.data.history package.
  • Removed ItemRatingVector and UserRatingVector, as they type distinction severely complicates configuration for generalized model builders. The upside: types remain sane and configuring basket recommenders will be feasible. Downside: the type system doensn't indicate whether a user vector contains ratings or some other data.

Other Changes

  • Changed DynamicRatingPredictor.predict(long, Collection, Collection) to take a UserHistory of events rather than a collection of ratings.
  • Made abstract recommenders and predictors uniformly expose the DAO as a protected final field.
  • Added methods to DataAccessObject, with default implementations in the abstract implementation, to allow user history objects to be directly retrieved for given users.
  • Added snapshotting as an explicit concept to the data layer. DAOFactory now has a snapshot() method, which is supposed to return an immutable snapshot of the data for test/build purposes. Iterative algorithms still use rating snapshots, as they're faster and provide indexing, but this allows us to be more flexible in what kinds of data access recommender component builders can perform. Factory implementations now need to provide a snapshot method; this can be done by simply creating an event collection DAO from the events. Users with large data sets may want to use more exotic methods like database replication or transactions.

    The JDBCRatingDAO factory makes snapshotting configurable. By default, it assumes the database is unchanging; it can be configured to take an in-memory snapshot and return an EventCollectionDAO.