Check out the app on Heroku Explore the frontend repo
Drink This provides cocktail recommendations using a memory-based approach to collaborative filtering. We use the PyCall gem to import key Python libraries into our Rails app, including numpy
, pandas
, and sklearn
. This allows us, for example, to calculate similarity among users in our application with sci-kit learn's euclidean_distance
method and to use pandas DataFrames to manipulate data as we pass it through our recommendation engine. The recommendation model takes a user's rating history into account, identifies the closest 15% of users, then makes a recommendation to the requester based on what similar users have rated highly.
Check out our Wiki for more info.
gem faraday
gem active_model_serializer
gem figaro
gem pycall
gem numpy
gem pandas
We make use of three Python libraries commonly used in data science to construct our recommendation model: NumPy, pandas, and sci-kit learn (sklearn
here). In order to use these inside of a Rails application, we utilize a gem called PyCall
, which allows us to import and use these libraries, and by extension Python syntax and functions, within Ruby methods. The bulk of our model is constructed with Python, after converting an array of Ruby objects (Ratings) from our database into a pandas DataFrame in our Dataframeable module:
The sci-kit learn library gives us access to metrics
, which includes score functions, performance metrics and pairwise metrics and distance computations, and by extension pairwise
, from which we get the calculation of Euclidean distance. In Euclidean geometry, the Euclidean distance is the usual distance between two points (roughly, distance in multi-dimensional space), and this distance is measured as a line segment. In our model, we use the Euclidean distance to calculate, among users when compared to the current user, which users (the 15% of users in our database) is closest in preferences to the current user. This method enables our app to recommend an accurate cocktail to the current user based on the preferences of other similar users.
Some examples of this in action:
As the user base grows in our app (and thus our database of user ratings also grows), the recommendation model will become more accurate in providing a recommendation to a particular user that they will enjoy.
-
Fork and clone this repo
-
Install Python3 locally with shared libraries enabled. Detailed instructions for installing Python and the packages we rely on can be found in this Wiki article.
-
Bundle install
-
Configure API keys:
- Run
bundle exec figaro install
for Figaro to generate an application.yml file where secure information can be stored locally - Create an app and retrieve an API key from the Yelp Fusion API
- Sign up to get an API key for TheCocktailDB
- Run
NOTE: All endpoints require a user authorization token from OAuth
GET /recommendation
- User must have ratings prior to requesting a recommendation or the model will simply return a random cocktail
GET /cocktail/:id
- Includes: Name, image, recipe (ingredients and measurements), directions, user rating (if applicable)
- Requires a
cocktail_id
parameter
{
"data": {
"id": "11007",
"type": "cocktail",
"attributes": {
"name": "Margarita",
"thumbnail": "https://www.thecocktaildb.com/images/media/drink/5noda61589575158.jpg",
"glass": "Cocktail glass",
"recipe": [
"1 1/2 oz Tequila",
"1/2 oz Triple sec",
"1 oz Lime juice",
"Salt"
],
"instructions": "Rub the rim of the glass with the lime slice to make the salt stick to it. Take care to moisten only the outer rim and sprinkle the salt on it. The salt should present to the lips of the imbiber and never mix into the cocktail. Shake the other ingredients with ice, then carefully pour into the glass.",
"rating": 0
}
}
}
POST /cocktails/:id/rating
- Requires
stars
parameter - Stars parameter must be an integer from 1-5
{
"data": {
"id": "701",
"type": "cocktail_rating",
"attributes": {
"user_id": 7,
"cocktail_id": 11007,
"stars": 4
}
}
}
GET /dashboard
GET /search
- Requires a
name
parameter with a string or string fragment to search
GET /search/yelp
To run the full test suite, simply run bundle exec rspec
.
Gems required for testing:
Since this Rails app also requires Python, both this Ruby buildpack and this Python buildpack are required for deploying to Heroku. The Python buildpack must be ordered before the Ruby buildpack. The Python buildpack includes a built in post compile hook, which will run the bin/post_compile
script included in this app to ensure that Python is built with shared libraries enabled. This is required for your local environment as well. We have written some basic instructions for installing Python, but these may not work for all environments. The app requires Python 3.9.6 configred with shared libraries enabled on install.
- Implement GraphQL
- Using the microservices approach on python, instead of using PyCall
- Implement Docker
- Update the recommendation model to a model-based approach using Python's ML libraries