@Override public void predict(long uid, @Nonnull MutableSparseVector predictions) { logger.debug("predicting {} items for {}", predictions.keyDomain().size(), uid); OrdRecModel params = new OrdRecModel(quantizer); SparseVector ratings = makeUserVector(uid, userEventDao); LongSet keySet = LongUtils.setUnion(ratings.keySet(), predictions.keyDomain()); MutableSparseVector scores = MutableSparseVector.create(keySet); itemScorer.score(uid, scores); params.train(ratings, scores); logger.debug("trained parameters for {}: {}", uid, params); Vector probabilities = Vector.createLength(params.getLevelCount()); Long2ObjectMap<IVector> distChannel = null; if (reportDistribution) { distChannel = predictions.addChannel(RATING_PROBABILITY_CHANNEL); } for (VectorEntry e : predictions.fast(VectorEntry.State.EITHER)) { long iid = e.getKey(); double score = scores.get(iid); params.getProbDistribution(score, probabilities); int mlIdx = probabilities.maxElementIndex(); predictions.set(e, quantizer.getIndexValue(mlIdx)); if (distChannel != null) { distChannel.put(e.getKey(), probabilities.immutable()); } } }
@Override public double similarity(SparseVector vec1, SparseVector vec2) { final double distance; // One of the vector is empty if (Scalars.isZero(vec1.norm()) || Scalars.isZero(vec2.norm())) { return Double.NaN; } LongSet ts = LongUtils.setUnion(vec1.keySet(), vec2.keySet()); MutableSparseVector v1 = MutableSparseVector.create(ts); v1.fill(0); v1.set(vec1); v1.multiply(1.0 / v1.norm()); v1.addScaled(vec2, -1.0 / vec2.norm()); distance = v1.norm(); return 1 - distance; }
@Override public boolean equals(Object o) { if (this == o) { return true; } else if (o instanceof SparseVector) { SparseVector vo = (SparseVector) o; int sz = size(); int osz = vo.size(); if (sz != osz) { return false; } else { if (!this.keySet().equals(vo.keySet())) { return false; // same keys } // we know that sparse vector values are always in key order. so just compare them. return this.values().equals(vo.values()); } } else { return false; } }
@Override public LongSet keySet() { return vector.keySet(); }