www.mongodb.com
Open in
urlscan Pro
2600:9000:2127:1400:7:7859:3840:93a1
Public Scan
Submitted URL: https://email.mongodb.com/u/click?_t=86ba93b39a0e415ea7cd8e8ed81051cd&_m=22da38678a114318b4d9dd3fef097039&_e=9XQUFk_3AJD2v...
Effective URL: https://www.mongodb.com/developer/code-examples/python/song-recommendations-example-app/
Submission: On April 27 via manual from US — Scanned from DE
Effective URL: https://www.mongodb.com/developer/code-examples/python/song-recommendations-example-app/
Submission: On April 27 via manual from US — Scanned from DE
Form analysis
2 forms found in the DOMGET https://developer.mongodb.com/learn#main
<form role="search" method="GET" action="https://developer.mongodb.com/learn#main" class="css-dc0gsv">
<div class="css-87svlz">
<div class="css-36i4c2"><input type="text" placeholder="Search articles and topics..." class="css-etrcff" value=""></div>
<div class="css-v2nqhr">
<div class="css-aef77t"><button role="label" type="button" class="css-14k7wrz"><span data-testid="selected-value" class="css-6k4l2y">Developer Articles & Topics</span>
<div class="css-109dpaz"><svg data-testid="icon" width="16" height="9" viewBox="0 0 16 9" fill="none" xmlns="http://www.w3.org/2000/svg" class="css-1yzkxhp">
<path d="M1.06689 0.799988L8.00023 7.73332L14.9336 0.799988" stroke-linecap="round" stroke-linejoin="round" class="css-1tlq8q9"></path>
</svg></div>
</button>
<div class="css-hn9qqo">
<ul data-testid="options" role="listbox" class="css-ac9zo2">
<li role="option" tabindex="0" class="css-11dtrvq">General Information</li>
<li role="option" tabindex="0" class="css-11dtrvq">All Documentation</li>
<li role="option" tabindex="0" class="css-11dtrvq">Realm Documentation</li>
<li role="option" tabindex="0" class="css-11dtrvq">Developer Articles & Topics</li>
<li role="option" tabindex="0" class="css-11dtrvq">Community Forums</li>
<li role="option" tabindex="0" class="css-11dtrvq">Blog</li>
<li role="option" tabindex="0" class="css-11dtrvq">University</li>
</ul>
</div>
</div><input type="hidden" id="text" name="text" value=""><input type="hidden" id="content" name="content" value="Articles">
<div class="css-1myrko"><button type="submit" tabindex="0" class=" css-13l1z36" data-track="true"><img alt="search icon" src="https://webimages.mongodb.com/_com_assets/cms/krc3hljsdwdfd2w5d-web-actions-search.svg?auto=format%252Ccompress"
class="css-r9fohf"></button></div>
</div>
</div>
</form>
GET https://developer.mongodb.com/learn#main
<form role="search" method="GET" action="https://developer.mongodb.com/learn#main" class="css-11a71ad">
<div class="css-7590ag"><input type="text" placeholder="Search articles and topics..." class="css-xrkki1" value=""></div>
<div class="css-abpu8v"><select class="select-overlay css-15v6p12" id="filter-select">
<option value="General Information">General Information</option>
<option value="All Documentation">All Documentation</option>
<option value="Realm Documentation">Realm Documentation</option>
<option selected="" value="Developer Articles & Topics">Developer Articles & Topics</option>
<option value="Community Forums">Community Forums</option>
<option value="Blog">Blog</option>
<option value="University">University</option>
</select><input type="hidden" id="text" name="text" value=""><input type="hidden" id="content" name="content" value="Articles">
<div class="css-1myrko"><button type="submit" tabindex="0" class=" css-31biy7" data-track="true">Search</button></div>
</div>
</form>
Text Content
___ Developer Articles & Topics * General Information * All Documentation * Realm Documentation * Developer Articles & Topics * Community Forums * Blog * University * Products Atlas→ Developer data platform -------------------------------------------------------------------------------- Enterprise Advanced→ Enterprise software and support -------------------------------------------------------------------------------- Community Edition→ Free software used by millions -------------------------------------------------------------------------------- * Database→ * Search→ * Data Lake (Preview)→ * Charts→ * Device Sync→ * APIs, Triggers, Functions→ * Enterprise Server→ * Ops Manager→ * Enterprise Kubernetes Operator→ * Community Server→ * Cloud Manager→ * Community Kubernetes Operator→ Tools→ Build faster -------------------------------------------------------------------------------- * Compass→ * Shell→ * VS Code Plugin→ * Atlas CLI→ * Database Connectors→ * Cluster-to-Cluster Sync→ * Mongoose ODM Support→ * Relational Migrator→ * Solutions By Industry -------------------------------------------------------------------------------- By Use Case -------------------------------------------------------------------------------- * Financial Services→ * Telecom→ * Healthcare→ * Retail→ * Public Sector→ * Manufacturing→ * All Industries→ * Analytics→ * Internet of Things→ * Mobile→ * Payments→ * Serverless Development→ * All Use Cases→ Developer Data Platform Innovate fast at scale with a unified developer experience Learn More -------------------------------------------------------------------------------- White Papers & Presentations Webinars, white papers, datasheets and more View All * Resources Documentation→ -------------------------------------------------------------------------------- * Atlas→ * Server→ * Drivers→ * Develop Applications→ * Launch and Manage MongoDB→ * View and Analyze→ * Start with Guides→ Community -------------------------------------------------------------------------------- Education -------------------------------------------------------------------------------- * Developer Center→ * Events & Webinars→ * Forums→ * Champions→ * Find a User Group→ * University→ * Certification→ * Academia→ * Intro to MongoDB Course→ * Browse All Courses→ * Company About -------------------------------------------------------------------------------- Services -------------------------------------------------------------------------------- Partnerships -------------------------------------------------------------------------------- * Who We Are→ * Customer Stories→ * Blog→ * Careers→ * Pressroom→ * Leadership→ * Investors→ * Consulting→ * Training→ * Customer Support→ * Customer Success→ * Become a Partner→ * Find a Partner→ * MongoDB for Startups→ * Pricing Sign In Try Free General InformationAll DocumentationRealm DocumentationDeveloper Articles & TopicsCommunity ForumsBlogUniversity Search MongoDB Developerchevron-down * Topics * Languagesplus * Technologiesplus * Productsplus * Expertise Levelsplus * All Topics * Documentation * Articles * Tutorials * Events * Code Examples * Podcasts * Videos MongoDB Developer * Topicschevron-down * Documentation * Articles * Tutorials * Events * Code Examples * Podcasts * Videos close PYTHON plus Sign in to follow topics Articles Code Examples Documentation external Quickstarts Tutorials Videos MongoDB Developer Centerchevron-right Developer Topicschevron-right Languageschevron-right Pythonchevron-right Code Examples A SPOTIFY SONG AND PLAYLIST RECOMMENDATION ENGINE Rachelle PalmerPublished Jun 23, 2022 • Updated Jul 13, 2022 SparkMongoDBData VisualizationPython FULL APPLICATION Rate this code example social-githubView Code Try it CREATORS Lucas De Oliveira, Chandrish Ambati, and Anish Mukherjee from University of San Francisco contributed this amazing project. BACKGROUND TO THE PROJECT In 2018, Spotify organized an Association for Computing Machinery (ACM) RecSys Challenge where they posted a dataset of one million playlists, challenging participants to recommend a list of 500 songs given a user-created playlist. As both music lovers and data scientists, we were naturally drawn to this challenge. Right away, we agreed that combining song embeddings with some nearest-neighbors method for recommendation would likely produce very good results. Importantly, we were curious about how we could solve this recommendation task at scale with over 4 billion user-curated playlists on Spotify, where this number keeps growing. This realization raised serious questions about how to train a decent model since all that data would likely not fit in memory or a single server. WHAT WE BUILT This project resulted in a scalable ETL pipeline utilizing * Apache Spark * MongoDB * Amazon S3 * Databricks (PySpark) These were used to train a deep learning Word2Vec model to build song and playlist embeddings for recommendation. We followed up with data visualizations we created on Tensorflow’s Embedding Projector. THE PROCESS COLLECTING LYRICS The most tedious task of this project was collecting as many lyrics for the songs in the playlists as possible. We began by isolating the unique songs in the playlist files by their track URI; in total we had over 2 million unique songs. Then, we used the track name and artist name to look up the lyrics on the web. Initially, we used simple Python requests to pull in the lyrical information but this proved too slow for our purposes. We then used asyncio, which allowed us to make requests concurrently. This sped up the process significantly, reducing the downloading time of lyrics for 10k songs from 15 mins to under a minute. Ultimately, we were only able to collect lyrics for 138,000 songs. PRE-PROCESSING The original dataset contains 1 million playlists spread across 1 thousand JSON files totaling about 33 GB of data. We used PySpark in Databricks to preprocess these separate JSON files into a single SparkSQL DataFrame and then joined this DataFrame with the lyrics we saved. While the aforementioned data collection and preprocessing steps are time-consuming, the model also needs to be re-trained and re-evaluated often, so it is critical to store data in a scalable database. In addition, we’d like to consider a database that is schemaless for future expansion in data sets and supports various data types. Considering our needs, we concluded that MongoDB would be the optimal solution as a data and feature store. Check out the Preprocessing.ipynb notebook to see how we preprocessed the data. TRAINING SONG EMBEDDINGS For our analyses, we read our preprocessed data from MongoDB into a Spark DataFrame and grouped the records by playlist id (pid), aggregating all of the songs in a playlist into a list under the column song_list. Using the Word2Vec model in Spark MLlib we trained song embeddings by feeding lists of track IDs from a playlist into the model much like you would send a list of words from a sentence to train word embeddings. As shown below, we trained song embeddings in only 3 lines of PySpark code: from pyspark.ml.feature import Word2Vec word2Vec = Word2Vec(vectorSize=32, seed=42, inputCol="song_list").setMinCount(1) word2Vec.sexMaxIter(10) model = word2Vec.fit(df_play) xxxxxxxxxx 1 from pyspark.ml.feature import Word2Vec 2 word2Vec = Word2Vec(vectorSize=32, seed=42, inputCol="song_list").setMinCount(1) 3 word2Vec.sexMaxIter(10) 4 model = word2Vec.fit(df_play) We then saved the song embeddings down to MongoDB for later use. Below is a snapshot of the song embeddings DataFrame that we saved: Check out the Song_Embeddings.ipynb notebook to see how we train song embeddings. TRAINING PLAYLISTS EMBEDDINGS Finally, we extended our recommendation task beyond simple song recommendations to recommending entire playlists. Given an input playlist, we would return the k closest or most similar playlists. We took a “continuous bag of songs” approach to this problem by calculating playlist embeddings as the average of all song embeddings in that playlist. This workflow started by reading back the song embeddings from MongoDB into a SparkSQL DataFrame. Then, we calculated a playlist embedding by taking the average of all song embeddings in that playlist and saved them in MongoDB. Check out the Playlist_Embeddings.ipynb notebook to see how we did this. TRAINING LYRICS EMBEDDINGS Are you still reading? Whew! We trained lyrics embeddings by loading in a song's lyrics, separating the words into lists, and feeding those words to a Word2Vec model to produce 32-dimensional vectors for each word. We then took the average embedding across all words as that song's lyrical embedding. Ultimately, our analytical goal here was to determine whether users create playlists based on common lyrical themes by seeing if the pairwise song embedding distance and the pairwise lyrical embedding distance between two songs were correlated. Unsurprisingly, it appears they are not. Check out theLyrical_Embeddings.ipynb notebook to see our analysis. NOTES ON OUR APPROACH You may be wondering why we used a language model (Word2Vec) to train these embeddings. Why not use a Pin2Vec or custom neural network model to predict implicit ratings? For practical reasons, we wanted to work exclusively in the Spark ecosystem and deal with the data in a distributed fashion. This was a constraint set on the project ahead of time and challenged us to think creatively. However, we found Word2Vec an attractive candidate model for theoretical reasons as well. The Word2Vec model uses a word’s context to train static embeddings by training the input word’s embeddings to predict its surrounding words. In essence, the embedding of any word is determined by how it co-occurs with other words. This had a clear mapping to our own problem: by using a Word2Vec model the distance between song embeddings would reflect the songs’ co-occurrence throughout 1M playlists, making it a useful measure for a distance-based recommendation (nearest neighbors). It would effectively model how people grouped songs together, using user behavior as the determinant factor in similarity. Additionally, the Word2Vec model accepts input in the form of a list of words. For each playlist we had a list of track IDs, which made working with the Word2Vec model not only conceptually but also practically appealing. DATA VISUALIZATIONS WITH TENSORFLOW AND MONGODB After all of that, we were finally ready to visualize our results and make some interactive recommendations. We decided to represent our embedding results visually using Tensorflow’s Embedding Projector which maps the 32-dimensional song and playlist embeddings into an interactive visualization of a 3D embedding space. You have the choice of using PCA or tSNE for dimensionality reduction and cosine similarity or Euclidean distance for measuring distances between vectors. Click here for the song embeddings projector for the full 2 million songs, or here for a less crowded version with a random sample of 100k songs (shown below): The neat thing about using Tensorflow’s projector is that it gives us a beautiful visualization tool and distance calculator all in one. Try searching on the right panel for a song and if the song is part of the original dataset, you will see the “most similar” songs appear under it. USING MONGODB FOR ML/AI We were impressed by how easy it was to use MongoDB to reliably store and load our data. Because we were using distributed computing, it would have been infeasible to run our pipeline from start to finish any time we wanted to update our code or fine-tune the model. MongoDB allowed us to save our incremental results for later processing and modeling, which collectively saved us hours of waiting for code to re-run. It worked well with all the tools we use everyday and the tooling we chose - we didn't have any areas of friction. We were shocked by how this method of training embeddings actually worked. While the 2 million song embedding projector is crowded visually, we see that the recommendations it produces are actually quite good at grouping songs together. Consider the embedding recommendation for The Beatles’ “A Day In The Life”: Or the recommendation for Jay Z’s “Heart of the City (Ain’t No Love)”: Fan of Taylor Swift? Here are the recommendations for “New Romantics”: We were delighted to find naturally occurring clusters in the playlist embeddings. Most notably, we see a cluster containing mostly Christian rock, one with Christmas music, one for reggaeton, and one large cluster where genres span its length rather continuously and intuitively. Note also that when we select a playlist, we have many recommended playlists with the same names. This in essence validates our song embeddings. Recall that playlist embeddings were created by taking the average embedding of all its songs; the name of the playlists did not factor in at all. The similar names only conceptually reinforce this fact. NEXT STEPS? We felt happy with the conclusion of this project but there is more that could be done here. 1. We could use these trained song embeddings in other downstream tasks and see how effective these are. Also, you could download the song embeddings we here: Embeddings | Meta Info 2. We could look at other methods of training these embeddings using some recurrent neural networks and enhanced implementation of this Word2Vec model. social-githubView Code Try it -------------------------------------------------------------------------------- Rate this code example RELATED Tutorial ADDING AUTHENTICATION TO YOUR FARM STACK APP -------------------------------------------------------------------------------- Sep 23, 2022 Tutorial CALLING THE MONGODB ATLAS ADMINISTRATION API: HOW TO DO IT FROM NODE, PYTHON, AND RUBY -------------------------------------------------------------------------------- Apr 13, 2023 Tutorial UPGRADE FEARLESSLY WITH THE MONGODB STABLE API -------------------------------------------------------------------------------- May 16, 2022 Code Example GETTING STARTED WITH MONGODB AND TORNADO -------------------------------------------------------------------------------- Sep 23, 2022 Request a Code Example TECHNOLOGIES USED Languages Python Technologies Spark Products MongoDBData Visualization TABLE OF CONTENTS * Creators * Background to the Project * What We Built * The Process * Notes on our Approach * Data Visualizations with Tensorflow and MongoDB * Using MongoDB for ML/AI * Next Steps? © 2023 MongoDB, Inc. About * Careers * Investor Relations * Legal Notices * Privacy Notices * Security Information * Trust Center Support * Contact Us * Customer Portal * Atlas Status * Paid Support Social * Github * Stack Overflow * LinkedIn * Youtube * Twitter * Twitch * Facebook © 2023 MongoDB, Inc. PRIVACY PREFERENCE CENTER "Cookies" are small files that enable us to store information while you visit one of our websites. When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies, but essential cookies are always enabled. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer. MongoDB Privacy Policy Allow All MANAGE CONSENT PREFERENCES STRICTLY NECESSARY COOKIES Always Active These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information. PERFORMANCE COOKIES Performance Cookies These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore anonymous. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance. FUNCTIONAL COOKIES Functional Cookies These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages. If you do not allow these cookies then some or all of these services may not function properly. TARGETING COOKIES Targeting Cookies These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites. They do not store directly personal information, but are based on uniquely identifying your browser and internet device. If you do not allow these cookies, you will experience less targeted advertising. SOCIAL MEDIA COOKIES Social Media Cookies These cookies are set by a range of social media services that we have added to the site to enable you to share our content with your friends and networks. They are capable of tracking your browser across other sites and building up a profile of your interests. This may impact the content and messages you see on other websites you visit. If you do not allow these cookies you may not be able to use or see these sharing tools. BACK BUTTON PERFORMANCE COOKIES Vendor Search Search Icon Filter Icon Clear checkbox label label Apply Cancel Consent Leg.Interest checkbox label label checkbox label label checkbox label label Confirm My Choices By clicking "Accept All Cookies", you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. You can enable and disable optional cookies as desired. Read our Privacy Policy. Read our Privacy Policy Manage Cookies Accept All Cookies