Created
September 30, 2019 19:32
-
-
Save cicorias/ebddbbb7381bcb9426b60c5092dc226e to your computer and use it in GitHub Desktop.
movie recommendations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "nbformat": 4, | |
| "nbformat_minor": 0, | |
| "metadata": { | |
| "colab": { | |
| "name": "Movie recomender.ipynb", | |
| "provenance": [] | |
| }, | |
| "kernelspec": { | |
| "name": "python3", | |
| "display_name": "Python 3" | |
| } | |
| }, | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "id": "jOiB1clWAqk4", | |
| "colab_type": "code", | |
| "outputId": "fab38c4b-6767-407a-c99c-33acbbcedcbb", | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 136 | |
| } | |
| }, | |
| "source": [ | |
| "import pandas as pd\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "def load_movielens():\n", | |
| "\n", | |
| " movies = pd.read_csv(\"movies.csv\", sep=',')\n", | |
| "\n", | |
| " ratings = pd.read_csv(\"ratings.csv\", sep=',')\n", | |
| "\n", | |
| " return movies, ratings\n", | |
| "\n", | |
| "\n", | |
| "def biparteMatrix(movies_frame, ratings_frame):\n", | |
| "\n", | |
| " \n", | |
| " user_ids = list(ratings_frame.userId.unique()) \n", | |
| " movie_ids = list(movies_frame.movieId.unique()) \n", | |
| "\n", | |
| " numberOfUsers = len(user_ids)\n", | |
| " numberOfMovies = len(movie_ids)\n", | |
| "\n", | |
| "\n", | |
| " user_movie_biparte = np.zeros((numberOfUsers, numberOfMovies))\n", | |
| "\n", | |
| "\n", | |
| " for name, group in ratings_frame.groupby([\"userId\", \"movieId\"]):\n", | |
| "\n", | |
| " \n", | |
| " userId, movieId = name\n", | |
| "\n", | |
| " user_index = user_ids.index(userId)\n", | |
| " movie_index = movie_ids.index(movieId)\n", | |
| " user_movie_biparte[user_index, movie_index] = group[[\"rating\"]].values[0,0]\n", | |
| "\n", | |
| " return user_movie_biparte\n", | |
| "\n", | |
| "\n", | |
| "def load():\n", | |
| "\n", | |
| "\n", | |
| " movies, ratings = load_movielens()\n", | |
| " matrix = biparteMatrix(movies, ratings)\n", | |
| "\n", | |
| " return matrix\n", | |
| "\n", | |
| "load() " | |
| ], | |
| "execution_count": 11, | |
| "outputs": [ | |
| { | |
| "output_type": "execute_result", | |
| "data": { | |
| "text/plain": [ | |
| "array([[4. , 0. , 4. , ..., 0. , 0. , 0. ],\n", | |
| " [0. , 0. , 0. , ..., 0. , 0. , 0. ],\n", | |
| " [0. , 0. , 0. , ..., 0. , 0. , 0. ],\n", | |
| " ...,\n", | |
| " [2.5, 2. , 2. , ..., 0. , 0. , 0. ],\n", | |
| " [3. , 0. , 0. , ..., 0. , 0. , 0. ],\n", | |
| " [5. , 0. , 0. , ..., 0. , 0. , 0. ]])" | |
| ] | |
| }, | |
| "metadata": { | |
| "tags": [] | |
| }, | |
| "execution_count": 11 | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "id": "Smw0D7OqA-rJ", | |
| "colab_type": "code", | |
| "colab": {} | |
| }, | |
| "source": [ | |
| "import operator\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "user_movie_matrix = load()\n", | |
| "\n", | |
| "def greedy():\n", | |
| "\n", | |
| " for row in user_movie_matrix:\n", | |
| "\n", | |
| " row = list(row) \n", | |
| " maxrating = max(row)\n", | |
| " print (user_movie_matrix[user_movie_matrix[row] == maxrating])\n", | |
| "\n", | |
| " pass\n", | |
| "\n", | |
| "\n", | |
| "def bfs_paths(graph, start, goal):\n", | |
| " flag = \"product\"\n", | |
| " queue = [(start, [start])]\n", | |
| " nonzero_indices = []\n", | |
| " while queue:\n", | |
| " (vertex, path) = queue.pop(0)\n", | |
| " if flag == \"product\":\n", | |
| " # the children nodes are the vertical of biparte matrix(nonzero)\n", | |
| " column = graph[:, [vertex]]\n", | |
| " nonzero_indices = column.nonzero()\n", | |
| " nonzero_indices = nonzero_indices[0]\n", | |
| " for child_index in nonzero_indices:\n", | |
| " row = graph[child_index]\n", | |
| " nonzero_row_indices = row.nonzero()[0]\n", | |
| "\n", | |
| " for row_index in nonzero_row_indices:\n", | |
| " if goal == row_index:\n", | |
| " yield path + [child_index]\n", | |
| " else:\n", | |
| " queue.append((row_index, path + [row_index]))\n", | |
| "\n", | |
| " \n", | |
| "def graph_search(biparte_matrix):\n", | |
| "\n", | |
| "\n", | |
| " # the user who is being recommeneded\n", | |
| " target_vector = biparte_matrix[0]\n", | |
| "\n", | |
| "\n", | |
| " bfs_all_roots = np.argpartition(target_vector, -10 )[-10:]\n", | |
| " bfs_roots = []\n", | |
| "\n", | |
| " for root in bfs_all_roots:\n", | |
| " if target_vector[root] != 0 :\n", | |
| " bfs_roots.append(root)\n", | |
| "\n", | |
| " \n", | |
| " path =[]\n", | |
| " data = {}\n", | |
| " for item_index in range(biparte_matrix.shape[0]):\n", | |
| " \n", | |
| " if target_vector[item_index] == 0:\n", | |
| " \n", | |
| " for root in bfs_roots:\n", | |
| " path.append( bfs_paths(biparte_matrix, root, item_index ))\n", | |
| " data[item_index] = path\n", | |
| " \n", | |
| " \n", | |
| " return data \n", | |
| "def user_base_collabertive_filtering(): \n", | |
| "\n", | |
| " for user in range(2):\n", | |
| " distances = []\n", | |
| " for anotheruser in range(user_movie_matrix.shape[0]):\n", | |
| " \n", | |
| " distance = np.linalg.norm(user_movie_matrix[user] - user_movie_matrix[anotheruser] )\n", | |
| " distances.append(distance) \n", | |
| "\n", | |
| " \n", | |
| " closest_all_indices=np.argpartition(distances, -20)[-20:]\n", | |
| " closest_indices = []\n", | |
| " for index in closest_all_indices:\n", | |
| " if distances[index] != 0:\n", | |
| " closest_indices.append(index)\n", | |
| " \n", | |
| " \n", | |
| " # consider the first five closest neighbors for the recommendation\n", | |
| "\n", | |
| " closest_indices.insert(0, user) \n", | |
| " biparte_matrix = user_movie_matrix[closest_indices[0:4]] \n", | |
| " # now execute the graph search for recommendation\n", | |
| " \n", | |
| " paths = graph_search(biparte_matrix)\n", | |
| " \n", | |
| " data= {} \n", | |
| " for item in paths.keys():\n", | |
| " print (item)\n", | |
| " weight = 0 \n", | |
| " allpaths = paths[item]\n", | |
| " for path in allpaths:\n", | |
| " depth = len(path)\n", | |
| " weight = weight + (0.5)**depth\n", | |
| " data[item] = weight \n", | |
| "\n", | |
| " # find the which movie has great weight:\n", | |
| " fav_movie = max(data.iteritems(), key=operator.itemgetter(1))[0] \n", | |
| " \n", | |
| "\n", | |
| "def get_movie_avg_rating(id, ratings):\n", | |
| " \n", | |
| " rating = 0\n", | |
| " for index, row in ratings.iterrows():\n", | |
| " if row[\"movieId\"] == id:\n", | |
| " rating = rating + row[\"rating\"] \n", | |
| " return rating\n", | |
| "\n", | |
| "\n", | |
| "def get_user_movie_rating( id, ratings, target_user):\n", | |
| "\n", | |
| " rating = 0\n", | |
| " df = ratings[ratings.userId == 1]\n", | |
| " for index, row in df.iterrows():\n", | |
| " if row[\"movieId\"] == id:\n", | |
| " rating = rating + row[\"rating\"] \n", | |
| " return rating\n", | |
| "\n", | |
| "\n", | |
| "def content_based_filtering():\n", | |
| "\n", | |
| " movies, ratings = load_movielens()\n", | |
| "\n", | |
| " target_user = 1\n", | |
| " \n", | |
| " movie_ids = []\n", | |
| " # movies watched by user\n", | |
| " for index, row in ratings.iterrows():\n", | |
| " if row[\"userId\"] == 1 :\n", | |
| " movie_ids.append(row[\"movieId\"])\n", | |
| " \n", | |
| " \n", | |
| " # compute the average of the ratings\n", | |
| " genre_dict = {}\n", | |
| " genre_count_dict = {}\n", | |
| " genre_ratio = {}\n", | |
| " for id in movie_ids:\n", | |
| " df = movies[movies.movieId == id]\n", | |
| " genres = []\n", | |
| " for index, row in df.iterrows():\n", | |
| " genres = row[\"genres\"]\n", | |
| " genres = genres.lower()\n", | |
| " genres = genres.split('|') \n", | |
| " \n", | |
| " rating = get_user_movie_rating(id, ratings, target_user =1 )\n", | |
| "\n", | |
| " for genre in genres:\n", | |
| " if genre in genre_dict.keys():\n", | |
| " genre_dict[genre] = genre_dict[genre] + rating\n", | |
| " genre_count_dict[genre] = genre_count_dict[genre] + 1\n", | |
| " else:\n", | |
| " genre_dict[genre] = rating \n", | |
| " genre_count_dict[genre] = rating\n", | |
| " \n", | |
| " for key in genre_dict.keys():\n", | |
| " ratio = genre_dict[key] / float(genre_count_dict[key])\n", | |
| " genre_dict[key] = ratio\n", | |
| " \n", | |
| " fav_genre = max(genre_dict.iteritems(), key=operator.itemgetter(1))[0]\n", | |
| " \n", | |
| " #best movies from that genre:\n", | |
| " \n", | |
| " genres_ids = []\n", | |
| " fav_movie_id = 0\n", | |
| " for index, row in movies.iterrows():\n", | |
| " genres = row['genres']\n", | |
| " genres = genres.lower()\n", | |
| " genres = genres.split('|')\n", | |
| " if fav_genre in genres:\n", | |
| " movie_rating = get_movie_avg_rating(row[\"movieId\"], ratings )\n", | |
| " if movie_rating > rating:\n", | |
| " fav_movie_id = row[\"movieId\"] \n", | |
| " rating = movie_rating\n", | |
| "\n", | |
| " print (\"content based recommended movie is:\")\n", | |
| " print (movies[movies.movieId == fav_movie_id])\n", | |
| "\n", | |
| " \n", | |
| " return fav_mov_id \n", | |
| "\n", | |
| "\n", | |
| "def evaluation():\n", | |
| "\n", | |
| " \n", | |
| " fav_mov_id_con = content_based_filtering()\n", | |
| "\n", | |
| " fav_mov_id_col = user_base_collabertive_filtering()\n", | |
| "\n", | |
| " \n", | |
| " for user in range(2):\n", | |
| " distances = []\n", | |
| " for anotheruser in range(user_movie_matrix.shape[0]):\n", | |
| " \n", | |
| " distance = np.linalg.norm(user_movie_matrix[user] - user_movie_matrix[anotheruser] )\n", | |
| " distances.append(distance) \n", | |
| "\n", | |
| " \n", | |
| " closest_all_indices=np.argpartition(distances, -20)[-20:]\n", | |
| " closest_indices = []\n", | |
| " for index in closest_all_indices:\n", | |
| " if distances[index] != 0:\n", | |
| " closest_indices.append(index)\n", | |
| "\n", | |
| " closest_indices.insert(0, user) \n", | |
| " biparte_matrix = user_movie_matrix[closest_indices[0:4]] \n", | |
| " \n", | |
| " \n", | |
| " target_col_vector =user_movie_matrix[0]\n", | |
| " target_con_vector = user_movie_matrix[0]\n", | |
| " \n", | |
| " score_col = 0\n", | |
| " score_con = 0\n", | |
| " for row in biparte_matrix: \n", | |
| " score_col = score_col + np.linalg.norm(row, target_col_vector)\n", | |
| " score_con = score_con + np.linalg.norm(row, target_con_vector)\n", | |
| "\n", | |
| "\n", | |
| " print (\"The collaberative filtering sum of distances is: \", score_col)\n", | |
| " print (\"The contend based filtering sum of distances is: \", score_con)" | |
| ], | |
| "execution_count": 0, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "id": "utj6xUCJHDiP", | |
| "colab_type": "code", | |
| "colab": {} | |
| }, | |
| "source": [ | |
| "" | |
| ], | |
| "execution_count": 0, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "metadata": { | |
| "id": "CjCrDW6dBGbP", | |
| "colab_type": "code", | |
| "colab": {} | |
| }, | |
| "source": [ | |
| "" | |
| ], | |
| "execution_count": 0, | |
| "outputs": [] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment