@Test
  public void testSnapshot() throws RecommenderBuildException {
    List<Rating> rs = new ArrayList<Rating>();
    rs.add(Ratings.make(1, 5, 2));
    rs.add(Ratings.make(1, 7, 4));
    rs.add(Ratings.make(8, 4, 5));
    rs.add(Ratings.make(8, 5, 4));

    EventDAO dao = EventCollectionDAO.create(rs);

    LenskitConfiguration config = new LenskitConfiguration();
    config.bind(EventDAO.class).to(dao);
    config.bind(ItemScorer.class).to(UserUserItemScorer.class);
    config.bind(NeighborFinder.class).to(SnapshotNeighborFinder.class);

    LenskitRecommenderEngine engine = LenskitRecommenderEngine.build(config);
    Recommender rec = engine.createRecommender();
    assertThat(rec.getItemScorer(), instanceOf(UserUserItemScorer.class));
    assertThat(rec.getItemRecommender(), instanceOf(TopNItemRecommender.class));
    RatingPredictor pred = rec.getRatingPredictor();
    assertThat(pred, instanceOf(SimpleRatingPredictor.class));

    Recommender rec2 = engine.createRecommender();
    assertThat(rec2.getItemScorer(), not(sameInstance(rec.getItemScorer())));
  }
  @Before
  public void createRatingSource() {
    List<Rating> rs = new ArrayList<Rating>();
    rs.add(Ratings.make(1, 5, 2));
    rs.add(Ratings.make(1, 7, 4));
    rs.add(Ratings.make(8, 4, 5));
    rs.add(Ratings.make(8, 5, 4));

    dao = EventCollectionDAO.create(rs);
  }
  /**
   * Build a rating matrix from the rating data. Each user's ratings are first normalized by
   * subtracting a baseline score (usually a mean).
   *
   * @param userMapping The index mapping of user IDs to column numbers.
   * @param itemMapping The index mapping of item IDs to row numbers.
   * @return A matrix storing the <i>normalized</i> user ratings.
   */
  private RealMatrix createRatingMatrix(IdIndexMapping userMapping, IdIndexMapping itemMapping) {
    final int nusers = userMapping.size();
    final int nitems = itemMapping.size();

    // Create a matrix with users on rows and items on columns
    logger.info("creating {} by {} rating matrix", nusers, nitems);
    RealMatrix matrix = MatrixUtils.createRealMatrix(nusers, nitems);

    // populate it with data
    Cursor<UserHistory<Event>> users = userEventDAO.streamEventsByUser();
    try {
      for (UserHistory<Event> user : users) {
        // Get the row number for this user
        int u = userMapping.getIndex(user.getUserId());
        MutableSparseVector ratings = Ratings.userRatingVector(user.filter(Rating.class));
        MutableSparseVector baselines = MutableSparseVector.create(ratings.keySet());
        baselineScorer.score(user.getUserId(), baselines);
        // TODO Populate this user's row with their ratings, minus the baseline scores
        for (VectorEntry entry : ratings.fast(State.SET)) {
          long itemid = entry.getKey();
          int i = itemMapping.getIndex(itemid);
          double rating = entry.getValue();
          double baseline = baselines.get(itemid);
          matrix.setEntry(u, i, rating - baseline);
        }
      }
    } finally {
      users.close();
    }

    return matrix;
  }
  @SuppressWarnings("deprecation")
  @Before
  public void setup() throws RecommenderBuildException {
    List<Rating> rs = new ArrayList<Rating>();
    rs.add(Ratings.make(1, 5, 2));
    rs.add(Ratings.make(1, 7, 4));
    rs.add(Ratings.make(8, 4, 5));
    rs.add(Ratings.make(8, 5, 4));

    EventDAO dao = new EventCollectionDAO(rs);

    LenskitConfiguration config = new LenskitConfiguration();
    config.bind(EventDAO.class).to(dao);
    config.bind(ItemScorer.class).to(UserUserItemScorer.class);
    config.bind(NeighborFinder.class).to(LiveNeighborFinder.class);

    engine = LenskitRecommenderEngine.build(config);
  }
 @Override
 public Rating copy(Rating r) {
   return Ratings.copyBuilder(r).build();
 }