🔥 Recommendations for Ruby, powered by cmfrec
- Supports side information 🎉
- Works with explicit and implicit feedback
- Uses high-performance matrix factorization
Add this line to your application’s Gemfile:
gem "cmfrec"
For Windows, also follow these instructions.
Create a recommender
recommender = Cmfrec::Recommender.new
If users rate items directly, this is known as explicit feedback. Fit the recommender with:
recommender.fit([
{user_id: 1, item_id: 1, rating: 5},
{user_id: 2, item_id: 1, rating: 3}
])
IDs can be integers, strings, or any other data type
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, or use a value like number of purchases, number of page views, or time spent on page:
recommender.fit([
{user_id: 1, item_id: 1, value: 1},
{user_id: 2, item_id: 1, value: 1}
])
Use
value
instead of rating for implicit feedback
Get recommendations for a user in the training data
recommender.user_recs(user_id)
Get recommendations for a new user
recommender.new_user_recs([
{item_id: 1, rating: 5},
{item_id: 2, rating: 3}
])
Use the count
option to specify the number of recommendations (default is 5)
recommender.user_recs(user_id, count: 3)
Get predicted ratings for specific users and items
recommender.predict([{user_id: 1, item_id: 2}, {user_id: 2, item_id: 4}])
Add side information about users, items, or both
user_info = [
{user_id: 1, cats: 1, dogs: 0},
{user_id: 2, cats: 2, dogs: 1}
]
item_info = [
{item_id: 1, genre_comedy: 1, genre_drama: 0},
{item_id: 2, genre_comedy: 0, genre_drama: 1}
]
recommender.fit(ratings, user_info: user_info, item_info: item_info)
Get recommendations for a new user with ratings and side information
ratings = [
{item_id: 1, rating: 5},
{item_id: 2, rating: 3}
]
recommender.new_user_recs(ratings, user_info: {cats: 0, dogs: 2})
Get recommendations with only side information
recommender.new_user_recs([], user_info: {cats: 0, dogs: 2})
Add this line to your application’s Gemfile:
gem "ngt"
Get similar users
recommender.similar_users(user_id)
Get similar items - “users who liked this item also liked”
recommender.similar_items(item_id)
Load the data
ratings, user_info, item_info = Cmfrec.load_movielens
Create a recommender and get predictions
recommender = Cmfrec::Recommender.new(factors: 20)
recommender.fit(ratings.first(80000), user_info: user_info, item_info: item_info)
recommender.predict(ratings.last(20000))
Ahoy is a great source for implicit feedback
views = Ahoy::Event.where(name: "Viewed post").group(:user_id).group_prop(:post_id).count
data =
views.map do |(user_id, post_id), count|
{
user_id: user_id,
item_id: post_id,
value: count
}
end
Create a recommender and get recommended posts for a user
recommender = Cmfrec::Recommender.new
recommender.fit(data)
recommender.user_recs(current_user.id)
Specify the number of factors and epochs
Cmfrec::Recommender.new(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.
Add implicit features
Cmfrec::Recommender.new(add_implicit_features: true)
Disable bias
Cmfrec::Recommender.new(user_bias: false, item_bias: false)
Data can be an array of hashes
[{user_id: 1, item_id: 1, rating: 5}, {user_id: 2, item_id: 1, rating: 3}]
Or a Rover data frame
Rover.read_csv("ratings.csv")
Store the recommender
json = recommender.to_json
File.write("recommender.json", json)
The serialized recommender includes user activity from the training data (to avoid recommending previously rated items), so be sure to protect it. You can save it to a file, database, or any other storage system, or use a tool like Trove. Also, user and item IDs should be integers or strings for this.
Load a recommender
json = File.read("recommender.json")
recommender = Cmfrec::Recommender.load_json(json)
Alternatively, you can store only the factors and use a library like Neighbor. See the examples for Disco, which has a similar API. For explicit feedback, you should disable the bias with this approach.
Get ids
recommender.user_ids
recommender.item_ids
Get the global mean
recommender.global_mean
Get the factors
recommender.user_factors
recommender.item_factors
Get the bias
recommender.user_bias
recommender.item_bias
On Windows, build the cmfrec C shared library and set:
Cmfrec.ffi_lib = "path/to/cmfrec.dll"
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/cmfrec-ruby.git
cd cmfrec-ruby
bundle install
bundle exec rake vendor:all
bundle exec rake test