<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by James Kirk on Medium]]></title>
        <description><![CDATA[Stories by James Kirk on Medium]]></description>
        <link>https://medium.com/@jameskirk1?source=rss-75df3566f52c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*tK1zCG1rW1mgBtIiwEMl8g.png</url>
            <title>Stories by James Kirk on Medium</title>
            <link>https://medium.com/@jameskirk1?source=rss-75df3566f52c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 08:20:18 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jameskirk1/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Getting Started with Recommender Systems and TensorRec]]></title>
            <link>https://medium.com/data-science/getting-started-with-recommender-systems-and-tensorrec-8f50a9943eef?source=rss-75df3566f52c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8f50a9943eef</guid>
            <category><![CDATA[recommendation-system]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[James Kirk]]></dc:creator>
            <pubDate>Tue, 22 Jan 2019 15:36:06 GMT</pubDate>
            <atom:updated>2019-01-22T20:44:30.735Z</atom:updated>
            <content:encoded><![CDATA[<h4>Prototyping a recommender system, step-by-step.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/532/0*d4HGOpwY6z2x1Rtk" /></figure><p>Recommender systems are used in many products to present users with relevant or personalized items (food, movies, music, books, news, etc). To do this, they learn from users’ previous interactions with items to identify users’ tastes and improve future recommendations.</p><p>This post will walk us through the prototyping of a new recommender system in Python using <a href="https://github.com/jfkirk/tensorrec">TensorRec</a> including input data manipulation, algorithm design, and usage for prediction.</p><p>You can find the Python code from this post’s example <a href="https://github.com/jfkirk/tensorrec/blob/master/examples/getting_started.py">here</a>.</p><h3>System Overview</h3><p><a href="https://github.com/jfkirk/tensorrec">TensorRec</a> is a Python package for building recommender systems. A TensorRec recommender system consumes three pieces of input data: user features, item features, and interactions. Based on the user/item features, the system will predict which items to recommend. The interactions are used when fitting the model: predictions are compared to the interactions and a loss/penalty is calculated, which the system learns to decrease.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YotDpHjvGL8xK91ZggthbA.png" /></figure><p>As we prototype our system, we’ll be tackling three major topics: how we handle interactions, how we handle features, and how we structure the recommender itself.</p><h3>Interaction Data</h3><p>For this example we’ll use the <a href="https://grouplens.org/datasets/movielens/">MovieLens dataset</a>. This dataset contains 1–5 star ratings for movies, metadata about those movies, and tags that users applied to the movies. For our first prototype we’ll focus on the ratings, but we’ll return to the other metadata later.</p><p>In raw form, the ratings look like this:</p><pre>userId, movieId, rating, timestamp<br>1,      1,       4.0,    964982703<br>1,      3,       4.0,    964981247<br>1,      6,       4.0,    964982224<br>1,      47,      5.0,    964983815<br>1,      50,      5.0,    964982931<br>1,      70,      3.0,    964982400<br>...</pre><p>Each row represents a single rating: one user’s thoughts about one movie. We’ll be using these ratings as our interactions. Our first step toward training this system is to ingest and format this interaction data. First, we read in the CSV file of ratings.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b37f43087c1f8d66d62753263d09e424/href">https://medium.com/media/b37f43087c1f8d66d62753263d09e424/href</a></iframe><p>At this point, we’ll break the ratings in to a training and test set by shuffling and splitting the ratings. Our prototypes will be trained on the training set, and we’ll evaluate their success using the test set. Splitting the train/test sets at random like this is crude, and there are more rigorous techniques for model evaluation, but it is quick and clear for the purposes of this example.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ef5169564df70a6c9e92b9fcd1437e5/href">https://medium.com/media/2ef5169564df70a6c9e92b9fcd1437e5/href</a></iframe><p>Next, we reorganize these ratings in to a <a href="https://docs.scipy.org/doc/scipy/reference/sparse.html">Scipy sparse matrix</a>. In this matrix, every row represents a user and every column is a movie. The [<em>i, j</em>]th value in this matrix is User <em>i</em>’s interaction with Movie <em>j</em>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dc05f266219d998ced435a6028b4cd74/href">https://medium.com/media/dc05f266219d998ced435a6028b4cd74/href</a></iframe><h3>Collaborative Filter Prototype</h3><p>A collaborative filter is an algorithm that learns which users have similar tastes and recommends items to a user based on what similar users have liked. A common way to do this is through <a href="https://www.cs.cmu.edu/~mgormley/courses/10601-s17/slides/lecture25-mf.pdf">matrix factorization</a>. In matrix factorization, we have to learn two matrices (user representations and item representations) that, when multiplied together, approximate the interactions:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*75E815RPh2HqxMw4O6aGYA.png" /><figcaption>From Wikipedia</figcaption></figure><p>In this case, rows of <em>W</em> are the user representations, columns of <em>H</em> are the item representations, and values in <em>V</em> are the interactions. <em>W</em> and <em>H </em>need to be learned to produce the best approximation of <em>V.</em></p><p>The width of <em>W</em> and the height of <em>H</em> are the same — this shared dimension is referred to as the “number of components.” A model with more components is learning more complex representations of users and items, but this can lead to over-fitting the training data. In general, we want to try to squeeze lots of information in to small representations. For this reason, in our prototype I’ve arbitrarily chosen to use 5 components. When prototyping further, we should experiment with increasing and decreasing the number of components and be wary of over-fitting.</p><p>TensorRec will perform matrix factorization by default if it is given only identity matrices as user/item features. These identity matrices are often called “indicator features.”</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/03e21bcd1a1f81e33376d17571722691/href">https://medium.com/media/03e21bcd1a1f81e33376d17571722691/href</a></iframe><p>We have now created the two indicator feature matrices, built a simple collaborative filter model with 5 components, and fit the model!</p><p>Next, of course, we’ll want to see how well the model performs.</p><p>To do this, we’ll look at a metric called “recall at K.” Recall@K says, for the average user, what percentage of their test items made it in to the top <em>K</em> in the predicted rankings. In other words, if we get a recall@10 value of .06, then there is a 6% chance that a particular movie I like will make it in to my top 10 recommendations.</p><p>Recall@K is a nice metric for many recommender systems because it emulates the behavior of a recommendation product: If a movie website is only going to show me my top 10 recommendations, then their algorithm will want to be effective at putting movies I like in my top 10.</p><p>Before calculating the recall, we’ll want to decide which interactions should count as a “like.” In this case, I’ve chosen to use all ratings of at least 4.0 as “likes” and ignore the rest.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d9f17211cdb0686135f4af23a9942380/href">https://medium.com/media/d9f17211cdb0686135f4af23a9942380/href</a></iframe><p>Great! Let’s check the results:</p><pre>Matrix factorization collaborative filter:<br>Recall at 10: Train: 0.0008 Test: 0.0010</pre><p>…Not great. These results tell us that, among the test-set movies, there is only a .1% chance that a liked movie made it in to the top 10. This recommender system is ineffective, and we’ll want to look for ways to improve it.</p><h3>Loss Graphs</h3><p>One way we can configure our TensorRec system is by changing the loss graph. The loss graph takes in predictions and interactions and calculates a penalty (loss) that the system will try to decrease as it learns.</p><p>By default, TensorRec uses RMSE (root mean square error) as the loss graph. This means that TensorRec is trying to estimate the values of the interactions exactly: if I rated a movie 4.5, TensorRec is trying to produce a predicted score of exactly 4.5.</p><p>This is intuitive, but it doesn’t line up with how recommender systems work in many products: a movie website doesn’t need to predict my rating exactly, it just needs to be able to rank movies I will like above movies I won’t like. For this reason, many systems function by “learning to rank.” We can make our TensorRec system work this way by using a loss graph called WMRB.</p><p><a href="https://arxiv.org/abs/1711.04015">WMRB, which stands for “weighted margin-rank batch,”</a> works by taking a random sample of items the user hasn’t interacted with and comparing their predictions to items the user likes. Over time, this pushes items a user likes to the top of the rankings.</p><p>We can tell TensorRec to use WMRB by specifying it when we construct the model and specifying the size of the sample batch when fitting the model. In this case, we’ll want to train the model on only the positive ratings (≥4.0) so WMRB pushes those to the top.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50706c73d7c15ea7dd19dba5e9bec637/href">https://medium.com/media/50706c73d7c15ea7dd19dba5e9bec637/href</a></iframe><p>Let’s look at the results:</p><pre>WMRB matrix factorization collaborative filter:<br>Recall at 10: Train: 0.1098 Test: 0.0776</pre><p>Much better! We’ve gone from a .1% chance of a liked item reaching the top 10 all the way to a 7.76% chance. This is an example of how impactful the right loss function can be. TensorRec allows you to specify and customize your own loss graphs, and you can see more example loss graphs <a href="https://github.com/jfkirk/tensorrec/blob/master/tensorrec/loss_graphs.py">here</a>.</p><h3>Adding Metadata Features</h3><p>To continue experimenting, we should try to make use of other data available to us. In the MovieLens example, we can use movie metadata, such as the movie’s genres, to enrich the recommendations.</p><p>In raw form, the movie metadata file looks like this:</p><pre>movieId, title,                    genres<br>1,       Toy Story (1995),         Adventure|Animation|Children|C...<br>2,       Jumanji (1995),           Adventure|Children|Fantasy<br>3,       Grumpier Old Men (1995),  Comedy|Romance<br>4,       Waiting to Exhale (1995), Comedy|Drama|Romance<br>...</pre><p>First, we’ll want to read this data, map the movies to our internal IDs, and keep track of the genres for each movie. Then we’ll binarize the genre labels using <a href="https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MultiLabelBinarizer.html#sklearn.preprocessing.MultiLabelBinarizer">Scikit’s MultiLabelBinarizer</a>. The binarized output will be our features for our new recommender system.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/790a0a30244ac00ed7c8113d01106ec2/href">https://medium.com/media/790a0a30244ac00ed7c8113d01106ec2/href</a></iframe><p>Running this will print out an example of the raw metadata and the binarized genres:</p><pre>Raw metadata example:<br>[&#39;movieId&#39;, &#39;title&#39;, &#39;genres&#39;]<br>[0, &#39;Toy Story (1995)&#39;, [&#39;Adventure&#39;, &#39;Animation&#39;, &#39;Children&#39;, &#39;Comedy&#39;, &#39;Fantasy&#39;]]</pre><pre>Binarized genres example for movie Toy Story (1995):<br>[0 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0]</pre><h3>Content-based Recommendation</h3><p>Now that we have metadata about our items, one thing we can try is to recommend based solely on the item metadata.</p><p>To do this, we will configure a TensorRec model to use a pass-through representation graph for item features. For us, this means that the item representations will be the same as the item features that are passed in (just the movie genres) and the user representations will reflect how much the user likes that particular genre.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50789548733a0417c68af64be0bfe29d/href">https://medium.com/media/50789548733a0417c68af64be0bfe29d/href</a></iframe><p>Great! Let’s check the results:</p><pre>Content-based recommender:<br>Recall at 10: Train: 0.0471 Test: 0.0130</pre><p>It’s not as good as the ranking collaborative filter but, with a recall@10 of 1.3%, it’s significantly more effective than our very first collaborative filter.</p><p>There is a major weakness to this system: genres alone are not very descriptive and are not enough information to make an informed recommendation. If we had more descriptive metadata (more tags, actors, sub-genres, etc) we may have more success with this content-based recommender system.</p><p>On the other hand, there is a major strength to this system: by relying on only metadata features, and not using indicator features, we can recommend movies which were not present when training the model. Similarly, if we have valuable user metadata we can avoid using user indicator features and make predictions for users who’ve never interacted with a movie before. This is called “cold-start” recommendation.</p><h3>Hybrid Model</h3><p>We know that our ranking collaborative filter gave us the best results, but it seems there is some value in using the movie metadata. Let’s combine these two: we’ll use indicator features to get the strengths of a collaborative filter, and we’ll also use the content features to take advantage of the metadata. Systems like this that combine collaborative filtering and content-based recommendation are called “hybrid” models.</p><p>We do this by stacking the two sets of features together:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/96bc411a90d9e092fb1dcaff71fd6c52/href">https://medium.com/media/96bc411a90d9e092fb1dcaff71fd6c52/href</a></iframe><p>Great! Let’s check the results:</p><pre>Hybrid recommender:<br>Recall at 10: Train: 0.1196 Test: 0.0794</pre><p>With a recall@10 of 7.94%, this is our strongest recommender system yet. Compared to the pure collaborative filter’s result of 7.76% the difference isn’t profound, but it is still an improvement. If we use more metadata than just genres, we’ll likely see an even larger impact.</p><h3>Making Recommendations</h3><p>We have a trained model and now we can use this model to make recommendations for our users. We do this by passing the user’s feature vector and all the item features to predict_rank() and examining the resulting rankings:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7241f8503dd5d19c97933eea06c0153c/href">https://medium.com/media/7241f8503dd5d19c97933eea06c0153c/href</a></iframe><p>This code snippet will print out the top 10 recommendations for user 432. I chose user 432 because I am familiar with the movies they’ve rated, so I feel I can put myself in their shoes and judge their recommendations. We should note that the movies user 432 has already rated will still be included — if we want to filter those out, we will need to do that with a post-processing step.</p><p>Let’s look at user 432’s training data to see what kinds of movies they like:</p><pre>User 432 liked:<br>Usual Suspects, The (1995)<br>Pulp Fiction (1994)<br>Silence of the Lambs, The (1991)<br>Reservoir Dogs (1992)<br>Shawshank Redemption, The (1994)<br>Kill Bill: Vol. 1 (2003)<br>Social Network, The (2010)<br>Trainspotting (1996)<br>Arrival (2016)<br>My Big Fat Greek Wedding (2002)</pre><p>Some crime, some dark comedy, and a notable love for Tarantino. Let’s look at user 432’s recommendations from our hybrid model:</p><pre>User 432 recommendations:<br>Seven (a.k.a. Se7en) (1995)<br>Usual Suspects, The (1995)<br>Pulp Fiction (1994)<br>Silence of the Lambs, The (1991)<br>Fargo (1996)<br>American Beauty (1999)<br>Fight Club (1999)<br>Shawshank Redemption, The (1994)<br>Departed, The (2006)<br>Memento (2000)</pre><p>Some more crime flicks with a definite dark comedy bent! This looks pretty good at-a-glance, but let’s check user 432’s test movies:</p><pre>User 432&#39;s held-out movies:<br>Fargo (1996)<br>American History X (1998)<br>Fight Club (1999)<br>Dark Knight Rises, The (2012)</pre><p>Both Fargo and Fight Club made it in to user 432’s recommendations — this is a great result! For this specific user, we achieved a recall@10 of 50%.</p><h3>Going Forward</h3><p>To continue to refine our recommender system we should experiment with more representation, prediction, and loss graphs, providing more metadata to the system, engineering those metadata features differently, managing interaction/feedback data differently, and optimizing the various hyper-parameters of the system.</p><p>I recently had the chance to visit <a href="https://twitter.com/MITREcorp">MITRE</a> to discuss many of the design choices when designing and deploying recommender systems. You can find a video of the talk <a href="https://www.youtube.com/watch?v=xBMGr08fowA&amp;t=3m58s">here</a>.</p><p>If you have questions, please feel free to ask them here or <a href="https://github.com/jfkirk/tensorrec/issues">open a GitHub issue</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8f50a9943eef" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/getting-started-with-recommender-systems-and-tensorrec-8f50a9943eef">Getting Started with Recommender Systems and TensorRec</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deep Learning for Recommendation with Keras and TensorRec]]></title>
            <link>https://medium.com/hackernoon/deep-learning-for-recommendation-with-keras-and-tensorrec-2b8935c795d0?source=rss-75df3566f52c------2</link>
            <guid isPermaLink="false">https://medium.com/p/2b8935c795d0</guid>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[recommendation-system]]></category>
            <dc:creator><![CDATA[James Kirk]]></dc:creator>
            <pubDate>Wed, 09 May 2018 13:59:15 GMT</pubDate>
            <atom:updated>2019-04-30T05:03:20.400Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1023/1*tGIXevLk_3ejZHF3w8GYXQ.jpeg" /></figure><p>With the release of <a href="https://github.com/jfkirk/tensorrec">TensorRec</a> v0.21, I’ve added the ability to easily use deep neural networks in your recommender system.</p><p>For some recommender problems, such as cold-start recommendation problems, deep <a href="https://hackernoon.com/tagged/learning">learning</a> can be an elegant solution for learning from user and item metadata. Using <a href="https://github.com/jfkirk/tensorrec">TensorRec</a> with <a href="https://keras.io/">Keras</a>, you can now experiment with deep representation models in your recommender systems quickly and easily.</p><h3>Implementation</h3><p>In a TensorRec model, the components that learn how to process user and item features are called the “representation graphs” (or “repr” for short). These graphs convert high-dimensional user/item features, such as metadata and indicator variables, into low-dimensional user/item representations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YotDpHjvGL8xK91ZggthbA.png" /><figcaption>The TensorRec recommender system.</figcaption></figure><p>Define your model’s representation graphs as a sequence of Keras layers by extending the class AbstractKerasRepresentationGraph. Next, overwrite the create_layers abstract method to return an ordered list of Keras layers.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/508acf0b226c590995540243f6458247/href">https://medium.com/media/508acf0b226c590995540243f6458247/href</a></iframe><h3><strong>Example</strong></h3><p>You can find the example above used in a full recommender system for the <a href="http://www2.informatik.uni-freiburg.de/~cziegler/BX/">Book Crossing dataset</a> in <a href="https://github.com/jfkirk/tensorrec/blob/master/examples/keras_example.py">this module.</a></p><p>With this dataset, the recommender system is learning to recommend books to users based on user metadata (location, age) and book metadata (author, title, year publisher, etc). This example compares four different configurations of a recommender system using combinations of linear kernel representations and deep network representations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hSSAFi9z71JOQmM__UjnHA.png" /><figcaption>Book Crossing example results</figcaption></figure><p>The architecture of this network has not been optimized for the Book Crossing problem, and should be regarded only as an example of the new Keras functionality.</p><h3><strong>A Word of Caution</strong></h3><p>When you’re holding a hammer (or deep learning), everything looks like a nail (or a deep learning problem).</p><p>Many real-world recommendation problems are best solved through thoughtful analysis, feature engineering, simple models, and effective feedback systems. Deep models are highly flexible, but this makes them particularly susceptible to overfitting through overparameterization. In these cases, performance with previously-unknown users and items can be significantly harmed.</p><p>An example of this issue is the third configuration in the Book Crossing example above. This system is the most effective of the four configurations at making recommendations for existing users based only on their age and location but, based on the same user metadata, is the worst performer on new users — a classic example of overfitting. This problem could be avoided with richer metadata, better feature engineering, or simpler models.</p><p>The Book Crossing example also illustrates that the best product outcomes may be from having multiple recommender systems. A product that is driven by two recommender systems, one designed and optimized for warm-start users and another for new cold-start users, may be the optimal system <a href="https://hackernoon.com/tagged/design">design</a> for your product.</p><p>If you’d like to contribute to (or even just try out) TensorRec I’d love to hear your feedback either on <a href="https://github.com/jfkirk/tensorrec">GitHub</a> or in the comment section of this post.</p><p>Special thanks to Joe Cauteruccio (Spotify), Mike Sanders (Spotify), and Logan Moore (Northeastern University) for their contributions to TensorRec.</p><p><em>Note: This is a personal project and, at time of writing, is not associated with Spotify.</em></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fupscri.be%2Fdde502%3Fas_embed%3Dtrue&amp;dntp=1&amp;url=https%3A%2F%2Fupscri.be%2Fhackernoon%2F&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=upscri" width="800" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href">https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2b8935c795d0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/deep-learning-for-recommendation-with-keras-and-tensorrec-2b8935c795d0">Deep Learning for Recommendation with Keras and TensorRec</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TensorRec: A Recommendation Engine Framework in TensorFlow]]></title>
            <link>https://medium.com/hackernoon/tensorrec-a-recommendation-engine-framework-in-tensorflow-d85e4f0874e8?source=rss-75df3566f52c------2</link>
            <guid isPermaLink="false">https://medium.com/p/d85e4f0874e8</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[recommendation-system]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[tensorflow]]></category>
            <dc:creator><![CDATA[James Kirk]]></dc:creator>
            <pubDate>Tue, 24 Oct 2017 00:15:26 GMT</pubDate>
            <atom:updated>2019-04-30T05:03:20.848Z</atom:updated>
            <content:encoded><![CDATA[<p>When building recommendation systems, I have been frustrated by how much effort I spend on data manipulation and API-building when real progress comes from developing algorithms that better understand my users and items.</p><p><a href="https://github.com/jfkirk/tensorrec">That is why I built TensorRec</a>, a framework intended to streamline the logistics of a TensorFlow-based recommendation engine and free you up to focus on the interesting stuff: developing your ideas for representation (also called embedding) functions, loss functions, and more robust <a href="https://hackernoon.com/tagged/learning">learning</a>.</p><p><em>Edit 1/22/19: There is now a </em><a href="https://medium.com/@jameskirk1/getting-started-with-recommender-systems-and-tensorrec-8f50a9943eef"><em>Getting Started guide for TensorRec</em></a></p><p>TensorRec is a recommendation algorithm with an easy API for training and prediction that resembles common machine learning <a href="https://hackernoon.com/tagged/tools">tools</a> in Python. It also gives you the flexibility to experiment with your own representation and loss functions, letting you build a recommendation system that is tailored to understanding your particular users and items.</p><p>The TensorRec project is still young, but I invite any usage, participation, or criticism that you have to offer.</p><p>In building TensorRec, I had four goals:</p><ol><li>Build a recommendation engine capable of learning from explicit positive and negative feedback.</li><li>Allow for arbitrary TensorFlow graphs to be used as representation functions and loss functions.</li><li>Provide reasonable defaults for representation functions and loss functions.</li><li>Pack as many Machine Learning buzzwords into a Medium post as possible.</li></ol><p>While the first three goals remain a work in progress — your mileage may vary — I’m <em>very</em> satisfied with number four.</p><h3>How It Works</h3><p>TensorRec scores recommendations by consuming user and item <a href="https://en.wikipedia.org/wiki/Feature_(machine_learning)">features</a> (ids, tags, or other metadata) and building two low-dimensional vectors, a “user representation” and an “item representation”. The <a href="https://en.wikipedia.org/wiki/Dot_product">dot product</a> of these two vectors is the score for the relationship between that user and that item — the highest scores are predicted to be the best recommendations.</p><pre># Predict scores for all users and all items<br>predictions = model.predict(user_features=user_features,<br>                            item_features=item_features)</pre><p>The algorithm used to generate these representations, called the representation function, can be customized: anything from a straight-forward linear transform to a deep neural network can be applied, depending on the particulars of the problem you need TensorRec to solve and the feature data you have available. Also, the user and item representation functions can be customized independently. You can find an example of representation function customization <a href="https://github.com/jfkirk/tensorrec/wiki/Representation-Graphs">here</a>.</p><p>TensorRec learns by comparing the scores it generates to actual interactions (likes/dislikes) between users and items. The comparator is called the “loss function,” and TensorRec allows you to customize your own loss functions as well. You can find an example of a custom loss function <a href="https://github.com/jfkirk/tensorrec/wiki/Loss-Graphs">here</a>.</p><p>The functions for fitting a TensorRec model are similar to fitting functions for other common machine learning tools:</p><pre># Fit the model for 5 epochs<br>model.fit(interactions, user_features, item_features,<br>          epochs=5, verbose=True)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7HdQ__6RDdtueu-GMETkng.png" /><figcaption>Update 3/30/18 — System Diagram</figcaption></figure><h3>Inspiration</h3><p>I have used <a href="https://github.com/lyst/lightfm">LightFM</a>, developed by Maciej Kula and <a href="https://medium.com/u/e49fe8455a34">Lyst</a>, extensively and I am impressed with its performance and usability. I wrote a blog post about using LightFM <a href="https://medium.com/product-at-catalant-technologies/using-lightfm-to-recommend-projects-to-consultants-44084df7321c">here</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*wamAT2hw_sYn0dy8Pftavw.png" /></figure><p>LightFM generates user and item representations by functioning as a factorization machine and learning linear embeddings for each feature. By taking the dot product of these two representation vectors, you get a unitless score that, when ranked, tells you how good (or bad) a given user-item match would be.</p><p>This linear factorization method is effective and computationally efficient, but I have run into issues using LightFM with imbalanced, redundant, inconsistent, or highly-correlated features — learning to meaningfully embed these features would require a more complex representation function, such as a deep neural network. This representation function would be able to learn nuanced relationships in the user and item features and increase the overall information capacity of the system. This made me curious to explore options for representation functions that were non-linear, and I developed TensorRec as a framework to do just that.</p><h3>TensorFlow for Recommendations</h3><p><a href="https://www.tensorflow.org/">TensorFlow,</a> originally developed by Google, is an open source tool that allows you to build, optimize, and distribute large, arbitrary machine learning systems.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pidw2QNb9nG5BrcNzbY4NA.jpeg" /></figure><p>In TensorFlow, a machine learning process is expressed as a ‘graph’ showing how data flows through the system. These graphs can be visualized using <a href="https://www.tensorflow.org/get_started/summaries_and_tensorboard">TensorBoard</a>, giving a clearer explanation of the machine learning process at-hand.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/255/1*uxA7W7d1rO9tjziEGSdPOg.png" /><figcaption>A single ReLU layer of a neural network shown as a TensorFlow graph.</figcaption></figure><p>To build our recommendation system, we need TensorFlow graphs that accomplish four tasks:</p><ol><li>Transform input data into feature tensors for easy embedding.</li><li>Transform user/item feature tensors into user/item representations (the representation function).</li><li>Transform a pair of representations into a prediction.</li><li>Transform predictions and truth values into a loss value (the loss function).</li></ol><p>TensorRec solves 1 and 3 while providing modularity and reasonable defaults for 2 and 4, giving you the freedom to experiment with representation and loss functions. All you need to do is plug in a function that builds your custom representation function graph or loss function graph, like <a href="https://github.com/jfkirk/tensorrec/wiki/Representation-Graphs">this example</a>.</p><h3>What’s Missing</h3><p>Many recent advances in information retrieval have come from sophisticated loss functions. Particularly interesting to me are pairwise loss functions, such as <a href="http://www.thespermwhale.com/jaseweston/papers/wsabie-ijcai.pdf">WARP</a>, but these are challenging to represent as TensorFlow graphs. TensorRec’s value to users would increase with implementation of these loss functions.</p><p>Valuable additions to TensorRec would be new features for dealing with large interaction data, managing model state, and handling implicit interactions.</p><p>If you’d like to contribute to, or even just try out, TensorRec I’d love to hear your feedback either on <a href="https://github.com/jfkirk/tensorrec">GitHub</a> or in the comment section of this post.</p><p><em>Note: This is a personal project and, at time of writing, is not associated with Spotify</em></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fupscri.be%2Fdde502%3Fas_embed%3Dtrue&amp;dntp=1&amp;url=https%3A%2F%2Fupscri.be%2Fhackernoon%2F&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=upscri" width="800" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href">https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d85e4f0874e8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/tensorrec-a-recommendation-engine-framework-in-tensorflow-d85e4f0874e8">TensorRec: A Recommendation Engine Framework in TensorFlow</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using LightFM to Recommend Projects to Consultants]]></title>
            <link>https://medium.com/product-at-catalant-technologies/using-lightfm-to-recommend-projects-to-consultants-44084df7321c?source=rss-75df3566f52c------2</link>
            <guid isPermaLink="false">https://medium.com/p/44084df7321c</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[future-of-work]]></category>
            <category><![CDATA[business-consulting]]></category>
            <category><![CDATA[recommendation-system]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[James Kirk]]></dc:creator>
            <pubDate>Tue, 13 Dec 2016 16:53:22 GMT</pubDate>
            <atom:updated>2021-07-08T21:40:12.191Z</atom:updated>
            <content:encoded><![CDATA[<p>We have a challenge at <a href="http://gocatalant.com/">Catalant Technologies</a>: there are more than 30,000 business experts and boutique firms using our platform all looking for the right projects to tackle. These experts are alumni of traditional consulting firms, SMEs in niche technical fields, veterans of the world’s largest enterprises, and everything in-between. The projects on our platform are just as diverse as the experts working on them, and we need to find the right projects for every expert. This is the challenge that my colleague <a href="https://medium.com/u/deaaea5183f7">Andy Luther</a> and I have been working on.</p><p>When an expert signs up for Catalant, they can provide a description of themselves in their ‘About Me’ section and tag themselves with skills and industries that represent their expertise. Similarly, when a business posts a project to our site, they write a project description and can tag their project with the skills they need. Experts are able to search for projects on their own, but we want to make it easy by recommending the most relevant projects for them.</p><p>One way we could generate these recommendations is by tracking which projects experts like and dislike (‘bookmark’ or ‘hide’ on Catalant), comparing these interactions to other experts’ likes and dislikes, and recommending projects that similar experts have liked. This is called ‘collaborative filtering,’ and it covers many algorithms with their own strengths and weaknesses. Collaborative filters are widely used on shopping websites like Amazon, news services, and video content providers like YouTube.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/532/1*4rPiC97dQ_XZDJAfjEYqlA.png" /><figcaption>Collaborative Filtering and Obesity: a silent killer.</figcaption></figure><p>There is an important difference between how websites like Amazon incorporate collaborative filters and how Catalant must recommend projects: Catalant project life-times are very short. Products stay on Amazon’s catalog for months and in that time they will be purchased and rated by potentially thousands of users. This allows them to develop a very rich understanding of what kinds of items are purchased by the same customers and make recommendations based off these user-clusters. A Catalant project will only be accepting bids for a few days, may be interacted with by less than thirty experts, and needs to be recommended to the right experts the moment it is posted. This short lifetime and small number of interactions would hobble many collaborative filtering strategies.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/250/1*ykhpFmGN4XJwTk3OaPOc9A.jpeg" /><figcaption>Catalant projects are ephemeral.</figcaption></figure><p>An alternative to collaborative filtering is content-based filtering. A content-based recommender is one that matches a user with items that have metadata (tags, genres, etc.) similar to items that user has already liked. On Netflix, that means breaking down movies by their genre, actors, subject matter or other criteria.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*IOoIUqnFMHRyb2r7JkrDkw.jpeg" /><figcaption>I have very niche movie preferences.</figcaption></figure><p>For Catalant, a content-based approach means recommending projects to a user that have similar industry and skill tags to projects the user has already bookmarked. There are two major drawbacks to content-based recommendation systems: they require a lot of manual processing to ensure that the project metadata is thorough and rich, and they miss out on the potential to learn from comparing different users’ behavior (called ‘transfer learning’).</p><p>The appropriate solution for Catalant recommendations is somewhere in-between collaborative filters and content-based recommenders. That is where LightFM comes in.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/399/1*tO02qRXmOzp-yETOBQfw8A.png" /></figure><p><a href="https://github.com/lyst/lightfm">LightFM</a> is a hybrid model that incorporates both content-based recommendations and the transfer learning of collaborative filtering methods; it gives us the best of both worlds. Developed by <a href="https://medium.com/u/e49fe8455a34">Lyst</a>, a Fashion e-Commerce site based in London, LightFM figures out what users like by learning relationships that map users and user metadata to the projects and project metadata that they like. These relationships are called ‘embeddings.’ In order to build these embeddings, LightFM utilizes three sets of information: the expert metadata, the project metadata, and the interactions between them.</p><p>For expert metadata, we build a matrix containing all of the expert’s industry and skill tags, as well as selected words from their profile tagline and ‘About Me’ section. That matrix looks something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/492/1*43Be-sAmktN9HYvseA3mng.png" /></figure><p>Similarly, for project metadata, we build a matrix containing the project’s industry tags, skill tags, selected words from the project name and description, and budget range:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/614/1*56TwD4Sh5A2SEGvl1S_82g.png" /></figure><p>The interactions are also put in to a matrix where every positive value represents a like and every negative is a dislike:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/555/1*tfnTAxGB-SSY8tV_Mrw2CQ.png" /></figure><p>LightFM then takes these three matrices and solves for the embeddings that will allow it to most accurately predict the values in the interactions matrix. You can read more about how LightFM learns (called ‘stochastic gradient descent’) in <a href="https://arxiv.org/pdf/1507.08439.pdf">this paper</a> by Maciej Kula from Lyst.</p><p>To create recommendations for an expert, we give LightFM that expert’s metadata and the metadata of all out-for-bid projects. LightFM then uses the embeddings that it has learned to score each project on how much the expert will like it. The top-scoring projects are the user’s recommendations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*Xq1_JwqTZ9qa-kdiydo_zg.jpeg" /><figcaption>Laura’s ideal project.</figcaption></figure><p>This system is something between a collaborative filter and a content-based system. It learns how groups of experts interact with various projects, like a collaborative filter, but it is also learning relationships between expert and project metadata, like a content-based system. By working in both worlds, LightFM gives us the strengths of both, and helps us match our diverse projects to our equally diverse experts.</p><p>In future posts, we will dive further in to how we measure success, how we break down expert/project metadata, how we optimize these models, and plans for maximizing sick wheelie hang-time.</p><p>If these problems are interesting to you, we have plenty more to solve at Catalant Technologies. We are looking for Data Science Engineers and Software Engineers. Learn more <a href="https://gocatalant.com/careers">here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=44084df7321c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/product-at-catalant-technologies/using-lightfm-to-recommend-projects-to-consultants-44084df7321c">Using LightFM to Recommend Projects to Consultants</a> was originally published in <a href="https://medium.com/product-at-catalant-technologies">Catalant Technologies</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>