Multidimensional Approach To Recommender Systems
Introduction
When it comes to recommender systems, I always remember the title song of 80’s sitcom, "Cheers". Here is how:
"You wanna go where people know, people are all the same" - Content-based
"You wanna be where you can see, our troubles are all the same" - Colloborative-filtering
"Taking a break from all your worries, sure would help a lot. Wouldn’t you like to get away?" ….Where, with whom? - Context-Aware.
Here I like to present a restaurant recommendation based on contextual information using Neo4j.
What is Context?
Context is any information that can be used to characterize the situation of an entity. An entity is a person, place, or object that is considered relevant to the interaction between a user and an application, including the user and applications themselves (AK Dey & GD Abowd - ACM Conference on Human Factors in Computer Systems (CHI 2000), Vol.5/Iss.1, pp.4-7, 2001).
Most common types of context are Identity ('who'), Acivity ('what'), Time ('when'), and location ('where') and one can use this information to determine 'why' the situation is occuring.
Traditional recommender systems use two entities (two dimensional) users and items. This recommendation can be made more personalized by using a multidimensional approach to include contextual information.
Apply to Restaurant Recommendation
Imported restaurant and consumer data (that relates to Mexico) from https://archive.ics.uci.edu/ml/datasets/Restaurant+%26+consumer+data.
User data has location, habits (like smoking, drinking), marital status, cuisine, budget, and many other pieces of information. For users, we can take each context (like smoking, cuisine, budget) as one dimension.
Data on restaurants includes location, cuisine, smoking, alocohol, price and other information. For restaurants too we will have multiple dimensions to offer a better choice of restaurants based on user preferences.
A pictorial description of a three dimensional approach is shown below:
The three dimensions in the user cube are user, smoking, cuisine and for the restaurant cube they are restaurant, smoking, cuisine. The colored slice of the user cube represents the users who like same cuisine with varying presferences for smoking. These choices will then be used to select restaurants that match the selected user choices. The colored slice of the restaurant cube presents the restaurants that match the user selected choices.
Same approach is applicable to even higher dimensions.
Setup
Four data files: Users_50.csv (selected 50 users) UCuisine.csv (users/cuisine) Restaurants.csv RestCuisine.csv (restaurants/cuisine)
Cypher queries to setup the database
Used this query for better visualization of both USER_PROFILE and RESTAURANT paths:
MATCH (c)-[r:USER_PROFILE|RESTAURANT]->(n)-[]->(p)
WHERE n.uid IN['U1001', 'U1002', 'U1003'] or n.pid IN [132609, 132613, 132630]
RETURN c, n, p LIMIT 20;
Left half is Restaurant and the right half is User Profile.
Recommend Restaurants Based On User Preferences
Three preferences: Mexican food, non-smoking, and medium priced.
//Users with selected choices..............
MATCH (c)-[]->(n)-[:CUISINE]->(r)-[:LIKES]->(t:Food {name: "Mexican"})
WITH COLLECT (n) as nodes, t
UNWIND nodes as n1
MATCH (c)-[]->(n1)-[:HABITS]->(q)-[:SMOKER]->(v:Smoker {attr1: "false"})
WITH COLLECT (n1) as nodes, t, v
UNWIND nodes as n2
MATCH (c)-[]->(n2)-[:HABITS]->(q)-[:BUDGET]->(v1:Budget {attr13: "medium"})
WITH v1, t, v MATCH (c)-[]->(n)-[:CUISINE]->(r)-[:LIKES]->(t:Food {name: "Mexican"})
WITH COLLECT (n) as nodes, t
UNWIND nodes as n1
MATCH (c)-[]->(n1)-[:HABITS]->(q)-[:SMOKER]->(v:Smoker {attr1: "false"})
WITH COLLECT (n1) as nodes, t, v
UNWIND nodes as n2
MATCH (c)-[]->(n2)-[:HABITS]->(q)-[:BUDGET]->(v1:Budget {attr13: "medium"})
WITH v1, t
//WITH v1, t, v1, n2
//RETURN n2.uid as User, t.name as Cuisine, v.attr1 as Smoker, v1.attr13 as Budget;
// Find the restaurants that match the user preferences......
MATCH (c)-[]->(n2)-[:REST_CUISINE]->(p:Cusine {name: t.name})
WITH COLLECT(n2) as pn, v1
UNWIND pn as n3
MATCH (c)-[]->(n3)-[:FEATURES]->(q1:Features {price: v1.attr13, smoking: "none"})
WITH COLLECT(n3) as pn
UNWIND pn as n4
WITH DISTINCT n4
MATCH (c)-[]->(n4)-[:ADDRESS]-(k)
RETURN n4.name as Restaurant, k.city as City;
Four preferences: Japanese food, non-smoking, medium priced, and ambience (friends).
MATCH (c)-[]->(n)-[:CUISINE]->(r)-[:LIKES]->(t:Food {name: "Japanese"})
WITH COLLECT (n) as nodes, t
UNWIND nodes as n1
MATCH (c)-[]->(n1)-[:HABITS]->(q)-[:SMOKER]->(v:Smoker {attr1: "false"})
WITH COLLECT (n1) as nodes, t, v
UNWIND nodes as n2
MATCH (c)-[]->(n2)-[:HABITS]->(q)-[:BUDGET]->(v1:Budget {attr13: "medium"})
WITH COLLECT (n2) as nodes, t, v, v1
UNWIND nodes as n3
MATCH (c)-[]->(n3)-[:HABITS]->(q)-[:AMBIENCE]->(v2:Ambnce {attr4: "friends"})
WITH COLLECT (n3) as nodes, t, v, v1, v2
UNWIND nodes as n4
WITH t, v1
//WITH v, t, v1, v2, n4
//RETURN n4.uid as User, t.name as Cuisine, v.attr1 as Smoker, v1.attr13 as Budget, v2.attr4 as Ambience;
MATCH (c)-[]->(n2)-[:REST_CUISINE]->(p:Cusine {name: t.name})
WITH COLLECT(n2) as pn, v1
UNWIND pn as n3
MATCH (c)-[]->(n3)-[:FEATURES]->(q1:Features {price: v1.attr13, smoking: "none", ambience: "familiar"})
WITH COLLECT(n3) as pn2
UNWIND pn2 as n4
WITH DISTINCT n4
MATCH (c)-[]->(n4)-[:ADDRESS]-(k)
RETURN n4.name as Restaurant, k.city as City;
Conclusions…
A more personnalized recommendation of restaurants is presented based on user preferences. One problem here is the availability of relevant datasets. The more information the dataset provides, the more helpful it would be for the analysis and results.
Resources
Datasets:
https://github.com/kaisesha/cdrgraph/blob/master/RestCuisine.csv https://github.com/kaisesha/cdrgraph/blob/master/Restaurants.csv https://github.com/kaisesha/cdrgraph/blob/master/UCuisine.csv https://github.com/kaisesha/cdrgraph/blob/master/Users_50.csv
Created by {Kamal Murthy} Email: ameyasoft@gmail.com
Is this page helpful?