{"id":1080,"date":"2017-01-05T11:17:42","date_gmt":"2017-01-05T11:17:42","guid":{"rendered":"http:\/\/blog.stratio.com\/?p=1080"},"modified":"2023-09-20T13:50:29","modified_gmt":"2023-09-20T13:50:29","slug":"creating-recommender-system-part-two","status":"publish","type":"post","link":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/","title":{"rendered":"Creating a Recommender System (Part II)"},"content":{"rendered":"<p style=\"text-align: justify;\">After the resounding success of\u00a0<a href=\"http:\/\/blog.stratio.com\/creating-a-recommender-system-part-i\/\" target=\"_blank\" rel=\"noopener\">the first article<\/a>\u00a0on recommender systems, \u00c1lvaro Santos is back with some further insight into creating a recommender system.<\/p>\n<p style=\"text-align: justify;\"><strong>Coming soon:<\/strong>\u00a0A follow-up Meetup in Madrid to go even further into this exciting topic.\u00a0<a href=\"https:\/\/www.meetup.com\/the-data-science-meetup\/\" target=\"_blank\" rel=\"noopener\">Stay tuned!<\/a><\/p>\n<p style=\"text-align: justify;\">***<\/p>\n<p style=\"text-align: justify;\">In the previous\u00a0<a href=\"http:\/\/blog.stratio.com\/creating-a-recommender-system-part-i\/\" target=\"_blank\" rel=\"noopener\">article of this series<\/a>, we explained what a recommender system is, describing its main parts and providing some basic algorithms which are frequently used in these systems. We also explained how to code some functions to read JSON files and to map the data in MongoDB and ElasticSearch using Spark SQL and Spark connectors.<\/p>\n<p style=\"text-align: justify;\">This second part will cover:<\/p>\n<ul style=\"text-align: justify;\">\n<li>Generating our\u00a0<em>Collaborative Filtering<\/em>\u00a0model.<\/li>\n<li>Pre-calculating product \/ user recommendations.<\/li>\n<li>Launching a small\u00a0<em>REST<\/em>\u00a0server to interact with the recommender.<\/li>\n<li>Querying the data store to retrieve content-based recommendations.<\/li>\n<li>Mixing the different types of recommendations to create a<em>\u00a0hybrid recommender<\/em>.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><!--more--><\/p>\n<h2 style=\"text-align: justify;\">Collaborative Filtering Algorithm<\/h2>\n<p style=\"text-align: justify;\">In this recommender service example, we have chosen ALS or Alternating Least Squares as the algorithm for Collaborative Filtering. Although ALS is the only algorithm implemented by Spark for this matter, it has been broadly tested and shown to have a good performance. It is perfectly suited for this project example.<\/p>\n<p style=\"text-align: justify;\">You can learn more about\u00a0<em>Alternating Least Squares<\/em>\u00a0<a href=\"http:\/\/bugra.github.io\/work\/notes\/2014-04-19\/alternating-least-squares-method-for-collaborative-filtering\/\">at this link<\/a>.<\/p>\n<h2 style=\"text-align: justify;\">Recommender Trainer<\/h2>\n<p style=\"text-align: justify;\">In this section, we will code the program that will create our\u00a0<em>Collaborative Filtering<\/em>\u00a0model. It will pre-calculate all recommendations to ensure a faster service.<\/p>\n<p style=\"text-align: justify;\">First of all, we should\u00a0read all the reviews from\u00a0<em>MongoDB<\/em>:<\/p>\n<pre class=\"lang:default decode:true\">def reviewStructure(): List[StructField] = {\n    List(\n      StructField(\"_id\", StringType),\n      StructField(\"reviewId\", StringType),\n      StructField(\"userId\", StringType),\n      StructField(\"productId\", StringType),\n      StructField(\"title\", StringType),\n      StructField(\"overall\", DoubleType),\n      StructField(\"content\", StringType),\n      StructField(\"date\", DateType)\n    )\n}\n\nval mongoRDD = sqlContext.fromMongoDB(reviewsConfig.build(),\n Option(StructType(reviewStructure)))\n\nmongoRDD.registerTempTable(\"reviews\")\n\nval ratingsDF = sqlContext.sql(\"select userId, productId, overall from reviews where userId is not null and productId is not null and overall is not null\").cache\n<\/pre>\n<p style=\"text-align: justify;\">The data cannot however be used by the Spark API &#8220;as it comes&#8221; from the DB. We must transform our ratings&#8217;\u00a0<em>Dataframe<\/em>\u00a0into a RDD of Spark ratings:<\/p>\n<pre class=\"lang:default decode:true \">val ratingsRDD = ratingsDF.map { row =&gt;\n  Rating(row.getAs[String](\"userId\").hashCode,\n         row.getAs[String](\"productId\").hashCode,\n         row.getAs[Double](\"overall\").toFloat \/ MAX_RATING)}\n<\/pre>\n<p>Now it is time to create our ALS model:<\/p>\n<pre class=\"lang:default decode:true \">val rank = 10\nval numIterations = 10\nval model = ALS.train(ratingsRDD, rank, numIterations, 0.01)\n<\/pre>\n<p style=\"text-align: justify;\">Once we have trained the model, the next step is to pre-calculate the recommendations. We should however, firstly\u00a0create two lists with the products and users:<\/p>\n<pre class=\"lang:default decode:true \">val usersRDD = ratingsDF.map(row =&gt; row.getAs[String](\"userId\"))\n                        .map(userId =&gt; (userId.hashCode, userId))\n\nval productsRDD = ratingsDF.map(row =&gt; row.getAs[String](\"productId\"))\n                           .map(productId =&gt; (productId.hashCode, productId))\nval productsMap: Broadcast[Map[Int, String]] = sc.broadcast(productsRDD.collect().toMap)\n<\/pre>\n<p>Then we need to calculate the user recommendations using the Spark API and save the data to MongoDB:<\/p>\n<pre class=\"lang:default decode:true \">val userRecs: RDD[Row] = model.recommendProductsForUsers(maxRecs)\n      .join(usersRDD).map { case (userIdInt, (ratings, userId)) =&gt;\n            Row(userId, ratings.map { rating =&gt;\n                Row(productsMap.value.get(rating.product).get,rating.rating)        \n             }.toList)}\n\nval userRecsConfig = ...\n\nsqlContext.createDataFrame(userRecs, StructType(userRecsStructure))\n          .saveToMongodb(userRecsConfig.build)\n<\/pre>\n<p style=\"text-align: justify;\">Finally, we have to pre-calculate the product recommendations. Spark does not provide a direct way of calculating the recommendations for products. We will therefore measure the similarity of the products using the\u00a0<em>cosine similarity<\/em>:<\/p>\n<pre class=\"lang:default decode:true \">def cosineSimilarity(vec1: DoubleMatrix, vec2: DoubleMatrix): Double = {\n  vec1.dot(vec2) \/ (vec1.norm2() * vec2.norm2())\n}\n\nval productsRecs = productsMap.toList.map { case (idInt, id) =&gt;\n  val itemFactor = model.productFeatures.lookup(idInt).head\n  val itemVector = new DoubleMatrix(itemFactor)\n\n  val sims: RDD[(String, Double)] = model.productFeatures\n                                         .map { case (currentIdInt, factor) =&gt;\n    val currentId = productsMap(currentIdInt)\n\n    val factorVector = new DoubleMatrix(factor)\n    val sim = cosineSimilarity(factorVector, itemVector)\n\n    (currentId, sim)\n  }\n\n  val recs = sims.filter { case (currentId, sim) =&gt; currentId != id }\n    .top(maxRecs)(Ordering.by[(String, Double), Double]\n                 { case (currentId, sim) =&gt; sim })\n    .map { case (currentId, sim) =&gt; Row(currentId, sim) }.toList\n\n  Row(id, recs)\n}\nval productRecsRDD: RDD[Row] = sc.parallelize(productsRecs)\n\nval productRecsConfig = ...\n\nsqlContext.createDataFrame(productRecsRDD, StructType(productRecsStructure))\n  .saveToMongodb(productRecsConfig.build)\n<\/pre>\n<h2>Recommender Service<\/h2>\n<p style=\"text-align: justify;\">After saving all the products\/previews and the pre-calculated\u00a0<em>Collaborative Filtering<\/em>\u00a0recommendations in the DBs, it is time to create a simple REST services that will retrieve the final recommendations. For that purpose we have selected the framework Spray.io, which is simple, elegant and pure Scala.<\/p>\n<p style=\"text-align: justify;\">Creating URL mappings for our recommender service is very simple:<\/p>\n<pre class=\"lang:default decode:true \">startServer(interface = \"localhost\", port = serverPort) {\n  path(\"recs\" \/ \"cf\" \/ \"pro\") {\n    post(\n      entity(as[ProductRecommendationRequest]) { request =&gt;\n        complete {\n          RecommenderService.getCollaborativeFilteringRecommendations(request)\n                            .toStream\n        }\n      }\n    )\n  } ~\n  path(\"recs\" \/ \"cf\" \/ \"usr\") {\n    post(\n      entity(as[UserRecommendationRequest]) { request =&gt;\n        complete {\n          RecommenderService.getCollaborativeFilteringRecommendations(request)\u00e7\n                            .toStream\n        }\n      }\n    )\n  } ~\n  ...\n<\/pre>\n<p style=\"text-align: justify;\">Now it is time to code our recommendation services. \u00a0We should start with the\u00a0<em>Collaborative Filtering<\/em>\u00a0recommendations. In this case it is simple because they have been pre-calculated. So we can just read them from\u00a0<em>MongoDB<\/em>:<\/p>\n<pre class=\"lang:default decode:true \">#User CF Recs\ndef parseUserRecs(o: DBObject, maxItems: Int): List[Recommendation] = {\n  o.getAs[MongoDBList](\"recs\").getOrElse(MongoDBList())\n                              .map { case (o: DBObject) =&gt; parseRec(o) }\n                              .toList.sortBy(x =&gt; x.rating).reverse.take(maxItems)\n}\n\nval listRecs = mongoClient(mongoConf.db)(ALSTrainer.PRODUCT_RECS_COLLECTION_NAME)\n                 .findOne(MongoDBObject(\"productId\" -&gt; productId))\n                 .getOrElse(MongoDBObject())\n\nval userRecs = parseProductRecs(listRecs, MAX_RECOMMENDATIONS)\n\n\n#Product CF Recs\n\ndef parseProductRecs(o: DBObject, maxItems: Int): List[Recommendation] = {\n  o.getAs[MongoDBList](\"recs\").getOrElse(MongoDBList())\n                              .map { case (o: DBObject) =&gt; parseRec(o) }\n                              .toList.sortBy(x =&gt; x.rating).reverse.take(maxItems)\n}\n\nval listRecs = mongoClient(mongoConf.db)(ALSTrainer.USER_RECS_COLLECTION_NAME)\n                .findOne(MongoDBObject(\"userId\" -&gt; userId))\n                .getOrElse(MongoDBObject())\n\nval productRecs = parseProductRecs(listRecs, MAX_RECOMMENDATIONS)\n<\/pre>\n<p style=\"text-align: justify;\">Then we should code the\u00a0<em>content-based recommendations<\/em>. Although we have not pre-calculated these types of recommendations, it is quite simple to obtain them using<em>\u00a0ElasticSearch<\/em>. To do this, we need to ask the server which products match certain criteria more:<\/p>\n<pre class=\"lang:default decode:true\">def parseESResponse(response: SearchResponse): List[Recommendation] = {\n  response.getHits match {\n    case null =&gt; List[Recommendation]()\n    case hits: SearchHits if hits.getTotalHits == 0 =&gt; List[Recommendation]()\n    case hits: SearchHits if hits.getTotalHits &gt; 0 =&gt; hits.getHits.map { hit =&gt; new Recommendation(hit.getId, hit.getScore) }.toList\n  }\n}\n\n#Similar Products CB Recs\nval indexName = esConf.index\nval q = QueryBuilders.moreLikeThisQuery(\"name\", \"features\")\n          .addLikeItem(new MoreLikeThisQueryBuilder.Item(indexName, DatasetIngestion.PRODUCTS_INDEX_NAME, productId))\n\nval similarRecs = parseESResponse(esClient.prepareSearch().setQuery(q)\n                                .setSize(MAX_RECOMMENDATIONS)\n                                .execute().actionGet())\n\n#Text Search CB Recs\nval indexName = esConf.index\nval q = QueryBuilders.multiMatchQuery(text, \"name\", \"features\")\n\nval textRecs = parseESResponse(esClient.prepareSearch().setQuery(q)\n                                .setSize(MAX_RECOMMENDATIONS)\n                                .execute().actionGet())\n<\/pre>\n<p>For hybrid recommendations, the theory is simple: use different types of recommendations and combine their output using weights.<\/p>\n<pre class=\"lang:default decode:true\">val cbRatingFactor = 1 - cfRatingFactor\n\nval cfRecs = findProductCFRecs(productId, ALSTrainer.MAX_RECOMMENDATIONS)\n               .map(x =&gt; new HybridRecommendation(x.productId, x.rating, x.rating * cfRatingFactor))\n\nval cbRecs = findContentBasedMoreLikeThisRecommendations(productId, ALSTrainer.MAX_RECOMMENDATIONS)\n                .map(x =&gt; new HybridRecommendation(x.productId, x.rating, x.rating * cbRatingFactor))\n\nval finalRecs = cfRecs ::: cbRecs\n\nval hyvrid = finalRecs.sortBy(x =&gt; -x.hybridRating).take(maxItems)\n<\/pre>\n<h2>Conclusions<\/h2>\n<p>In the second part of the series, we have learnt how to:<\/p>\n<p>1.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Create\u00a0<em>Collaborative Filtering<\/em>\u00a0recommendations using\u00a0<em>Spark<\/em>.<\/p>\n<p>2.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Obtain content-based recommendations using<em>\u00a0ElasticSearch<\/em>.<\/p>\n<p>3.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Combine several types of recommendations to create a\u00a0<em>hybrid recommender<\/em>.<\/p>\n<p>If you are interested in finding out more, the code is freely available in my\u00a0<a href=\"https:\/\/github.com\/alvsanand\/spark_recommender\" target=\"_blank\" rel=\"noopener\">Github repository.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>After the resounding success of the first article on recommender systems, \u00c1lvaro Santos is back with some further insight into creating a recommender system. Coming soon: A follow-up Meetup in Madrid to go even further into this exciting topic. Stay tuned!<\/p>\n","protected":false},"author":1,"featured_media":950,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[686],"tags":[],"ppma_author":[795],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v22.9 (Yoast SEO v22.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Creating a Recommender System (Part II)<\/title>\n<meta name=\"description\" content=\"Further insight into creating recommender systems: Collaborative Filtering model, calculating product\/user recommendations, hybrid recommender...\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating a Recommender System (Part II)\" \/>\n<meta property=\"og:description\" content=\"Further insight into creating recommender systems: Collaborative Filtering model, calculating product\/user recommendations, hybrid recommender...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/\" \/>\n<meta property=\"og:site_name\" content=\"Stratio\" \/>\n<meta property=\"article:published_time\" content=\"2017-01-05T11:17:42+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-20T13:50:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"730\" \/>\n\t<meta property=\"og:image:height\" content=\"312\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"Stratio\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:site\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Stratio\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/\"},\"author\":{\"name\":\"Stratio\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7\"},\"headline\":\"Creating a Recommender System (Part II)\",\"datePublished\":\"2017-01-05T11:17:42+00:00\",\"dateModified\":\"2023-09-20T13:50:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/\"},\"wordCount\":569,\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif\",\"articleSection\":[\"Product\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/\",\"url\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/\",\"name\":\"Creating a Recommender System (Part II)\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif\",\"datePublished\":\"2017-01-05T11:17:42+00:00\",\"dateModified\":\"2023-09-20T13:50:29+00:00\",\"description\":\"Further insight into creating recommender systems: Collaborative Filtering model, calculating product\/user recommendations, hybrid recommender...\",\"breadcrumb\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage\",\"url\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif\",\"contentUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif\",\"width\":730,\"height\":312,\"caption\":\"Recommdender System II\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.stratio.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating a Recommender System (Part II)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"name\":\"Stratio Blog\",\"description\":\"Corporate blog\",\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.stratio.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\",\"name\":\"Stratio\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"contentUrl\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"width\":260,\"height\":55,\"caption\":\"Stratio\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/stratiobd\",\"https:\/\/es.linkedin.com\/company\/stratiobd\",\"https:\/\/www.youtube.com\/c\/StratioBD\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7\",\"name\":\"Stratio\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/bb38888f58c2bb664646155f78ae6ccc\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g\",\"caption\":\"Stratio\"},\"description\":\"Stratio guides businesses on their journey through complete #DigitalTransformation with #BigData and #AI. Stratio works worldwide for large companies and multinationals in the sectors of banking, insurance, healthcare, telco, retail, energy and media.\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Creating a Recommender System (Part II)","description":"Further insight into creating recommender systems: Collaborative Filtering model, calculating product\/user recommendations, hybrid recommender...","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/","og_locale":"en_US","og_type":"article","og_title":"Creating a Recommender System (Part II)","og_description":"Further insight into creating recommender systems: Collaborative Filtering model, calculating product\/user recommendations, hybrid recommender...","og_url":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/","og_site_name":"Stratio","article_published_time":"2017-01-05T11:17:42+00:00","article_modified_time":"2023-09-20T13:50:29+00:00","og_image":[{"width":730,"height":312,"url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif","type":"image\/gif"}],"author":"Stratio","twitter_card":"summary_large_image","twitter_creator":"@stratiobd","twitter_site":"@stratiobd","twitter_misc":{"Written by":"Stratio","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#article","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/"},"author":{"name":"Stratio","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7"},"headline":"Creating a Recommender System (Part II)","datePublished":"2017-01-05T11:17:42+00:00","dateModified":"2023-09-20T13:50:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/"},"wordCount":569,"publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif","articleSection":["Product"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/","url":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/","name":"Creating a Recommender System (Part II)","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif","datePublished":"2017-01-05T11:17:42+00:00","dateModified":"2023-09-20T13:50:29+00:00","description":"Further insight into creating recommender systems: Collaborative Filtering model, calculating product\/user recommendations, hybrid recommender...","breadcrumb":{"@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#primaryimage","url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif","contentUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/10\/Recomendation_system3.gif","width":730,"height":312,"caption":"Recommdender System II"},{"@type":"BreadcrumbList","@id":"https:\/\/www.stratio.com\/blog\/creating-recommender-system-part-two\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.stratio.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Creating a Recommender System (Part II)"}]},{"@type":"WebSite","@id":"https:\/\/www.stratio.com\/blog\/#website","url":"https:\/\/www.stratio.com\/blog\/","name":"Stratio Blog","description":"Corporate blog","publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.stratio.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.stratio.com\/blog\/#organization","name":"Stratio","url":"https:\/\/www.stratio.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","contentUrl":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","width":260,"height":55,"caption":"Stratio"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/stratiobd","https:\/\/es.linkedin.com\/company\/stratiobd","https:\/\/www.youtube.com\/c\/StratioBD"]},{"@type":"Person","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7","name":"Stratio","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/bb38888f58c2bb664646155f78ae6ccc","url":"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g","caption":"Stratio"},"description":"Stratio guides businesses on their journey through complete #DigitalTransformation with #BigData and #AI. Stratio works worldwide for large companies and multinationals in the sectors of banking, insurance, healthcare, telco, retail, energy and media."}]}},"authors":[{"term_id":795,"user_id":1,"is_guest":0,"slug":"stratioadmin","display_name":"Stratio","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/1080"}],"collection":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/comments?post=1080"}],"version-history":[{"count":10,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/1080\/revisions"}],"predecessor-version":[{"id":13945,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/1080\/revisions\/13945"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media\/950"}],"wp:attachment":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media?parent=1080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/categories?post=1080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/tags?post=1080"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}