public static List <double> MoviesBasedOnUserProfile(int userSK, int mSK) { List <double> EvalData = new List <double>(); var Movies = GraphConfig.GraphClient.Cypher .Match("(p:UserDim { UserSK: {userSK}})<-[e: ratedUser]-(f:FactTable{flag:0})-[g: ratedMovie]->(h:MovieDim)") .With("SQRT(REDUCE(xDot = 0.0, a IN COLLECT(f.Rating - h.avgRate) | xDot + a^2)) AS xLength") .OptionalMatch("(p1:UserDim { UserSK: {userSK}})<-[x: ratedUser]-(f1:FactTable{flag:0})-[r1: ratedMovie]->(m:MovieDim)<-[r2: ratedMovie]-(f2:FactTable)-[y: ratedUser]->(p2:UserDim)") .With("xLength, collect(m.MovieSK) as mov, count(m) as movieCount, SUM((f1.Rating - m.avgRate) * (f2.Rating - m.avgRate)) AS xyDotProduct, " + "SQRT(REDUCE(yDot = 0.0, b IN COLLECT(f2.Rating - m.avgRate) | yDot + b ^ 2)) AS yLength, p1, p2") .WithParam("userSK", userSK) .With("p1, p2, xyDotProduct / (xLength* yLength) as similarity, mov") .OrderByDescending("similarity") .Limit(3) .OptionalMatch("(p2)<-[a: ratedUser]-(f3:FactTable)-[b: ratedMovie]->(m1:MovieDim)") .Where("NOT m1.MovieSK IN mov and m1.MovieSK <> {movieSK}") .WithParam("movieSK", mSK) .With("f3, mov, m1, p2, round(100*avg(f3.Rating))/100 as avgRating") .Return((m1, avgRating) => new { movie = Return.As <MovieDim>("m1"), averageRating = Return.As <double>("avgRating") }) .OrderByDescending("f3.Rating") //.Limit(50) .Results.ToList(); //find TP, FP, FN and TN double TP = 0, FP = 0, FN = 0, TN = 0; double Threshold = GetThreshold(userSK); List <FactTable> ReservedMovieDim = GetReserved(userSK); for (int k = 0; k < Movies.Count; k++) { int movieSK = Movies[k].movie.MovieSK; double movRat = Movies[k].averageRating; if (ReservedMovies.Contains(movieSK)) { FactTable movieItem = new FactTable(); foreach (FactTable resMov in ReservedMovieDim) { if (resMov.MovieSK == movieSK) { movieItem = resMov; } } if (movRat >= Threshold) { if (movieItem.Rating >= Threshold) { TP += 1; } else { FP += 1; } } else //when similiar user avg rating is less then threshold { if (movieItem.Rating >= Threshold) { FN += 1; } else { TN += 1; } } } else { TN += 1; } } double recall = TP / (TP + FP); double precision = TP / (TP + FN); Console.WriteLine("TP: " + TP + ", FP: " + FP + ", FN: " + FN + ", TN: " + TN); EvalData.Add(recall); EvalData.Add(precision); EvalData.Add(TP); EvalData.Add(FP); EvalData.Add(FN); EvalData.Add(TN); //List<int> common = ReservedMovies.Intersect(Movies).ToList(); //if (ReservedMovies.Count > 0) //{ // double recall = (common.Count * 100) / (ReservedMovies.Count); // double precision = (common.Count * 100) / (Movies.Count); // EvalData.Add((common.Count * 100) / (ReservedMovies.Count)); // Recall // EvalData.Add((common.Count * 100) / (Movies.Count)); //Precision //} return(EvalData); }
public static List <double> ContentBasedEval(int userSK, int MovieSK) { List <double> EvalData = new List <double>(); List <MovieDim> Movies = GraphConfig.GraphClient.Cypher .Match("(m: MovieDim{ MovieSK: {SK}})") .Match("(m) -[:belongsToGenre]->(g: GenreDim) < -[:belongsToGenre] - (simMov: MovieDim)") .Where("not(simMov)-[] - (: FactTable{ UserSK: {userSK}, flag: 0})") .With("m, simMov, COUNT(*) AS gCount") .OptionalMatch("(m)< -[:hasATag] - (a: TagDim) -[:hasATag]->(simMov)") .With("m, simMov, gCount, COUNT(a) AS tCount") .OptionalMatch("(m)< -[:ratedMovie] - (d: FactTable) -[:ratedMovie]->(simMov)") .With("m, simMov, gCount, tCount, COUNT(d) AS rCount") .With("simMov AS movies, (5* gCount)+(2* tCount)+(3* rCount) AS Weight") .WithParam("SK", MovieSK) .WithParam("userSK", userSK) .Return <MovieDim>("movies") .OrderByDescending("Weight") //.Limit(50) .Results.ToList(); //find TP, FP, FN and TN double TP = 0, FP = 0, FN = 0, TN = 0; double Threshold = GetThreshold(userSK); List <FactTable> ReservedMovieDim = GetReserved(userSK); foreach (MovieDim movie in Movies) { int movieSK = movie.MovieSK; double movRat = movie.avgRate; if (ReservedMovies.Contains(movieSK)) { FactTable movieItem = new FactTable(); foreach (FactTable resMov in ReservedMovieDim) { if (resMov.MovieSK == movieSK) { movieItem = resMov; } } if (movRat >= Threshold) { if (movieItem.Rating >= Threshold) { TP += 1; } else { FP += 1; } } else //when similiar user avg rating is less then threshold { if (movieItem.Rating >= Threshold) { FN += 1; } else { TN += 1; } } } else { TN += 1; } } double recall = TP / (TP + FP); double precision = TP / (TP + FN); //Console.WriteLine("TP: " + TP + ", FP: " + FP + ", FN: " + FN + ", TN: " + TN); EvalData.Add(recall); EvalData.Add(precision); EvalData.Add(TP); EvalData.Add(FP); EvalData.Add(FN); EvalData.Add(TN); return(EvalData); }