I am developing a simple social network with Java and Neo4j.
Users are able to submit the things they have already done and tag them with some tags. Also users can add some interests (which are tags, too). The system should recommend thing to the user that are not done by him yet. I have read some articles about collaborative filtering, where similarity is calculated between users. After similar users are found, some of the things they did but the logged user haven't done yet, will be perfect match for recommendations.
Here is the data model:
(me)-[:HAS_DONE]->(thing)-[:IS_TAGGED_WITH]->(tag)<-[:IS_TAGGED_WITH]-(theirThing)<-[:HAS_DONE]-(people)
(me)-[:HAS_DONE]->(thing)-[:IS_TAGGED_WITH]->(tag)<-[:IS_INTERESTED_IN]-(people)
(me)-[:IS_INTERESTED_IN]->(tag)<-[:IS_TAGGED_WITH]-(theirThing)<-[:HAS_DONE]-(people)
(me)-[:IS_INTERESTED_IN]->(tag)<-[:IS_INTERESTED_IN]-(people)
Collaborative filtering usually deals with some ratings.
For the case with tags, lets make the following notations:
U={u_1, u_2,..., u_n} - users
I={i_1, i_2,..., i_m} - interests
T={t_1, t_2,..., t_k} - things
UIsim(u_i, u_j) - the similarity of interests of two users. It is calculated by dividing the number of common interest to the maximum number of interests, added by one user.
UTsim(u_i, u_j) - the similarity of things of two users. It is calculated by dividing the number of common tags for things to the maximum number of tags, added by one user.
The final similarity between two users will be w1*UIsim(u_i, u_j)+w2*UTsim(u_i, u_j), where w1+w2=1.
Is it possible to implement this formula with Cypher? I mean is there a max
function? And will UNION
be appropriate for grouping the four cases?