🔥 Recommendations for Node.js using collaborative filtering
- Supports user-based and item-based recommendations
- Works with explicit and implicit feedback
- Uses high-performance matrix factorization
Run:
npm install disco-rec
Create a recommender
import { Recommender } from 'disco-rec';
const recommender = new Recommender();
If users rate items directly, this is known as explicit feedback. Fit the recommender with:
recommender.fit([
{userId: 1, itemId: 1, rating: 5},
{userId: 2, itemId: 1, rating: 3}
]);
IDs can be integers or strings
If users don’t rate items directly (for instance, they’re purchasing items or reading posts), this is known as implicit feedback. Leave out the rating.
recommender.fit([
{userId: 1, itemId: 1},
{userId: 2, itemId: 1}
]);
Each
userId
/itemId
combination should only appear once
Get user-based recommendations - “users like you also liked”
recommender.userRecs(userId);
Get item-based recommendations - “users who liked this item also liked”
recommender.itemRecs(itemId);
Use the count
option to specify the number of recommendations (default is 5)
recommender.userRecs(userId, 3);
Get predicted ratings for specific users and items
recommender.predict([{userId: 1, itemId: 2}, {userId: 2, itemId: 4}]);
Get similar users
recommender.similarUsers(userId);
Load the data
import { loadMovieLens } from 'disco-rec';
const data = await loadMovieLens();
Create a recommender and get similar movies
const recommender = new Recommender({factors: 20});
recommender.fit(data);
recommender.itemRecs('Star Wars (1977)');
Save recommendations to your database.
Alternatively, you can store only the factors and use a library like pgvector-node. See an example.
Disco uses high-performance matrix factorization.
- For explicit feedback, it uses stochastic gradient descent
- For implicit feedback, it uses coordinate descent
Specify the number of factors and epochs
new Recommender({factors: 8, epochs: 20});
If recommendations look off, trying changing factors
. The default is 8, but 3 could be good for some applications and 300 good for others.
Pass a validation set with:
recommender.fit(data, validationSet);
Collaborative filtering suffers from the cold start problem. It’s unable to make good recommendations without data on a user or item, which is problematic for new users and items.
recommender.userRecs(newUserId); // returns empty array
There are a number of ways to deal with this, but here are some common ones:
- For user-based recommendations, show new users the most popular items
- For item-based recommendations, make content-based recommendations
Get ids
recommender.userIds();
recommender.itemIds();
Get the global mean
recommender.globalMean();
Get factors
recommender.userFactors(userId);
recommender.itemFactors(itemId);
Thanks to LIBMF for providing high performance matrix factorization
View the changelog
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
To get started with development:
git clone https://github.com/ankane/disco-node.git
cd disco-node
npm install
npm test