Lenskit Versions Save

LensKit recommender toolkit.

lenskit-3.0-M2

7 years ago

lenskit-3.0-M1

7 years ago

lenskit-2.2.1

8 years ago

Bugfix release for LensKit 2.2, fixing #804.

lenskit-3.0-T2

8 years ago

Second release in the 3.0 Teaching series.

lenskit-2.2

9 years ago

LensKit 2.2, see the release notes.

lenskit-2.2-M4

9 years ago

This is the fourth milestone release for LensKit 2.2.

  • supports MovieLens 20M data set (and other data sets with header lines)
  • supports item names with ItemNameDAO
  • redesign item-item CF model to improve performance without fast iteration
  • some other fixes and improvements

lenskit-2.2-M3

9 years ago

The third milestone release for LensKit 2.2.

lenskit-2.1

9 years ago

The LensKit 2.1 release.

lenskit-2.0-M1

10 years ago

Today sees the release of the first milestone for LensKit 2.0 (2.0-M1). LensKit 2.0 will feature a number of cleaned up (and often simplified!) APIs. Unfortunately, that comes at the expense of backwards compatibility; projects using LensKit will need notable upgrades for LensKit 2.0.

The release notes contain a number of the changes; the change log is the definitive source of change information.

Data Structure Cleanup

We've cleaned up the side channel API for sparse vectors and scored IDs; side channels with unboxed doubles (for scored IDs) and side channel vectors (for sparse vectors) are now conceptually special cases of general-purpose side channels storing arbitrary, type-safe data.

We have also made the way you construct data structures more consistent. All data structure classes now have static factory methods and/or builders; public constructors are deprecated. In Effective Java, Joshua Bloch makes a good case for this being a better way of constructing objects, and it is confusing to construct some objects using constructors and others using factory methods. So all the classes in lenskit-data-structures have been updated to consistently use factory methods.

We have also deprecated a number of classes that are no longer needed, or at least not needed much. LongCursor is going away (see the next section), as are pointers.

Finally, we've done some under-the-hood improvements on sparse vectors to improve code reuse. Maintaining them is much more pleasant now.

New DAO infrastructure

LensKit 1.x had a monolithic Data Access Object that everything used to get access to data. This, combined with DAOFactory objects, made for some unhelpful complexity: you had to manage factories, writing wrapper DAOs was difficult, and there were a lot of methods to implement in a DAO.

In LensKit 2.0, DAOs have been completely restructured. There are now multiple DAO interfaces for different types of data and different access patterns. The base DAO, EventDAO, provides streaming access to events using a Cursor. There are several related DAOs, such as UserEventDAO that allows events to be queried by user, and ItemEventDAO to query by item. The default implementations of these DAOs stream all events into memory and store them in a map keyed by user or item. If you want to write your own DAO, you can implement the very simple interface in EventDAO and get the remaining required behavior easily (albeit somewhat inefficiently).

LensKit integrators can now implement each of the interfaces against their database, either in separate objects or in a single DAO that implements all available interfaces. The DAO implementation can also be configured via dependency injection; it is no longer special-cased using the DAO factory.

Components can now depend on just the DAO interfaces they need. And if no components use some DAO functionality, you no longer have to implement it in your custom DAO, without violating interface expectations.

Note that DAOs are expected to be fast: a custom UserEventDAO implementation should probably cache user histories. It's intended that new DAO instances will be constructed for each recommender session now, though, so you can easily do per-request caching simply by caching in the instance. This is important, as the user's history may be requested multiple times while servicing the same request.

If you need to build and use the recommender with different DAOs, it's a bit tricky right now. The way it is supported will be greatly improved for the final release of LensKit 2.0.

Simplified component interfaces

Several core component interfaces are now simpler. We've removed the deprecated inheritance relationship between RatingPredictor and ItemScorer. We've also removed all methods from the predictors, scorers, and recommenders that take a user history: the component is expected to get the history, if it needs it, from the UserEventDAO. This depends on fast, caching DAOs, but makes the interfaces simpler to implement and code to. The number of methods is now cut in half on many of these interfaces.

Have fun!

We hope LensKit 2.0 will be the easiest-to-use version of LensKit yet, but it's still a work-in-progress. But if you're feeling adventurous, please try it out, report bugs, and give us feedback on the mailing list. You can also watch our issue list for some of the things we have left to do.

It's also pushed to Maven Central.

lenskit-2.0

10 years ago

We are pleased to announce the release of LensKit 2.0. LensKit features a number of cleaned up and simplified APIs, some of which break backwards compatibility.

As usual, you can find a change-oriented summary in the release notes.

Most of the changes were announced with LensKit 2.0 M1. In addition, we've made the following API-breaking changes:

Baseline predictors are item scorers

We removed the BaselinePredictor interface, in favor of having baseline predictors just implement ItemScorer. There's now a @BaselineScorer qualifier that indicates that a particular item scorer will be used in a baseline capacity. SimpleRatingPredictor still uses a baseline scorer as a fallback for the primary item scorer, and FallbackItemScorer replaces BaselineItemScorer for implementing a general stack of two scorers, with a baseline providing defaults in case a primary fails.

Any configuration using a baseline scorer will need to change. For example, to use the user-mean scorer:

config.bind(BaselineScorer.class, ItemScorer.class)
      .to(UserMeanItemScorer.class);

All baseline scorers have changed their names:

  • ItemMeanPredictor is now ItemMeanRatingItemScorer
  • GlobalMeanPredictor is now GlobalMeanRatingItemScorer
  • ConstantPredictor is now ConstantItemScorer
  • UserMeanPredictor is now UserMeanItemScorer

ItemUserMeanPredictor removed

The ItemUserMeanPredictor has been removed completely. Its functionality has been replaced by allowing the user-mean item scorer to use an arbitrary baseline for averaging user offsets; this is controlled by an ItemScorer dependency qualified with UserMeanBaseline. So, if you used to use an ItemUserMeanPredictor, now do this:

config.bind(BaselineScorer.class, ItemScorer.class)
      .to(UserMeanItemScorer.class);
config.bind(UserMeanBaseline.class, ItemScorer.class)
      .to(ItemMeanRatingItemScorer.class);

Deprecated APIs removed

Almost all deprecated APIs have been removed. This includes many deprecated APIs in the data structures module. To ease the transition, we released 2.0-M2 prior to removing many deprecated APIs; you can update your code to 2.0-M2, fix all deprecation warnings, and then update to the final 2.0 release.

Have fun!

We hope you enjoy using this version of LensKit. If you have problems, please raise them on the mailing list or report bugs.