Adding recommendation listings

Recall that in Chapter 6, Collaborative Filtering versus Content-Based Recommendation Engines, we trained a collaborative filtering based model using an ALS implementation of Apache Spark. Now that we already have it persisted we will re-use it to provide recommendations on a customer page.

Remember that when we trained that model, we had to create a rating object. This object had userId, productId, and a rating value. However, these values are specific to the algorithm, and are not related to our products, and customer IDs. So first, we need to recover those mappings. The following change to AmazonRatingALS does the job for us:

Adding recommendation listings

With this change, we will have both customer and product mappings, which we will use to map between our data and the model representation of items and customers. After retraining the ALS model, now we will have the mappings written to disk which we can load in-memory.

$ sbt ';set javaOptions += "-Xmx6114m"' ';set fork := true' 'run-main chapter06.AmazonRatingsALS'
[success] Total time: 3359 ...

Since our web application is written in the Play 2 framework, we have a problem with integrating Apache Spark into the same codebase. We need Apache Spark, to read the model and those mapping files. The integration problem is because both of them use different versions of Akka, which are incompatible. To overcome that limitation, we will create a simple recommender web service using the Spray framework. This can all be implemented in one single file. Again, update build.sbt for library dependencies:

libraryDependencies += "io.spray" %% "spray-can" % "1.3.3"

libraryDependencies += "io.spray" %% "spray-routing" % "1.3.3"

libraryDependencies += "io.spray" %% "spray-json" % "1.3.2"

Now, create a simple web service using the Spray framework (http://spray.io/) for which our web application will use forwarding recommendation queries. This is implemented in src/main/scala/chapter07/RecommendationServer.scala. The following snippets show the route recommendations/foruser/<userID>, that then returns at most 10 recommendations for a particular user. All the ID mappings to and from our representation are handled in this snippet:

Adding recommendation listings

The full implementation is present in src/main/scala/chapter07/RecommendationServer.scala. We need to make sure that the RecommendationServer is running for our web application to be able to fetch recommendations for a customer.

$ sbt "set fork := true" "run-main chapter07.RecommendationServer"

This server will run on localhost (or 127.0.0.1), listening on HTTP port 8082. We will use this same host and port to configure our web application. All such configurations in our project are controlled using conf/application.conf, parts of which are shown in the following code:

elasticsearch {
  server = "127.0.0.1"
  port = 9300
  products_index = "products_index"
}

mongodb {
  host = "localhost"
  port = 27017
  database = "amazon_dataset"
  products_collection = "products"
}

recommenderService {
  host = "localhost"
  port = 8082
}

Next, we will update our customer view to fetch recommendations asynchronously using AJAX. We added the following method to util.Recommender, and created a route /recommendation/for/customer/:id/ which merely acts as a proxy to RecommendationServer running on port 8082.

Adding recommendation listings

The rest of the changes are mostly cosmetic. Let's take a look at how the recommendations are displayed:

Adding recommendation listings

The left side shows the customer information we already had earlier. The right side shows that for this customer, we have 10 recommendations, which shows the product IDs (with recommender score in parentheses, the higher the better).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.167.183