{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" }, "colab": { "name": "Netflix Movie Recommendation System.ipynb", "version": "0.3.2", "provenance": [], "collapsed_sections": [], "machine_shape": "hm", "include_colab_link": true }, "accelerator": "GPU" }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "view-in-github", "colab_type": "text" }, "source": [ "\"Open" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Kqp39W9AGHII" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "qXxFUPPKGHIJ" }, "source": [ "

1. Business Problem

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "68x6gvapGHIK" }, "source": [ "

1.1 Problem Description

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "aE6iT69QGHIL" }, "source": [ "

\n", "Netflix is all about connecting people to the movies they love. To help customers find those movies, they developed world-class movie recommendation system: CinematchSM. Its job is to predict whether someone will enjoy a movie based on how much they liked or disliked other movies. Netflix use those predictions to make personal movie recommendations based on each customer’s unique tastes. And while Cinematch is doing pretty well, it can always be made better.\n", "

\n", "

Now there are a lot of interesting alternative approaches to how Cinematch works that netflix haven’t tried. Some are described in the literature, some aren’t. We’re curious whether any of these can beat Cinematch by making better predictions. Because, frankly, if there is a much better approach it could make a big difference to our customers and our business.

\n", "

Credits: https://www.netflixprize.com/rules.html

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Ne0jR1z6GHIM" }, "source": [ "

1.2 Problem Statement

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "DBuTSu8bGHIN" }, "source": [ "

\n", "Netflix provided a lot of anonymous rating data, and a prediction accuracy bar that is 10% better than what Cinematch can do on the same training data set. (Accuracy is a measurement of how closely predicted ratings of movies match subsequent actual ratings.) \n", "

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "JfA0haeYGHIP" }, "source": [ "

1.3 Sources

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "d76zFbnkGHIR" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Z1iliA-iGHIS" }, "source": [ "

1.4 Real world/Business Objectives and constraints

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "e0mcbCxNGHIT" }, "source": [ "Objectives:\n", "1. Predict the rating that a user would give to a movie that he ahs not yet rated.\n", "2. Minimize the difference between predicted and actual rating (RMSE and MAPE)\n", "
\n", "\n", "Constraints:\n", "1. Some form of interpretability." ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "y0xC5pTnGHIU" }, "source": [ "

2. Machine Learning Problem

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "PVtbZQwPGHIU" }, "source": [ "

2.1 Data

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "lrlJdwTHGHIV" }, "source": [ "

2.1.1 Data Overview

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "eKyUpY8TGHIW" }, "source": [ "

Get the data from : https://www.kaggle.com/netflix-inc/netflix-prize-data/data

\n", "

Data files : \n", "

\n", "
  \n",
        "The first line of each file [combined_data_1.txt, combined_data_2.txt, combined_data_3.txt, combined_data_4.txt] contains the movie id followed by a colon. Each subsequent line in the file corresponds to a rating from a customer and its date in the following format:\n",
        "\n",
        "CustomerID,Rating,Date\n",
        "\n",
        "MovieIDs range from 1 to 17770 sequentially.\n",
        "CustomerIDs range from 1 to 2649429, with gaps. There are 480189 users.\n",
        "Ratings are on a five star (integral) scale from 1 to 5.\n",
        "Dates have the format YYYY-MM-DD.\n",
        "
" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "pAdsJZkMGHIX" }, "source": [ "

2.1.2 Example Data point

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "tCsmW-lrGHIX" }, "source": [ "
\n",
        "1:\n",
        "1488844,3,2005-09-06\n",
        "822109,5,2005-05-13\n",
        "885013,4,2005-10-19\n",
        "30878,4,2005-12-26\n",
        "823519,3,2004-05-03\n",
        "893988,3,2005-11-17\n",
        "124105,4,2004-08-05\n",
        "1248029,3,2004-04-22\n",
        "1842128,4,2004-05-09\n",
        "2238063,3,2005-05-11\n",
        "1503895,4,2005-05-19\n",
        "2207774,5,2005-06-06\n",
        "2590061,3,2004-08-12\n",
        "2442,3,2004-04-14\n",
        "543865,4,2004-05-28\n",
        "1209119,4,2004-03-23\n",
        "804919,4,2004-06-10\n",
        "1086807,3,2004-12-28\n",
        "1711859,4,2005-05-08\n",
        "372233,5,2005-11-23\n",
        "1080361,3,2005-03-28\n",
        "1245640,3,2005-12-19\n",
        "558634,4,2004-12-14\n",
        "2165002,4,2004-04-06\n",
        "1181550,3,2004-02-01\n",
        "1227322,4,2004-02-06\n",
        "427928,4,2004-02-26\n",
        "814701,5,2005-09-29\n",
        "808731,4,2005-10-31\n",
        "662870,5,2005-08-24\n",
        "337541,5,2005-03-23\n",
        "786312,3,2004-11-16\n",
        "1133214,4,2004-03-07\n",
        "1537427,4,2004-03-29\n",
        "1209954,5,2005-05-09\n",
        "2381599,3,2005-09-12\n",
        "525356,2,2004-07-11\n",
        "1910569,4,2004-04-12\n",
        "2263586,4,2004-08-20\n",
        "2421815,2,2004-02-26\n",
        "1009622,1,2005-01-19\n",
        "1481961,2,2005-05-24\n",
        "401047,4,2005-06-03\n",
        "2179073,3,2004-08-29\n",
        "1434636,3,2004-05-01\n",
        "93986,5,2005-10-06\n",
        "1308744,5,2005-10-29\n",
        "2647871,4,2005-12-30\n",
        "1905581,5,2005-08-16\n",
        "2508819,3,2004-05-18\n",
        "1578279,1,2005-05-19\n",
        "1159695,4,2005-02-15\n",
        "2588432,3,2005-03-31\n",
        "2423091,3,2005-09-12\n",
        "470232,4,2004-04-08\n",
        "2148699,2,2004-06-05\n",
        "1342007,3,2004-07-16\n",
        "466135,4,2004-07-13\n",
        "2472440,3,2005-08-13\n",
        "1283744,3,2004-04-17\n",
        "1927580,4,2004-11-08\n",
        "716874,5,2005-05-06\n",
        "4326,4,2005-10-29\n",
        "
" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "qw41PPqqGHIY" }, "source": [ "

2.2 Mapping the real world problem to a Machine Learning Problem

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "gcl-ilooGHIc" }, "source": [ "

2.2.1 Type of Machine Learning Problem

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "LdnjiE2BGHId" }, "source": [ "
\n",
        "For a given movie and user we need to predict the rating would be given by him/her to the movie. \n",
        "The given problem is a Recommendation problem \n",
        "It can also seen as a Regression problem \n",
        "
" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "EBchxZGuGHIk" }, "source": [ "

2.2.2 Performance metric

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "sWvLhIk3GHIl" }, "source": [ "\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "GwDgl7vmGHIl" }, "source": [ "

2.2.3 Machine Learning Objective and Constraints

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "L03FzLdeGHIm" }, "source": [ "1. Minimize RMSE.\n", "2. Try to provide some interpretability." ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "uRN6G1IuGHIn", "colab": {} }, "source": [ "# this is just to know how much time will it take to run this entire ipython notebook \n", "from datetime import datetime\n", "# globalstart = datetime.now()\n", "import pandas as pd\n", "import numpy as np\n", "import matplotlib\n", "matplotlib.use('nbagg')\n", "# !pip install scikit-surprise\n", "import matplotlib.pyplot as plt\n", "plt.rcParams.update({'figure.max_open_warning': 0})\n", "\n", "import seaborn as sns\n", "sns.set_style('whitegrid')\n", "import os\n", "from scipy import sparse\n", "from scipy.sparse import csr_matrix\n", "%matplotlib inline\n", "from sklearn.decomposition import TruncatedSVD\n", "from sklearn.metrics.pairwise import cosine_similarity\n", "import random" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "mxd0uHQVOEF2", "colab_type": "code", "colab": {} }, "source": [ "" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "RM59l6hBJV1h", "colab_type": "code", "outputId": "0ec20cb1-347b-4b6b-caf3-6a5e11b7cd97", "colab": { "base_uri": "https://localhost:8080/", "height": 122 } }, "source": [ "from google.colab import drive\n", "drive.mount('/content/drive')" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdocs.test%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.photos.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpeopleapi.readonly&response_type=code\n", "\n", "Enter your authorization code:\n", "··········\n", "Mounted at /content/drive\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Nwow3bg2GHIq" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "rOKh2aUbGHIr" }, "source": [ "

3. Exploratory Data Analysis

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "y_bp2_o1GHIs" }, "source": [ "

3.1 Preprocessing

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "LnMF4vI4GHIs" }, "source": [ "

3.1.1 Converting / Merging whole data to required format: u_i, m_j, r_ij

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "70c17ed1-22c7-4938-ccec-26af46e51fa6", "id": "N-pTnvA8GHIt", "colab": {} }, "source": [ "start = datetime.now()\n", "if not os.path.isfile('/content/drive/My Drive/Netflix_recommender/data_folder/data.csv'):\n", " # Create a file 'data.csv' before reading it\n", " # Read all the files in netflix and store them in one big file('data.csv')\n", " # We re reading from each of the four files and appendig each rating to a global file 'train.csv'\n", " data = open('/content/drive/My Drive/Netflix_recommender/data_folder/data.csv', mode='w')\n", " \n", " row = list()\n", " files=['/content/drive/My Drive/Netflix_recommender/data_folder/combined_data_1.txt','/content/drive/My Drive/Netflix_recommender/data_folder/combined_data_2.txt', \n", " '/content/drive/My Drive/Netflix_recommender/data_folder/combined_data_3.txt', '/content/drive/My Drive/Netflix_recommender/data_folder/combined_data_4.txt']\n", " for file in files:\n", " print(\"Reading ratings from {}...\".format(file))\n", " with open(file) as f:\n", " for line in f: \n", " del row[:] # you don't have to do this.\n", " line = line.strip()\n", " if line.endswith(':'):\n", " # All below are ratings for this movie, until another movie appears.\n", " movie_id = line.replace(':', '')\n", " else:\n", " row = [x for x in line.split(',')]\n", " row.insert(0, movie_id)\n", " data.write(','.join(row))\n", " data.write('\\n')\n", " print(\"Done.\\n\")\n", " data.close()\n", "print('Time taken :', datetime.now() - start)" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Reading ratings from data_folder/combined_data_1.txt...\n", "Done.\n", "\n", "Reading ratings from data_folder/combined_data_2.txt...\n", "Done.\n", "\n", "Reading ratings from data_folder/combined_data_3.txt...\n", "Done.\n", "\n", "Reading ratings from data_folder/combined_data_4.txt...\n", "Done.\n", "\n", "Time taken : 0:05:03.705966\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "HlotH9C7GHIw" }, "source": [ " " ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "1c812d97-f4c5-4f0e-f209-8eaa56b0ab78", "id": "zbFHJAwSGHIx", "colab": { "base_uri": "https://localhost:8080/", "height": 102 } }, "source": [ "print(\"creating the dataframe from data.csv file..\")\n", "df = pd.read_csv('/content/drive/My Drive/Netflix_recommender/data_folder/data.csv', sep=',', \n", " names=['movie', 'user','rating','date'])\n", "df.date = pd.to_datetime(df.date)\n", "print('Done.\\n')\n", "\n", "# we are arranging the ratings according to time.\n", "print('Sorting the dataframe by date..')\n", "df.sort_values(by='date', inplace=True)\n", "print('Done..')" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "creating the dataframe from data.csv file..\n", "Done.\n", "\n", "Sorting the dataframe by date..\n", "Done..\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "7baa43b9-a133-4f1b-bb14-814eb0e07145", "id": "tXsJQB-CGHI1", "colab": { "base_uri": "https://localhost:8080/", "height": 204 } }, "source": [ "df.head()" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
movieuserratingdate
564319941034151018041999-11-11
9056171179851018051999-11-11
586987791077451018031999-11-11
48101611865151018021999-11-11
818932081466051018021999-11-11
\n", "
" ], "text/plain": [ " movie user rating date\n", "56431994 10341 510180 4 1999-11-11\n", "9056171 1798 510180 5 1999-11-11\n", "58698779 10774 510180 3 1999-11-11\n", "48101611 8651 510180 2 1999-11-11\n", "81893208 14660 510180 2 1999-11-11" ] }, "metadata": { "tags": [] }, "execution_count": 4 } ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "f20024d3-5648-4843-a0f1-8292aabc5d4f", "id": "KB8urNZWGHI3", "colab": { "base_uri": "https://localhost:8080/", "height": 170 } }, "source": [ "df.describe()['rating']" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "count 1.004805e+08\n", "mean 3.604290e+00\n", "std 1.085219e+00\n", "min 1.000000e+00\n", "25% 3.000000e+00\n", "50% 4.000000e+00\n", "75% 4.000000e+00\n", "max 5.000000e+00\n", "Name: rating, dtype: float64" ] }, "metadata": { "tags": [] }, "execution_count": 5 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "El0nKTF3GHI8" }, "source": [ "

3.1.2 Checking for NaN values

" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "159f6cf4-3cdf-471b-a4b6-8ce760c56bdb", "id": "bBoutCr8GHI9", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "# just to make sure that all Nan containing rows are deleted..\n", "print(\"No of Nan values in our dataframe : \", sum(df.isnull().any()))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "No of Nan values in our dataframe : 0\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "lBsgBgJOGHJF" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "p8fPR6NDGHJF" }, "source": [ "

3.1.3 Removing Duplicates

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "413c7499-8c64-4487-9f00-e5eaa04769d1", "id": "f4tN0DQ0GHJG", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "dup_bool = df.duplicated(['movie','user','rating'])\n", "dups = sum(dup_bool) # by considering all columns..( including timestamp)\n", "print(\"There are {} duplicate rating entries in the data..\".format(dups))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "There are 0 duplicate rating entries in the data..\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "a1ktiJ6KGHJI" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "EQSxmXy8GHJJ" }, "source": [ "

3.1.4 Basic Statistics (#Ratings, #Users, and #Movies)

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "a4bc67cd-6a7a-41c0-d75c-adc4bb80be98", "id": "vQVNTCjzGHJJ", "colab": { "base_uri": "https://localhost:8080/", "height": 119 } }, "source": [ "print(\"Total data \")\n", "print(\"-\"*50)\n", "print(\"\\nTotal no of ratings :\",df.shape[0])\n", "print(\"Total No of Users :\", len(np.unique(df.user)))\n", "print(\"Total No of movies :\", len(np.unique(df.movie)))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Total data \n", "--------------------------------------------------\n", "\n", "Total no of ratings : 100480507\n", "Total No of Users : 480189\n", "Total No of movies : 17770\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "xEnrVuKDGHJM" }, "source": [ "

3.2 Spliting data into Train and Test(80:20)

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "hBRN_GB2GHJN", "colab": {} }, "source": [ "if not os.path.isfile('/content/drive/My Drive/Netflix_recommender/data_folder/train.csv'):\n", " # create the dataframe and store it in the disk for offline purposes..\n", " df.iloc[:int(df.shape[0]*0.80)].to_csv(\"train.csv\", index=False)\n", "\n", "if not os.path.isfile('/content/drive/My Drive/Netflix_recommender/data_folder/test.csv'):\n", " # create the dataframe and store it in the disk for offline purposes..\n", " df.iloc[int(df.shape[0]*0.80):].to_csv(\"test.csv\", index=False)\n", "\n", "train_df = pd.read_csv(\"/content/drive/My Drive/Netflix_recommender/data_folder/train.csv\", parse_dates=['date'])\n", "test_df = pd.read_csv(\"/content/drive/My Drive/Netflix_recommender/data_folder/test.csv\")" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "FjI2Bwr5GHJV" }, "source": [ "

3.2.1 Basic Statistics in Train data (#Ratings, #Users, and #Movies)

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "d248bf9c-e7d2-48dd-a538-d12c53f32091", "id": "kUEUofOvGHJV", "colab": { "base_uri": "https://localhost:8080/", "height": 119 } }, "source": [ "# movies = train_df.movie.value_counts()\n", "# users = train_df.user.value_counts()\n", "print(\"Training data \")\n", "print(\"-\"*50)\n", "print(\"\\nTotal no of ratings :\",train_df.shape[0])\n", "print(\"Total No of Users :\", len(np.unique(train_df.user)))\n", "print(\"Total No of movies :\", len(np.unique(train_df.movie)))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training data \n", "--------------------------------------------------\n", "\n", "Total no of ratings : 80384405\n", "Total No of Users : 405041\n", "Total No of movies : 17424\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "kNzpnzXDGHJX" }, "source": [ "

3.2.2 Basic Statistics in Test data (#Ratings, #Users, and #Movies)

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "d8b4e924-7c3b-4138-c254-2f33768b7024", "id": "KYo7TX2JGHJX", "colab": { "base_uri": "https://localhost:8080/", "height": 119 } }, "source": [ "print(\"Test data \")\n", "print(\"-\"*50)\n", "print(\"\\nTotal no of ratings :\",test_df.shape[0])\n", "print(\"Total No of Users :\", len(np.unique(test_df.user)))\n", "print(\"Total No of movies :\", len(np.unique(test_df.movie)))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Test data \n", "--------------------------------------------------\n", "\n", "Total no of ratings : 20096102\n", "Total No of Users : 349312\n", "Total No of movies : 17757\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "N0tlZ5jIGHJZ" }, "source": [ "

3.3 Exploratory Data Analysis on Train data

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "9WIr9e5SGHJZ" }, "source": [ " " ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "g768N7pOGHJa", "colab": {} }, "source": [ "# method to make y-axis more readable\n", "def human(num, units = 'M'):\n", " units = units.lower()\n", " num = float(num)\n", " if units == 'k':\n", " return str(num/10**3) + \" K\"\n", " elif units == 'm':\n", " return str(num/10**6) + \" M\"\n", " elif units == 'b':\n", " return str(num/10**9) + \" B\"" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "o0lRFBKbGHJb" }, "source": [ "

3.3.1 Distribution of ratings

" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "abeeef99-a7fb-4ae5-af98-e7cca952c7f3", "id": "nqmCKT-bGHJc", "colab": { "base_uri": "https://localhost:8080/", "height": 297 } }, "source": [ "fig, ax = plt.subplots()\n", "plt.title('Distribution of ratings over Training dataset', fontsize=15)\n", "sns.countplot(train_df.rating)\n", "ax.set_yticklabels([human(item, 'M') for item in ax.get_yticks()])\n", "ax.set_ylabel('No. of Ratings(Millions)')\n", "\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZcAAAEYCAYAAACQgLsAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3XmYHGW5/vFvCDhw2BSEGAHBBR8D\niGgCiKCAKCAoEZXtiIqgiIKCRjwuCAH0J6LsooctJCgQUEAjRkJEAVHZBjmyDLciEEkMxBgI0eBA\nwvz+eN9mmqa7p2amejozuT/XNdd0VdfyVHV1PfUuVT2qp6cHMzOzMq3S7gDMzGzkcXIxM7PSObmY\nmVnpnFzMzKx0Ti5mZlY6JxczMyvdqu0OYEUQEZOBE/JgD7AYeBC4HjhH0mNV024GPAy8T9K1BZb9\nEuCrwE8l3V0wnkeAn0j6Yh6eCmwlaUKhDWq+7N2BLSSdWTO+tHWUKSI+Sdp/mwC3SNqlBev4EnC7\npBtrxvcAn5X0vbLXOVLkY3XTPib7uKSpg1zPrcCDkg7u53yPARdKOm4w6x+MiJgA3AHsIOnWfsz3\nGeBvRc4zrRARewGvGejx7+TSazGwZ369LvAW4NPA4RGxp6TO/N58YAfggYLLfQkpcT0CFEouwL7A\nPwtO21+7Ax8CzqwZfzKwRovWOSAR8QrgB8D3gB8DT7RoVV/K67ixZvwOpAsJa2xfoKNq+DrgJ8CF\nVeP+WsJ6DgP+M4D59gIWlLD+dvgMcAvQluRC2nfvIn03+s3JpdeymquKWRHxA+BmYHpEvEHScknd\nQOGrj/6IiDUkPS3pj61YfjOSyjgBlO11wGhgiqQ/9WfGiFhd0kBORs/rz1XmSBcRo4CO2n1ae6xG\nxDJgbpF9Vznei6xf0n39ibdqvrsGMp8NnpNLE5KezFUmvwTeDVxXr1osIvYhlU7eADwD/Bn4kqSb\ngCV5cRdHxMX59avz/4eBg4E9gH2AO4F31VaLVUTE+4FTgM3ytIdLuj+/96K48vip5OquXP03KY+v\nPJphmqRD6lWLRcQ2wGmkK/huYCbwBUmP16zzAGA34MC8vRcBJ0p6rtn+jYijgKOBVwGPAudKOiO/\nN5neqsr/iwhoUL0SEYcAFwPbA6fm//8PODkiTgH2Ju3zJ4GbgEmVqs68r9cHToiIyvp2lXRjbbVY\nRNwILASuBk4CNgR+B3xS0tyqeF4FnAfsAjwGnAi8F3h5pVovIjYGTs/TrA38HbhM0teb7K/RwNeB\nQ4ExpKrbb0q6rGo/nA9sKOnJqvm2BO4F3i3pV3ncxLysrfJ+uQT4mqRnq/b/UcD7gTOArYFPAD9s\nFF8zEbEn6Xu0G/BFYGdgKnBkRHwZ2A/YHFhKunj7vKSHq+Z/QbVY/lwPBj4AnAtsCXQBR1Ynttpq\nsYiYDmxMOj6+Q6rS6yR9l1Q138uB/wXek/fPd4HXAu+S9IY+tvWYvI0vI1WtX1BnmqbbnLd3S2DL\niPhUnu0gSdMj4jBSSW4c8BzwR+CL1dXuEfGmHPMEYDVgDnCmpAuqpvkQqcp5C2AR6Tt0vKTlef8e\nmaernCvOk3REs22v5gb9vt0ILAPeWu/NiHgtqRrg18D7gA+TirHr5Unemf9/g3SS3oFUtVbxXdIJ\neT/SAd/IpqST0cnAf5Oq7mZFxOr92JYLgctIJ7xKLCc32K4NSNv+X3l9nyWdEGbndqRqpwL/IlW3\n/Qg4Pr9uKLelnAPMIO23HwOn5S9dJdYj8+sP51h/0cf2XQ78nFScryTYDUn7dW/gGOA1wK8jonLs\n70uqEr2I3n3S7Gp3e9JJdxJwOKn69Pyq7RqVt2kcKQl8Afhcnq/aJaR2pMNJJ7Bv8sLqpXpOAr6W\n17cPKbFdGhEH5fd/Smoz3LdmvgOAx4Hf5Bj3JyXI2/NyTsxxfKtmvv8CppE+iz3z9IM1FbiN9JlX\nEtVGwFk5lk/l9d4SEWv2sax1cmzn0Hu8XRMRfe3H15G+j5NJCWoT0vei2qXAO0if9RGkJDuxj+US\nEQeQkvHVpMT3F6qOjyp9bfNhwEPANfQel7Pze5sCU4APAh8B/pHn3STHsArpu/Jv0nd3Iql6ed2q\nOD8KXAH8NsfwLdJxemKe5FzSeW1O1fq/3df2V3PJpQ+S/hMRC0lXivW8GVgi6diqcTOrXt+R//+1\n5oqq8vJWSUfSt5cDEyX9Ps/fSarLPoR0hdUnSXMjYj7QXaDaYlL+v4ekp/I6/0K6wvog6URecbOk\nyvSz81XqB4Ar6y04H/yTgalV810fEesCX4mIM3Os9+f3/iTp3gKbeLaks6pHSDq0ar2jgT8Ac4Gd\nctx/7E9VDumEtrekJ/IyXwGcUVXFsxfwJmA7SXfkaW4ntblVVz1uR7oS/XkevrHZSiNiPVJy/Iak\nb+TRs3IJaDJweS5pX0dKJhdXzX4AqSS8PCe/7wCXSPpM1fK7gXMj4luSKu19a5BKqj8rsF+KulTS\nidUjJH22Ko7RwK9IbY570+AYytYGjqj6Tiwifb470Hx/rgdsL2lOnm914PKI2EzSIxExntQ2uU/l\n88ml1rmkE3YzXyN13vlcHp4VEWNJSazwNku6LyKeBhbUHpeSjq+ZdzaptuQg0oXeK0nJa1dJf8mT\n3lAzz7eB8yUdnUdfHxHLgVMj4lRJj0bE48B/Blo97JJLMaOavHcPsG5ETIuI3QtcbdXq62q8YkHl\nSwSQvxidpJNUK2wHXF9JLHmdt5FOkjvVTHt9zfD9pKqHRjYmfQF+XDP+CtLJ+40DiBfq7MuIeE9E\n/D4iFpNKoJXqq9cPcB13VBJLVkmAG+X/2wKPVRILgKR5pM+q2t3AtyLikFyN1petSFe39fbZ63NJ\nszK8W0SsD89Xbb4+jye/fhVwZUSsWvkjlbxXz+up6CFVZZWp3me0U0T8OieHZaRScAd9f0b/rv5O\n0PtZNDv2AP5cSSwN5tsWWE7VRaKkJeSSXyMRsQbp2K1NxlfXmXag20xEvDEiZkTEgjzvM6Sq8sq8\nj5NqJy6IiP2qjo2KrYBXAD+ucwysSSp1D5qTSx/yVc36pA/sRXI97URSdctMYGFEXFbnA22k7nLr\nqNfjZQEwtuD8/TWW+rE9Tm+VX8WTNcPPkE5UzZZdWVbtsqmz/KJesLyI2JZURTWXVH2wA73Vm/2p\nTqxWb1url/cKUjVFrdpxB5Dazc4A5kTE3RGxW5P1Ft1nM4BnSaXLynrmknodQSoBQzpWn636q7Rv\nbFK17CckPUO5aj+j1wKzSG16nwB2JJ3cF9P3Z9TXZzHQ+V4BLJK0vGa6ep9rtUrtRu139QXDg9nm\niKi042xIaq98e563qzJvbjd7N6l35TTgsYi4MSIqF22VY+AGXngMdOXx1cfAgLlarG+7kvbTHxpN\nIOkXwC9ytc7epG6+55AauPtS9DcPNmwwrtKLptKLp7Y95GUFl19rfoN1juHFV+EDWTZ1ll/5ci4a\n4HJr9+W+pBPCAZJ6ACKir3syBusxoN6FxQZUdaXNpZlDchXhdqSqrRkR8aqqaqlq1fus+v0X7DNJ\n/4qIX5CSyvnA/sCPK9tP7749nNQQXKu663Urfo+jdpl7k3oEvj/3xKyUANZpwbqLegxYLyJG1ySY\nvi4YK4mz9riuHR7MNr+dlPx2kPRIZWROOs/L1cj75vbRnUnVZT8nlXAqx8DH6C21VSul56iTSxMR\n8VJS3eSDpDrRpiQtBi6LiJ1JV8lQ/GqqLxtGxNuq6pdfRWpMrtStLyBdfTxfpI2ItYC3kRrlKvoq\nVVTcBnw6ItbOVQKVksBm9F4FD9RcUu+o/Xhhtcv+wFOkqsYyrAE8W3VihdQ5oFbRfVLEHaSeZ9tJ\nuh0gIjYCxpMa4F8g96i7NSJOBH5Paqytl1zuJfUq2o/UsF+xP6map/qqejpwRUS8j1Sinl69SmAe\nsFl1z6E2WoNUBVV9Ej+I5lXRrXYH6eS/N6kkSESsTbrQnN9oJklPR8S9pJqMqVVvfaBm0qLbXO+4\nrNyL1l0ZERHvJCWcejE9Q2oHPRuYkqvt7yFddG0q6ZJG29Ng/YU5ufRaNSIqVSZrk04GnybVc+9Z\np4gMQO4muAPp5rG/k7oW7kfqDYSkZyLiYWD/fOD9B+jXPRvZQuBHEXEc8DSpV8cC8kEs6bmI+Bnw\n+YiYQyr6T8rTVnsAGBOp2+q9wMLqK6Aqp+ftnxUR3wbWInWDvge4agDxPy/HOhk4LyL+SWqQ3Dmv\n76sa5P0pVWYDx0TEmaSrtrdR07CaPQDsnRvD/5VC1JI60xUxE/g/UpvGV0j7/wTSVe1zALmEO4t0\njPyZVNc+iXTF3FVnmUhalLfjuNwB4U7SSWsv0ompNoalpO7QD1eSXF7OcxExCfhhRKxDSu7PkJLQ\n+4EPSVo6wG0fiBtIPZUuiohLSJ0hPkf6HNpCUmdEzAYujHQrwkLgWNKFT9Pu9aSeiZdFxFmk9qV3\nkZJStaLb/ACwa0RUqrj+SrpAeTrPewbpYu940rEDQERsRzo/XEkqib6cdHzdJunfeZpjSW0y65Gq\n2ZaRulrvC+yVz3cPAJtExIdJFyULJP2tj+1/nttceq1Lqvr6PanRtNKt9o3qvTu/nj+Risunkz6k\n40j92v+napojSB/wr0hXRa8cQHxzSH3nJ5OuRJeQenJVn4iPIh183yd1Jbyc1EhX7UpSQjo1xzK5\n3srylfCupGR4eV7eb0n3Sgy6Hj5fNR9NOpivJZ0gJ0k6ZbDLrlrHTNLn8EHSFejOpPtNah1L6gX0\nC9I+GT+IdfaQrlwfIJUqzyJ1A72fdHKCtE/vIW3/DFK9+FJgdzW/qfB40knp06R99g7gYEnVJRPy\nMmaQ2mmuqF2IpCtyjNuQjvWrSXeD30VvSXtISLoT+CRpW64lfVYfoO9eWa32YdLx/n3S9/mXpB5o\nTzWZB0mXk07k+5G6hr+B1NW4epqi2zyZ1B35KtJxuYfS/VQHkO7bmkHqrn8oL6ydmEdKRseTLnrP\nIVWBVtrhkDQtD2+fl38Vqar0VnoT6KWkLtpn5vV/tdm21xrlnzk2a61cUnkI+J6kE/qa3lY8ue3i\nAWC2pE/1Nb25WsysdBFxBOnq7y+kUu0XSFVfU9oZlxUXEf9N6oF3P6lW49OkXlQ/aGdcw4mTi1n5\n/kOqjtuU1DvqdtJjQ+Y0nctWJEuBL5PaIVYhtaPtrYJPNjdXi5mZWQu4Qd/MzEq30laL3X333T0d\nHX09387MzKotXbp04fjx4/t8AslKm1w6OjoYN66UR+iYma00Ojs7C7UdulrMzMxK5+RiZmalc3Ix\nM7PSObmYmVnpnFzMzKx0Ti5mZlY6JxczMyudk4uZmZXOycXMzErn5GJm/fZcd3ffEw0zI3Gb2mml\nffyLmQ3cKh0d3PSOndsdRql2vvmmdocworjkYmZmpXNyMTOz0jm5mJlZ6ZxczMysdE4uZmZWOicX\nMzMrnZOLmZmVzsnFzMxK5+RiZmalc3IxM7PSObmYmVnpWvJssYjYBLgEGAP0AOdLOiu/Nxn4JPCP\nPPlXJc2ss4w9gbOA0cCFkk6pM81UYH9gjKQledyZwNHABpIWlrtlZmZWRKtKLsuASZK2AN4KHBkR\nW1S9f4akbfJfvcQyGjgXeA+wBXBQzfzVHgQm5vlWAd4JzCtvU8zMrL9aklwkzZd0V369BOgCNurH\nIrYDHpT0kKRngOnkBFLHdOCA/HoX4Hek5GZmZm3S8kfuR8RmwJuB26pGHxURHwXuJJVwnqiZbSPg\n0arhucD2DVbxZ2CfiHgZcBDwI1KJp6nu7m66uroKbYOZvdC4cePaHUJL+JxQnpYml4hYC7gKOEbS\nU3n0D4CTSW0xJwOnAYcOclVXAweSEtCniszQ0dExYr8gZjYwPif0rbOzs9B0LUsuEbEaKbFcKunq\nynhJj1dNcwFwbZ3Z5wGbVA1vTPN2lCuATmCapOciYjChm5nZILWkzSUiRgEXAV2STq95b2zV4L7A\nvXUWcQeweUS8OiJeQiqVzGi0PklzgK8B3x9s7GZmNnitKrnsCHwEuCci7s7jKl2OT42IbUjVYo+Q\nq7Ei4pWkLsd7SVoWEUcBs0hdkadIuq/ZCiWd15pNMTOz/hrV09PT7hjaoqurq8f1q2YDd9M7dm53\nCKXa+eab2h3CsNDZ2dk5fvz4CX1N5zv0zcysdE4uZmZWOicXMzMrnZOLmZmVzsnFzMxK5+RiZmal\nc3IxM7PSObmYFdS9rLvdIZRuJG6TrRha/lRks5GiY9UOdjxnx3aHUarfffZ37Q7BRiiXXMzMrHRO\nLmZmVjonFzMzK52Ti5mZlc7JxczMSufkYmZmpXNyMTOz0jm5mJlZ6ZxczMysdE4uZmZWOicXMzMr\nXeHkEhFrRsToVgZjZmYjQ8MHV0bEKsCBwIeBbYFuoCMiFgK/AM6T9OCQRGlmZsNKs5LLb4DXAl8B\nXiFpE0kbAjsBtwLfjoiDhyBGMzMbZpo9cv9dkp6tHSlpEXAVcFVErNayyMzMbNhqmFwqiSUiXgvM\nldQdEbsAWwOXSHqyXvIxMzMr0qB/FbA8Il4HnA9sAlzW0qjMzGxYK5JcnpO0DNgXOEfSscDY1oZl\nZmbDWZHk8mxEHAR8DLg2j3Nbi5mZNVQkuXwc2AH4pqSHI+LVwA9bG5aZmQ1nzXqLASDpfuBzVcMP\nA99uNk9EbAJcAowBeoDzJZ2V31sPuALYDHgE2F/SE3WW8THguDz4DUnT6kxzI/AaYFNJPXncT0k9\n3dbqa9vMzKw1+iy5RMSOETE7Iv4cEQ9FxMMR8VAfsy0DJknaAngrcGREbJHf+zJwg6TNgRvycO06\n1wNOALYHtgNOiIiXNVjXk8COeb6X4vYgM7O2K1ItdhFwOunmyW2BCfl/Q5LmS7orv14CdAEb5bcn\nApVSyDTg/XUWsQcwW9KiXKqZDezZYHXTSU8SAPgAcHWBbTIzsxbqs1oMWCzplwNdQURsBrwZuC2P\nGiNpfn79GKnqrNZGwKNVw3PpTU61bgAuyM89OxA4HPh6X3F1d3fT1dXVZ/xmFePGjWt3CC0xkO+B\n94X1pUhy+U1EfIdUIuiujKyUTJqJiLVI98kcI+mp2vcl9URETz/irWc5cAspsawh6ZGI6HOmjo6O\nEfsFMesPfw96eV/0rbOzs9B0RZLL9vn/hKpxPcA7m82UHw1zFXCppOqqqscjYqyk+RExFlhQZ/Z5\nwC5VwxsDNzZZ3XTgGmBys5jMzGxoFOkttmt/FxoRo0htNV2STq95ewbpnplT8v+f1VnELOD/VTXi\n7056gGYjvwW+BVze31jNzKx8fSaXiFiX1HPrHXnUTcBJkhY3mW1H4CPAPRFxdx73VUkzSUnlyog4\nDJgD7J/XMwE4QtInJC2KiJOBO/K8J+UHZtaVuyF/t69tMTOzoVGkWmwKcC85CZCSxsWknll1SboF\nGNXgvX8Cu9UZfyfwiarhKXndDUnapcF43+NiZtZGRZLLayV9sGr4xKrSiJmZ2YsUuc/l6YjYqTIQ\nETsCT7cuJDMzG+6KlFw+DUzLbS+jgEXAIa0MyszMhrcivcXuBt4UEevk4Rfdr2JmZlatYXKJiIMl\n/SgivlAzHoA6XYzNzMyA5iWXNfP/tYciEDMzGzkaJhdJ5+X/Jw5dOGZmNhI0qxY7u9mMkj7X7H0z\nM1t5NasWK/Z0MjMzsxrNqsVe9MuPZmZmRTSrFvs56enHdUnapyURmZnZsNesWswPgjQz68OyZ5ez\n6mqj2x1GqcrYpmbVYjcNaslmZiuBVVcbzfcm/bzdYZTqqNPeN+hlNKsWu1LS/hFxD3WqxyRtPei1\nm5nZiNSsWuzo/P+9QxGImZmNHM2qxebn/3OGLhwzMxsJmlWLLeGF1WGj8vAooEfSOi2OzczMhqlm\n1WI3AK8ArgamS/rb0IRkZmbDXcMfC5P0fmAP4B/ABRFxU0R8JiLWG7LozMxsWGr6S5SSFku6GHgP\ncB5wEv6hMDMz60PTHwuLiLcBBwFvB24B9pX026EIzMzMhq9mDfqPAE8C04HDgWV5/FsAJN3V+vDM\nzGw4alZyeYTUO2wPYHdSL7GKHuCdrQvLzMyGs2b3uewyhHGYmdkI0rBBPyJ2ajZjRKwTEVuVH5KZ\nmQ13zarFPhgRpwLXkX447B/A6sDrgF2BTYFJLY/QzMyGnWbVYp/P97R8ENgPGAs8DXQB50m6ZWhC\nNDOz4aZpV2RJi4AL8p+ZmVkhTZMLQEQcDVwMLCElmbcAX5Z0fYtjMzOzYarP5AIcKumsiNgDWB/4\nCPBDoGlyiYgppMf1L5C0VdX4ycAnSW04AF+VNLPO/HsCZwGjgQslnVJnmqnA/sAYSUvyuDNJPxew\ngaSFBbbPzMxK1vTxL1nl/pa9gEsk3ccL73lpZCqwZ4P3zpC0Tf6rl1hGA+eSHjuzBXBQRGzRYFkP\nAhPzfKuQ7r+ZVyA+MzNrkSLJpTMiricll1kRsTbwXF8zSboZWDTAuLYDHpT0kKRnSE8JmNhg2unA\nAfn1LsDvyE8TMDOz9ihSLXYYsA3wkKSlEbE+8PFBrveoiPgocCcwSdITNe9vBDxaNTwX2L7Bsv4M\n7BMRLyM9B+1HpBJPU93d3XR1dfU7cFt5jRs3rt0htMRAvgfeF728L+orkly2yf9fExGVcYsjYlVJ\nAykh/AA4mfQImZOB04BDB7CcalcDB5IS0KeKzNDR0TFiDwqz/vD3oJf3Ra9G+6Kzs7PQ/EWSy/dJ\nPcT+RGpr2Qq4D1g3Ij7d315jkh6vvI6IC4Br60w2D9ikanhjmrejXEG60XOapOeqkqCZmbVBkTaX\nvwNvljRB0njgzcBDwLuBU/u7wogYWzW4L3BvncnuADaPiFdHxEtIpZIZjZYpaQ7wNVIiNDOzNiuS\nXF6fe4gBIOl+4A2SHmo2U0RcDvwhvYy5EXFYfuvUiLgnIv5EeozM5/P0r4yImXkdy4CjgFmkJwJc\nWR1DPZLOk/TXAttjZmYtVqRa7L6I+AGpVxaknln3R0QH8GyjmSQd1GD8RxqM/zupR1pleCbwom7K\nNfMc0mD8Zs3mMzOz1ipScjmEdC/JMfnvoTzuWVLJw8zM7AX6LLlIeprUo+u0Om//q/SIzMxs2Cvy\nbLEdgcmkR+w/P72k17QuLDMzG86KtLlcRGp07wSWtzYcMzMbCYokl8WSftnySMzMbMQoklx+ExHf\nId0F310ZKemulkVlZmbDWpHkUnmm14SqcT2kpw+bmZm9SJHeYu5ubGZm/dIwuUTEwZJ+FBFfqPe+\npNNbF5aZmQ1nzUoua+b/a9d5r6cFsZiZ2QjRMLlIOi+//JWk31W/l+99MTMzq6vI41/OKTjOzMwM\naN7msgPwNmCDmnaXdYDRrQ7MzMyGr2ZtLi8B1srTVLe7PAV8qJVBmZnZ8NaszeUm4KaImJp/jMvM\nzKyQIjdRLs136G8JrF4ZKck3UZqZWV1FGvQvBR4AXg2cCDxC+hliMzOzuookl/UlXQQ8K+kmSYfi\nR7+YmVkTRarFKj9lPD8i9gb+DqzXupDMzGy4K5JcvhER6wKTSPe3rEP6fRczM7O6ijy48tr8cjGw\nK0BErNl4DjMzW9k1TS4RsREwFviTpGciYkPgGOAQ4JWtD8/MzIajhg36EXEMcDepKuzWiPgE0AWs\nAYwfmvDMzGw4alZyORwISYsi4lXAn4EdJXUOTWhmZjZcNeuK/B9JiwAk/S39c2IxM7O+NSu5bBwR\nZ1cNj60elvS51oVlZmbDWbPkcmzNsEstZmZWSLMHV04bykDMzGzkKPL4FzMzs34pcof+gETEFOC9\nwAJJW1WNXw+4AtiM9BDM/SU9UWf+jwHH5cFv1CtJRcSNwGuATSX15HE/Bd4laa0yt8fMzIprdp/L\nt/P//Qa47KnAnnXGfxm4QdLmwA15uHbd6wEnANsD2wEnRMTLGqznSWDHPN9LSTd9mplZGzWrFtsr\nIkYBXxnIgiXdDCyq89ZEoFIKmQa8v840ewCzJS3KpZrZ1E9UANOBA/PrDwBXDyReMzMrT7NqseuA\nJ4C1IuIpYBTQU/kvaZ0BrnOMpPn59WPAmDrTbAQ8WjU8N4+r5wbggogYTUoyhwNfH2BsZmZWgma9\nxY4Fjo2In0ma2IqVS+qJiJ5BLmY5cAspsawh6ZGI6HOm7u5uurq6BrlqW5mMGzeu3SG0xEC+B94X\nvbwv6ivyVOSJETEG2DaPuk3SPwaxzscjYqyk+RExFlhQZ5p5wC5VwxsDNzZZ5nTgGmBy0SA6OjpG\n7EFh1h/+HvTyvujVaF90dha75bHPrsi5Qf92YD9gf+D2iPhQ8RBfZAbwsfz6Y8DP6kwzC9g9Il6W\nG/J3z+Ma+S3wLeDyQcRlZmYlKdIV+ThgW0kLACJiA+BXwE+azRQRl5NKHy+PiLnACfnnkk8BroyI\nw4A5pIRFREwAjpD0ifywzJOBO/LiTqo856ye3A35uwW2xczMhkCR5LJKJbFk/6RAiUfSQQ3G/xPY\nrc74O4FPVA1PAab0sY5dGoz3PS5mZm1UJLlcFxGz6K1yOgCY2bqQzMxsuCtSAjkWOA/YOv+dL+l/\nWh2YmZkNX4Ue/yLpanxzopmZFeQHV5qZWemcXMzMrHROLmZmVroBJZeImFxyHGZmNoIMtOTinzxe\nSfQs6253CKUbidtktqIZ0I+FSfp52YHYimnUqh387aQ3tjuMUr3q+HvaHYLZiNdncomIjYFzgJ1I\nj9z/LXC0pLktjs3MzIapItViF5MeNjkWeCXw8zzOzMysriLVYhtIqk4mUyPimFYFZGZmw1+R5PLP\niDiY3meLHUR6eKWZmVldRarFDiU9Fv8xYD7wIeDjrQzKzMyGtyK/RDkH2GcIYjEzsxGiYXKJiOOb\nzNcj6eQWxGNmZiNAs5LLv+uMWxM4DFgfcHIxM7O6GiYXSadVXkfE2sDRpLaW6cBpjeYzMzNr2uYS\nEesBXwA+DEwD3iLpiaEIzMzMhq9mbS7fAT4AnA+8UdK/hiwqMzMb1pqVXCYB3cBxwNciojJ+FKlB\nf50Wx2ZmZsNUszYX/9aLmZkNiBOImZmVzsnFzMxK5+RiZmalc3IxM7PSObmYmVnpnFzMzKx0Ti5m\nZlY6JxczMytdkV+iLF1EPAKMJb1GAAAHuUlEQVQsAZYDyyRNqDPNKOAsYC9gKXCIpLvqTNcDXCrp\n4Dy8KulHzW6T9N5WbYOZmTXWluSS7SppYZP33wNsnv+2B36Q/9f6N7BVRKwh6Wng3cC8soM1M7Pi\nVuRqsYnAJZJ6JN0KvDQixjaYdiawd359EHD5UARoZmb1tavk0gNcn6u0zpN0fp1pNgIerRqem8fN\nrzPtdOD4iLgW2BqYAry9WQDd3d10dXUNJPaVyrhx49odQksM5LP3vujlfdHL+6K+diWXnSTNi4gN\ngdkR8YCkmwe6MEl/iojNSKWWmUXm6ejoGLEHhfXNn30v74te3he9Gu2Lzs7OQvO3pVpM0rz8fwFw\nDbBdncnmAZtUDW9M87aUGcB3cZWYmVnbDXlyiYg1888mExFrArsD99aZdAbw0YgYFRFvBRZLqlcl\nVjEFOFHSPaUHbWZm/dKOarExwDX5x8dWBS6TdB1ARBwBIOl/SdVbewEPkroif7zZQiXNBc5uXdhm\nZlbUkCcXSQ8Bb2rw3v9Wve4BjiywvLXqjLsRuHHAQZqZ2aCsyF2RzcxsmHJyMTOz0jm5mJlZ6Zxc\n6uh+dnm7QyjdSNwmM1txtfPZYiusjtVGM/7YS9odRqk6v/PRdodgZisRl1zMzKx0Ti5mZlY6Jxcz\nMyudk4uZmZXOycXMzErn5GJmZqVzcjEzs9I5uZiZWemcXMzMrHROLmZmVjonFzMzK52Ti5mZlc7J\nxczMSufkYmZmpXNyMTOz0jm5mJlZ6ZxczMysdE4uZmZWOicXMzMrnZOLmZmVzsnFzMxK5+RiZmal\nc3IxM7PSObmYmVnpVm3HSiNiT+AsYDRwoaRT6kzTAVwCjAf+CRwg6ZGaaTYDHga+Kem4PO7lwHzg\nPElHtXAzzMysgSEvuUTEaOBc4D3AFsBBEbFFnUkPA56Q9DrgDODbDRb5MLB31fB+wH3lRWxmZv3V\njmqx7YAHJT0k6RlgOjCxznQTgWn59U+A3SJiVJ3plgJdETEhDx8AXFlyzGZm1g/tqBbbCHi0angu\nsH2z6SQti4jFwPrAwjrTTgcOjIjHgeXA34FXNgti6dKlCzs7O+c0ev/8A7dsNvuw09nZOfCZ955a\nWhwrgn8MYl+c/bazS4yk/QZzXKx1xuklRtJ+g9kXO/x309PNsNPHvti0yDLa0ubSAtcBJwOPA1cU\nmWH8+PEbtDQiM7OVWDuqxeYBm1QNb5zHNZwuIlYF1iU17L9Irl7rBCaRqtDMzKyN2pFc7gA2j4hX\nR8RLgAOBGXWmmwF8LL/+EPBrST1Nlnsa8D+SFpUarZmZ9duQV4vl9pOjgFmkrshTJN0HEBEnAXdK\nmgFcBPwwIh4EFpGSULPl3od7iZmZrRBG9fQ0KwyYmZn1n+/QNzOz0jm5mJlZ6UZKV+RhJyKmAO8F\nFkjaqt3xtEtEbEJ6zM8YoAc4X9JZ7Y2qPSJideBmoIP03fyJpBPaG1V75Sd63AnMk/TedsfTLhHx\nCLCEdB/fMkkTms6wAnDJpX2mAnu2O4gVwDJgkqQtgLcCRzZ4HNDKoBt4p6Q3AdsAe0bEW9scU7sd\nDXS1O4gVxK6SthkOiQWcXNpG0s2kXnArNUnzJd2VXy8hnUg2am9U7SGpR9K/8uBq+W+l7XETERuT\nnht4Ybtjsf5zcrEVRn7K9ZuB29ocSttExOiIuBtYAMyWtNLuC+BM4EvAc+0OZAXQA1wfEZ0RcXi7\ngynCycVWCBGxFnAVcIykp9odT7tIWi5pG9KTK7aLiJWyPS4iKu2Rg3go3oiyk6S3kJ4mf2REvKPd\nAfXFycXaLiJWIyWWSyVd3e54VgSSngR+w8rbLrcjsE9uyJ4OvDMiftTWiNpI0rz8fwFwDenp8is0\nJxdrq/wzChcBXZJG1mN2+ykiNoiIl+bXawDvBh5ob1TtIekrkjaWtBnp6Ry/lnRwm8Nqi4hYMyLW\nrrwGdgfubW9UfXNX5DaJiMuBXYCXR8Rc4ARJF7U3qrbYEfgIcE9uawD4qqSZbYypXcYC03L321WA\nKyVd2+aYrP3GANdEBKRz9mWSrmtvSH3z41/MzKx0rhYzM7PSObmYmVnpnFzMzKx0Ti5mZlY6Jxcz\nMyudk4vZCiAijomI/6oanlm558VsOHJXZLMhkm8YHSXpRc/KyneiT5C0cKjjMmsFJxezFsoP45xF\nehjneOB24I3AGuTfa4mIzwHfBQQslLRrJdkAawG/BG4B3gbMAyZKejoitiU93eA5YDbwnpX5t4Fs\nxeJqMbPW2xz4vqQtSb9dMwHYGtg5IraWdDbwd9LvdezaYP5z8/xPAh/M4y8GPpUfdLm85Vth1g9O\nLmatN0fSrfn1/hFxF/BHYEugyA+jPSyp8micTmCz3B6ztqQ/5PGXlRqx2SA5uZi13r8BIuLVwBeB\n3SRtDfwCWL3A/N1Vr5fjZwLaMODkYjZ01iElmsURMYb02xwVS4C1iy4oP5J/SURsn0cdWFqUZiVw\ncjEbIpL+j1Qd9gCpGut3VW+fD1wXEb/pxyIPAy7IT5NeE1hcVqxmg+XeYmbDVESsJelf+fWXgbGS\njm5zWGaA627NhrO9I+IrpO/xHOCQ9oZj1sslFzMzK53bXMzMrHROLmZmVjonFzMzK52Ti5mZlc7J\nxczMSvf/Ab+L4fSATyIbAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Fdo_j64AGHJd" }, "source": [ "

Add new column (week day) to the data set for analysis.

" ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "f19498ad-6c85-4999-d8c6-33b9d300cf3f", "id": "_xjyPNEXGHJe", "colab": { "base_uri": "https://localhost:8080/", "height": 204 } }, "source": [ "# It is used to skip the warning ''SettingWithCopyWarning''.. \n", "pd.options.mode.chained_assignment = None # default='warn'\n", "\n", "train_df['day_of_week'] = train_df.date.dt.weekday_name\n", "\n", "train_df.tail()" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
movieuserratingdateday_of_week
8038440012074203361842005-08-08Monday
80384401862179706132005-08-08Monday
8038440210986149871552005-08-08Monday
803844031486150001642005-08-08Monday
803844045926104401552005-08-08Monday
\n", "
" ], "text/plain": [ " movie user rating date day_of_week\n", "80384400 12074 2033618 4 2005-08-08 Monday\n", "80384401 862 1797061 3 2005-08-08 Monday\n", "80384402 10986 1498715 5 2005-08-08 Monday\n", "80384403 14861 500016 4 2005-08-08 Monday\n", "80384404 5926 1044015 5 2005-08-08 Monday" ] }, "metadata": { "tags": [] }, "execution_count": 16 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "ygJPJ8TGGHJg" }, "source": [ "

3.3.2 Number of Ratings per a month

" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "8981337b-0e70-4b05-d896-88abc2516e54", "id": "Qnco9MwLGHJh", "colab": { "base_uri": "https://localhost:8080/", "height": 295 } }, "source": [ "ax = train_df.resample('m', on='date')['rating'].count().plot()\n", "ax.set_title('No of ratings per month (Training data)')\n", "plt.xlabel('Month')\n", "plt.ylabel('No of ratings(per month)')\n", "ax.set_yticklabels([human(item, 'M') for item in ax.get_yticks()])\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "xWj3WheyGHJj" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "TKfHd26wGHJk" }, "source": [ "

3.3.3 Analysis on the Ratings given by user

" ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "161d1eaa-b744-4688-83b5-36cf2e6b1681", "id": "idlP3rKeGHJq", "colab": { "base_uri": "https://localhost:8080/", "height": 136 } }, "source": [ "no_of_rated_movies_per_user = train_df.groupby(by='user')['rating'].count().sort_values(ascending=False)\n", "\n", "no_of_rated_movies_per_user.head()" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "user\n", "305344 17112\n", "2439493 15896\n", "387418 15402\n", "1639792 9767\n", "1461435 9447\n", "Name: rating, dtype: int64" ] }, "metadata": { "tags": [] }, "execution_count": 8 } ] }, { "cell_type": "code", "metadata": { "id": "aUdrPjIBTysZ", "colab_type": "code", "outputId": "a2783438-1c69-4dff-c5fa-adff1dbf7de8", "colab": { "base_uri": "https://localhost:8080/", "height": 170 } }, "source": [ "no_of_rated_movies_per_user.describe()" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "count 405041.000000\n", "mean 198.459921\n", "std 290.793238\n", "min 1.000000\n", "25% 34.000000\n", "50% 89.000000\n", "75% 245.000000\n", "max 17112.000000\n", "Name: rating, dtype: float64" ] }, "metadata": { "tags": [] }, "execution_count": 28 } ] }, { "cell_type": "code", "metadata": { "id": "tz_k92E3T8k9", "colab_type": "code", "outputId": "6e2f28e3-c782-4af4-81f8-a74c943647e6", "colab": { "base_uri": "https://localhost:8080/", "height": 286 } }, "source": [ "plt.plot(no_of_rated_movies_per_user.values)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[]" ] }, "metadata": { "tags": [] }, "execution_count": 29 }, { "output_type": "display_data", "data": { "image/png": "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\n9huLmNGJAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "id": "hqXHdcYWTOcm", "colab_type": "code", "outputId": "85712e60-5056-4629-ec3d-bbd9ff6cbffe", "colab": { "base_uri": "https://localhost:8080/", "height": 286 } }, "source": [ "plt.plot(no_of_rated_movies_per_user.values[:100])" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[]" ] }, "metadata": { "tags": [] }, "execution_count": 27 }, { "output_type": "display_data", "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "df9ce16f-a521-4824-82c7-6db68e665ad6", "id": "gsw7dn-lGHJ1", "colab": { "base_uri": "https://localhost:8080/", "height": 295 } }, "source": [ "tyfig = plt.figure(figsize=plt.figaspect(.5))\n", "\n", "ax1 = plt.subplot(121)\n", "sns.kdeplot(no_of_rated_movies_per_user, shade=True, ax=ax1)\n", "plt.xlabel('No of ratings by user')\n", "plt.title(\"PDF\")\n", "\n", "ax2 = plt.subplot(122)\n", "sns.kdeplot(no_of_rated_movies_per_user, shade=True, cumulative=True,ax=ax2)\n", "plt.xlabel('No of ratings by user')\n", "plt.title('CDF')\n", "\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "image/png": "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\nCvIiIiJ16v8DVNbwziTrvw4AAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "0217ea22-3546-4f56-befc-f9a78c21b651", "id": "AVN_18IHGHJ5", "colab": { "base_uri": "https://localhost:8080/", "height": 170 } }, "source": [ "no_of_rated_movies_per_user.describe()" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "count 405041.000000\n", "mean 198.459921\n", "std 290.793238\n", "min 1.000000\n", "25% 34.000000\n", "50% 89.000000\n", "75% 245.000000\n", "max 17112.000000\n", "Name: rating, dtype: float64" ] }, "metadata": { "tags": [] }, "execution_count": 31 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "D5c1dpEBGHJ8" }, "source": [ "> _There, is something interesting going on with the quantiles.._" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "ftxPLUPcGHJ9", "colab": {} }, "source": [ "quantiles = no_of_rated_movies_per_user.quantile(np.arange(0,1.01,0.01), interpolation='higher')" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "9KOcgUldwWcm", "colab_type": "code", "colab": {} }, "source": [ "" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "6a7ef012-2612-40b9-8516-43637e338b1f", "id": "1EK2PIQMGHMv", "colab": {} }, "source": [ "plt.title(\"Quantiles and their Values\")\n", "quantiles.plot()\n", "# quantiles with 0.05 difference\n", "plt.scatter(x=quantiles.index[::5], y=quantiles.values[::5], c='orange', label=\"quantiles with 0.05 intervals\")\n", "# quantiles with 0.25 difference\n", "plt.scatter(x=quantiles.index[::25], y=quantiles.values[::25], c='m', label = \"quantiles with 0.25 intervals\")\n", "plt.ylabel('No of ratings by user')\n", "plt.xlabel('Value at the quantile')\n", "plt.legend(loc='best')\n", "\n", "# annotate the 25th, 50th, 75th and 100th percentile values....\n", "for x,y in zip(quantiles.index[::25], quantiles[::25]):\n", " plt.annotate(s=\"({} , {})\".format(x,y), xy=(x,y), xytext=(x-0.05, y+500)\n", " ,fontweight='bold')\n", "\n", "\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "GjNmHPGCGHM_" }, "source": [ "- __It is very skewed.. just like nunmber of ratings given per user.__\n", " \n", " \n", " - There are some movies (which are very popular) which are rated by huge number of users.\n", " \n", " - But most of the movies(like 90%) got some hundereds of ratings." ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "88gf03axGHNA" }, "source": [ "

3.3.5 Number of ratings on each day of the week

" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "f2b2b524-96cb-4edc-ce04-006380c7cd3f", "id": "LEMc4h97GHNB", "colab": {} }, "source": [ "fig, ax = plt.subplots()\n", "sns.countplot(x='day_of_week', data=train_df, ax=ax)\n", "plt.title('No of ratings on each day...')\n", "plt.ylabel('Total no of ratings')\n", "plt.xlabel('')\n", "ax.set_yticklabels([human(item, 'M') for item in ax.get_yticks()])\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "stream", "text": [ "0:01:10.003761\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "e9bd9666-b045-41bf-d5c9-6fff7c8d7c9f", "id": "AQPi83aoGHNG", "colab": {} }, "source": [ "avg_week_df = train_df.groupby(by=['day_of_week'])['rating'].mean()\n", "print(\" AVerage ratings\")\n", "print(\"-\"*30)\n", "print(avg_week_df)\n", "print(\"\\n\")" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ " AVerage ratings\n", "------------------------------\n", "day_of_week\n", "Friday 3.585274\n", "Monday 3.577250\n", "Saturday 3.591791\n", "Sunday 3.594144\n", "Thursday 3.582463\n", "Tuesday 3.574438\n", "Wednesday 3.583751\n", "Name: rating, dtype: float64\n", "\n", "\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "5o1LK_m-GHNJ" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "colab_type": "text", "id": "p8ppntjZGHNK" }, "source": [ "

3.3.6 Creating sparse matrix from data frame

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "NaR7yrqPGHNK" }, "source": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "ioKS3o7VGHNL" }, "source": [ "

3.3.6.1 Creating sparse matrix from train data frame

" ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "cf2444aa-18be-4e29-95a3-693b1c22e027", "id": "SfWUsCnLGHNL", "colab": { "base_uri": "https://localhost:8080/", "height": 68 } }, "source": [ "\n", "start = datetime.now()\n", "if os.path.isfile('/content/drive/My Drive/Netflix_recommender/data_folder/train_sparse_matrix.npz'):\n", " print(\"It is present in your pwd, getting it from disk....\")\n", " # just get it from the disk instead of computing it\n", " train_sparse_matrix = sparse.load_npz('/content/drive/My Drive/Netflix_recommender/data_folder/train_sparse_matrix.npz')\n", " print(\"DONE..\")\n", "else: \n", " print(\"We are creating sparse_matrix from the dataframe..\")\n", " # create sparse_matrix and store it for after usage.\n", " # csr_matrix(data_values, (row_index, col_index), shape_of_matrix)\n", " # It should be in such a way that, MATRIX[row, col] = data\n", " train_sparse_matrix = sparse.csr_matrix((train_df.rating.values, (train_df.user.values,\n", " train_df.movie.values)),)\n", " \n", " print('Done. It\\'s shape is : (user, movie) : ',train_sparse_matrix.shape)\n", " print('Saving it into disk for furthur usage..')\n", " # save it into disk\n", " sparse.save_npz(\"train_sparse_matrix.npz\", train_sparse_matrix)\n", " print('Done..\\n')\n", "\n", "print(datetime.now() - start)" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "It is present in your pwd, getting it from disk....\n", "DONE..\n", "0:00:04.955848\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "XFbTLnY3GHNO" }, "source": [ "

The Sparsity of Train Sparse Matrix

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "99164627-26ef-4692-b31d-265f7bafce06", "id": "0Zy4dRnnGHNO", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "us,mv = train_sparse_matrix.shape\n", "elem = train_sparse_matrix.count_nonzero()\n", "\n", "print(\"Sparsity Of Train matrix : {} % \".format( (1-(elem/(us*mv))) * 100) )" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Sparsity Of Train matrix : 99.8292709259195 % \n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "hOlZ-zQAGHNR" }, "source": [ "

3.3.6.2 Creating sparse matrix from test data frame

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "80f3aabe-a508-45d4-a5db-93a50e22dadb", "id": "5VMK9kIMGHNR", "colab": { "base_uri": "https://localhost:8080/", "height": 68 } }, "source": [ "start = datetime.now()\n", "if os.path.isfile('/content/drive/My Drive/Netflix_recommender/data_folder/test_sparse_matrix.npz'):\n", " print(\"It is present in your pwd, getting it from disk....\")\n", " # just get it from the disk instead of computing it\n", " test_sparse_matrix = sparse.load_npz('/content/drive/My Drive/Netflix_recommender/data_folder/test_sparse_matrix.npz')\n", " print(\"DONE..\")\n", "else: \n", " print(\"We are creating sparse_matrix from the dataframe..\")\n", " # create sparse_matrix and store it for after usage.\n", " # csr_matrix(data_values, (row_index, col_index), shape_of_matrix)\n", " # It should be in such a way that, MATRIX[row, col] = data\n", " test_sparse_matrix = sparse.csr_matrix((test_df.rating.values, (test_df.user.values,\n", " test_df.movie.values)))\n", " \n", " print('Done. It\\'s shape is : (user, movie) : ',test_sparse_matrix.shape)\n", " print('Saving it into disk for furthur usage..')\n", " # save it into disk\n", " sparse.save_npz(\"test_sparse_matrix.npz\", test_sparse_matrix)\n", " print('Done..\\n')\n", " \n", "print(datetime.now() - start)" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "It is present in your pwd, getting it from disk....\n", "DONE..\n", "0:00:02.357853\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "t3xebt2ZGHNT" }, "source": [ "

The Sparsity of Test data Matrix

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "d49234ce-e450-43f4-aac2-4185ae6daf80", "id": "6EKxr7vwGHNY", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "us,mv = test_sparse_matrix.shape\n", "elem = test_sparse_matrix.count_nonzero()\n", "\n", "print(\"Sparsity Of Test matrix : {} % \".format( (1-(elem/(us*mv))) * 100) )" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Sparsity Of Test matrix : 99.95731772988694 % \n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "XiTGR4RmGHNe" }, "source": [ "

3.3.7 Finding Global average of all movie ratings, Average rating per user, and Average rating per movie

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "wHOby1-ZGHNe", "colab": {} }, "source": [ "# get the user averages in dictionary (key: user_id/movie_id, value: avg rating)\n", "\n", "def get_average_ratings(sparse_matrix, of_users):\n", " \n", " # average ratings of user/axes\n", " ax = 1 if of_users else 0 # 1 - User axes,0 - Movie axes\n", "\n", " # \".A1\" is for converting Column_Matrix to 1-D numpy array \n", " sum_of_ratings = sparse_matrix.sum(axis=ax).A1\n", " # Boolean matrix of ratings ( whether a user rated that movie or not)\n", " is_rated = sparse_matrix!=0\n", " # no of ratings that each user OR movie..\n", " no_of_ratings = is_rated.sum(axis=ax).A1\n", " \n", " # max_user and max_movie ids in sparse matrix \n", " u,m = sparse_matrix.shape\n", " # creae a dictonary of users and their average ratigns..\n", " average_ratings = { i : sum_of_ratings[i]/no_of_ratings[i]\n", " for i in range(u if of_users else m) \n", " if no_of_ratings[i] !=0}\n", "\n", " # return that dictionary of average ratings\n", " return average_ratings" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "lKKAvkjWGHNh" }, "source": [ "

3.3.7.1 finding global average of all movie ratings

" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "85b83613-6952-46c0-d21a-0b396c442f1d", "id": "E_2UJPQ0GHNi", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "train_averages = dict()\n", "# get the global average of ratings in our train set.\n", "train_global_average = train_sparse_matrix.sum()/train_sparse_matrix.count_nonzero()\n", "train_averages['global'] = train_global_average\n", "train_averages" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'global': 3.582890686321557}" ] }, "metadata": { "tags": [] }, "execution_count": 20 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "WxLw0l4cGHNr" }, "source": [ "

3.3.7.2 finding average rating per user

" ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "77ba4505-2a69-4e94-dde9-3d4090837044", "id": "FDxKEdnRGHNs", "colab": { "base_uri": "https://localhost:8080/", "height": 51 } }, "source": [ "train_averages['user'] = get_average_ratings(train_sparse_matrix, of_users=True)\n", "print('\\nAverage rating of user 10 :',train_averages['user'][10])" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "\n", "Average rating of user 10 : 3.3781094527363185\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "UUK-RMqTGHNz" }, "source": [ "

3.3.7.3 finding average rating per movie

" ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "10f11d17-ecbd-4155-8c66-164f02e89cc9", "id": "6SOIqs_9GHN0", "colab": { "base_uri": "https://localhost:8080/", "height": 51 } }, "source": [ "train_averages['movie'] = get_average_ratings(train_sparse_matrix, of_users=False)\n", "print('\\n AVerage rating of movie 15 :',train_averages['movie'][15])" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "\n", " AVerage rating of movie 15 : 3.3038461538461537\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "JxskKIsNGHN3" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "wyRb1XHUGHN4" }, "source": [ "

3.3.7.4 PDF's & CDF's of Avg.Ratings of Users & Movies (In Train Data)

" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "c20f89fb-1639-4d71-d5d6-1bdc331b060e", "id": "Brg-5Lf8GHN5", "colab": { "base_uri": "https://localhost:8080/", "height": 311 } }, "source": [ "start = datetime.now()\n", "# draw pdfs for average rating per user and average\n", "fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=plt.figaspect(.5))\n", "fig.suptitle('Avg Ratings per User and per Movie', fontsize=15)\n", "\n", "ax1.set_title('Users-Avg-Ratings')\n", "# get the list of average user ratings from the averages dictionary..\n", "user_averages = [rat for rat in train_averages['user'].values()]\n", "sns.distplot(user_averages, ax=ax1, hist=False, \n", " kde_kws=dict(cumulative=True), label='Cdf')\n", "sns.distplot(user_averages, ax=ax1, hist=False,label='Pdf')\n", "\n", "ax2.set_title('Movies-Avg-Rating')\n", "# get the list of movie_average_ratings from the dictionary..\n", "movie_averages = [rat for rat in train_averages['movie'].values()]\n", "sns.distplot(movie_averages, ax=ax2, hist=False, \n", " kde_kws=dict(cumulative=True), label='Cdf')\n", "sns.distplot(movie_averages, ax=ax2, hist=False, label='Pdf')\n", "\n", "plt.show()\n", "print(datetime.now() - start)" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "image/png": "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\n0zRN8zD/DzK4xFoJKDILAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } }, { "output_type": "stream", "text": [ "0:00:41.239658\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "fDkc5fbDGHN9" }, "source": [ "

3.3.8 Cold Start problem

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "OV7pWM-JGHN_" }, "source": [ "

3.3.8.1 Cold Start problem with Users

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "dfe1438c-6717-4cb3-bba3-dff0f65e0e49", "id": "0B336WmIGHOA", "colab": {} }, "source": [ "total_users = len(np.unique(df.user))\n", "users_train = len(train_averages['user'])\n", "new_users = total_users - users_train\n", "\n", "print('\\nTotal number of Users :', total_users)\n", "print('\\nNumber of Users in Train data :', users_train)\n", "print(\"\\nNo of Users that didn't appear in train data: {}({} %) \\n \".format(new_users,\n", " np.round((new_users/total_users)*100, 2)))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "\n", "Total number of Users : 480189\n", "\n", "Number of Users in Train data : 405041\n", "\n", "No of Users that didn't appear in train data: 75148(15.65 %) \n", " \n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Ce-YrA2tGHOC" }, "source": [ "> We might have to handle __new users__ ( ___75148___ ) who didn't appear in train data." ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "QW49HowmGHOD" }, "source": [ "

3.3.8.2 Cold Start problem with Movies

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "e7ec447d-f40a-4d62-d2c7-14f06806ad9e", "id": "PdYapFIaGHOE", "colab": {} }, "source": [ "total_movies = len(np.unique(df.movie))\n", "movies_train = len(train_averages['movie'])\n", "new_movies = total_movies - movies_train\n", "\n", "print('\\nTotal number of Movies :', total_movies)\n", "print('\\nNumber of Users in Train data :', movies_train)\n", "print(\"\\nNo of Movies that didn't appear in train data: {}({} %) \\n \".format(new_movies,\n", " np.round((new_movies/total_movies)*100, 2)))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "\n", "Total number of Movies : 17770\n", "\n", "Number of Users in Train data : 17424\n", "\n", "No of Movies that didn't appear in train data: 346(1.95 %) \n", " \n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "vfLw-_WgGHOG" }, "source": [ "> We might have to handle __346 movies__ (small comparatively) in test data" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "6egkG4CgGHOH" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Q7WCBgwSGHON" }, "source": [ "

3.4 Computing Similarity matrices

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "moMgv9DqGHON" }, "source": [ "

3.4.1 Computing User-User Similarity matrix

" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "colab_type": "text", "id": "bq_qbJCkGHOO" }, "source": [ "1. Calculating User User Similarity_Matrix is __not very easy__(_unless you have huge Computing Power and lots of time_) because of number of. usersbeing lare.\n", "\n", " * You can try if you want to. Your system could crash or the program stops with **Memory Error**\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Eefgxw-ZGHOP" }, "source": [ "

3.4.1.1 Trying with all dimensions (17k dimensions per user)

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "ChJI9dHJGHOQ", "colab": {} }, "source": [ "from sklearn.metrics.pairwise import cosine_similarity\n", "\n", "\n", "def compute_user_similarity(sparse_matrix, compute_for_few=False, top = 100, verbose=False, verb_for_n_rows = 20,\n", " draw_time_taken=True):\n", " no_of_users, _ = sparse_matrix.shape\n", " # get the indices of non zero rows(users) from our sparse matrix\n", " row_ind, col_ind = sparse_matrix.nonzero()\n", " row_ind = sorted(set(row_ind)) # we don't have to\n", " time_taken = list() # time taken for finding similar users for an user..\n", " \n", " # we create rows, cols, and data lists.., which can be used to create sparse matrices\n", " rows, cols, data = list(), list(), list()\n", " if verbose: print(\"Computing top\",top,\"similarities for each user..\")\n", " \n", " start = datetime.now()\n", " temp = 0\n", " \n", " for row in row_ind[:top] if compute_for_few else row_ind:\n", " temp = temp+1\n", " prev = datetime.now()\n", " \n", " # get the similarity row for this user with all other users\n", " sim = cosine_similarity(sparse_matrix.getrow(row), sparse_matrix).ravel()\n", " # We will get only the top ''top'' most similar users and ignore rest of them..\n", " top_sim_ind = sim.argsort()[-top:]\n", " top_sim_val = sim[top_sim_ind]\n", " \n", " # add them to our rows, cols and data\n", " rows.extend([row]*top)\n", " cols.extend(top_sim_ind)\n", " data.extend(top_sim_val)\n", " time_taken.append(datetime.now().timestamp() - prev.timestamp())\n", " if verbose:\n", " if temp%verb_for_n_rows == 0:\n", " print(\"computing done for {} users [ time elapsed : {} ]\"\n", " .format(temp, datetime.now()-start))\n", " \n", " \n", " # lets create sparse matrix out of these and return it\n", " if verbose: print('Creating Sparse matrix from the computed similarities')\n", " #return rows, cols, data\n", " \n", " if draw_time_taken:\n", " plt.plot(time_taken, label = 'time taken for each user')\n", " plt.plot(np.cumsum(time_taken), label='Total time')\n", " plt.legend(loc='best')\n", " plt.xlabel('User')\n", " plt.ylabel('Time (seconds)')\n", " plt.show()\n", " \n", " return sparse.csr_matrix((data, (rows, cols)), shape=(no_of_users, no_of_users)), time_taken " ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "id": "RNLuKop0GHOT", "colab": {} }, "source": [ "start = datetime.now()\n", "u_u_sim_sparse, _ = compute_user_similarity(train_sparse_matrix, compute_for_few=True, top = 100,\n", " verbose=True)\n", "print(\"-\"*100)\n", "print(\"Time taken :\",datetime.now()-start)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "QsRzdbEUGHOU" }, "source": [ "

3.4.1.2 Trying with reduced dimensions (Using TruncatedSVD for dimensionality reduction of user vector)

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "WIDu_I28GHOV" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "6h5654MXGHOV" }, "source": [ "* We have **405,041 users** in out training set and computing similarities between them..( **17K dimensional vector..**) is time consuming..\n", "\n", "\n", "- From above plot, It took roughly __8.88 sec__ for computing simlilar users for __one user__\n", " \n", " \n", "- We have __405,041 users__ with us in training set.\n", "\n", "\n", "- ${ 405041 \\times 8.88 = 3596764.08 \\sec } = 59946.068 \\min = 999.101133333 \\text{ hours}\n", "= 41.629213889 \\text{ days}...$\n", "\n", " - Even if we run on 4 cores parallelly (a typical system now a days), It will still take almost __10 and 1/2__ days.\n", " \n", " IDEA: Instead, we will try to reduce the dimentsions using SVD, so that __it might__ speed up the process..." ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "bf53b3a5-828f-457c-d354-4d52b6559767", "id": "ntGRZKe8GHOW", "colab": {} }, "source": [ "from datetime import datetime\n", "from sklearn.decomposition import TruncatedSVD\n", "\n", "start = datetime.now()\n", "\n", "# initilaize the algorithm with some parameters..\n", "# All of them are default except n_components. n_itr is for Randomized SVD solver.\n", "netflix_svd = TruncatedSVD(n_components=500, algorithm='randomized', random_state=15)\n", "trunc_svd = netflix_svd.fit_transform(train_sparse_matrix)\n", "\n", "print(datetime.now()-start)" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "0:29:07.069783\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "T5F0rmM1GHOX" }, "source": [ "Here,\n", "\n", "\n", "- $\\sum \\longleftarrow$ (netflix\\_svd.**singular\\_values\\_** )\n", "\n", "\n", "- $\\bigvee^T \\longleftarrow$ (netflix\\_svd.**components_**)\n", "\n", "\n", "- $\\bigcup$ is not returned. instead **Projection_of_X** onto the new vectorspace is returned. \n", "\n", "\n", "- It uses **randomized svd** internally, which returns **All 3 of them saperately**. Use that instead.. " ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "xw5xEQ6MGHOX", "colab": {} }, "source": [ "expl_var = np.cumsum(netflix_svd.explained_variance_ratio_)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "237de9aa-848a-47b8-ffcf-e7ebacce3905", "id": "KUps11F8GHOZ", "colab": {} }, "source": [ "fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=plt.figaspect(.5))\n", "\n", "ax1.set_ylabel(\"Variance Explained\", fontsize=15)\n", "ax1.set_xlabel(\"# Latent Facors\", fontsize=15)\n", "ax1.plot(expl_var)\n", "# annote some (latentfactors, expl_var) to make it clear\n", "ind = [1, 2,4,8,20, 60, 100, 200, 300, 400, 500]\n", "ax1.scatter(x = [i-1 for i in ind], y = expl_var[[i-1 for i in ind]], c='#ff3300')\n", "for i in ind:\n", " ax1.annotate(s =\"({}, {})\".format(i, np.round(expl_var[i-1], 2)), xy=(i-1, expl_var[i-1]),\n", " xytext = ( i+20, expl_var[i-1] - 0.01), fontweight='bold')\n", "\n", "change_in_expl_var = [expl_var[i+1] - expl_var[i] for i in range(len(expl_var)-1)]\n", "ax2.plot(change_in_expl_var)\n", "\n", "\n", "\n", "ax2.set_ylabel(\"Gain in Var_Expl with One Additional LF\", fontsize=10)\n", "ax2.yaxis.set_label_position(\"right\")\n", "ax2.set_xlabel(\"# Latent Facors\", fontsize=20)\n", "\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "stream", "text": [ "--------------------------------------------------\n", "time: 0:10:52.658092\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "FHEcJOfrGHOn" }, "source": [ "**: This is taking more time for each user than Original one.**" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "eMLuVBD5GHOn" }, "source": [ "- from above plot, It took almost __12.18__ for computing simlilar users for __one user__\n", " \n", " \n", "- We have __405041 users__ with us in training set.\n", "\n", "\n", "- ${ 405041 \\times 12.18 ==== 4933399.38 \\sec } ==== 82223.323 \\min ==== 1370.388716667 \\text{ hours}\n", "==== 57.099529861 \\text{ days}...$\n", "\n", " - Even we run on 4 cores parallelly (a typical system now a days), It will still take almost __(14 - 15) __ days.\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "_v7kZ4IFGHOo" }, "source": [ "- __Why did this happen...??__\n", "\n", "\n", " - Just think about it. It's not that difficult.\n", "\n", "---------------------------------_( sparse & dense..................get it ?? )_-----------------------------------" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "ASXSsaGmGHOo" }, "source": [ "__Is there any other way to compute user user similarity..??__" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "7ehSsq3gGHOq" }, "source": [ "-An alternative is to compute similar users for a particular user, whenenver required (**ie., Run time**)\n", " - We maintain a binary Vector for users, which tells us whether we already computed or not..\n", " - ***If not*** : \n", " - Compute top (let's just say, 1000) most similar users for this given user, and add this to our datastructure, so that we can just access it(similar users) without recomputing it again.\n", " - \n", " - ***If It is already Computed***:\n", " - Just get it directly from our datastructure, which has that information.\n", " - In production time, We might have to recompute similarities, if it is computed a long time ago. Because user preferences changes over time. If we could maintain some kind of Timer, which when expires, we have to update it ( recompute it ). \n", " - \n", " - ***Which datastructure to use:***\n", " - It is purely implementation dependant. \n", " - One simple method is to maintain a **Dictionary Of Dictionaries**.\n", " - \n", " - **key :** _userid_ \n", " - __value__: _Again a dictionary_\n", " - __key__ : _Similar User_\n", " - __value__: _Similarity Value_" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "colab_type": "text", "id": "oYouSYH0GHOr" }, "source": [ "

3.4.2 Computing Movie-Movie Similarity matrix

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "7_72kq4YGHOs", "colab": {} }, "source": [ "start = datetime.now()\n", "if not os.path.isfile('/content/drive/My Drive/Netflix_recommender/data_folder/m_m_sim_sparse.npz'):\n", " print(\"It seems you don't have that file. Computing movie_movie similarity...\")\n", " start = datetime.now()\n", " m_m_sim_sparse = cosine_similarity(X=train_sparse_matrix.T, dense_output=False)\n", " print(\"Done..\")\n", " # store this sparse matrix in disk before using it. For future purposes.\n", " print(\"Saving it to disk without the need of re-computing it again.. \")\n", " sparse.save_npz(\"m_m_sim_sparse.npz\", m_m_sim_sparse)\n", " print(\"Done..\")\n", "else:\n", " print(\"It is there, We will get it.\")\n", " m_m_sim_sparse = sparse.load_npz(\"/content/drive/My Drive/Netflix_recommender/data_folder/m_m_sim_sparse.npz\")\n", " print(\"Done ...\")\n", "\n", "print(\"It's a \",m_m_sim_sparse.shape,\" dimensional matrix\")\n", "\n", "print(datetime.now() - start)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "cd481df2-f6ea-4f01-d4d1-b500ab74f838", "id": "TXIu4Xx1GHOv", "colab": {} }, "source": [ "m_m_sim_sparse.shape" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(17771, 17771)" ] }, "metadata": { "tags": [] }, "execution_count": 59 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "FwunajS_GHOy" }, "source": [ "- Even though we have similarity measure of each movie, with all other movies, We generally don't care much about least similar movies.\n", "\n", "\n", "- Most of the times, only top_xxx similar items matters. It may be 10 or 100.\n", "\n", "\n", "- We take only those top similar movie ratings and store them in a saperate dictionary." ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "am27Q4cNGHOy", "colab": {} }, "source": [ "movie_ids = np.unique(m_m_sim_sparse.nonzero()[1])" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "7e9d1c69-1ceb-4c26-e81f-83291f44aaa5", "id": "9b8fpLlxGHO0", "colab": {} }, "source": [ "start = datetime.now()\n", "similar_movies = dict()\n", "for movie in movie_ids:\n", " # get the top similar movies and store them in the dictionary\n", " sim_movies = m_m_sim_sparse[movie].toarray().ravel().argsort()[::-1][1:]\n", " similar_movies[movie] = sim_movies[:100]\n", "print(datetime.now() - start)\n", "\n", "# just testing similar movies for movie_15\n", "similar_movies[15]" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "0:00:33.411700\n" ], "name": "stdout" }, { "output_type": "execute_result", "data": { "text/plain": [ "array([ 8279, 8013, 16528, 5927, 13105, 12049, 4424, 10193, 17590,\n", " 4549, 3755, 590, 14059, 15144, 15054, 9584, 9071, 6349,\n", " 16402, 3973, 1720, 5370, 16309, 9376, 6116, 4706, 2818,\n", " 778, 15331, 1416, 12979, 17139, 17710, 5452, 2534, 164,\n", " 15188, 8323, 2450, 16331, 9566, 15301, 13213, 14308, 15984,\n", " 10597, 6426, 5500, 7068, 7328, 5720, 9802, 376, 13013,\n", " 8003, 10199, 3338, 15390, 9688, 16455, 11730, 4513, 598,\n", " 12762, 2187, 509, 5865, 9166, 17115, 16334, 1942, 7282,\n", " 17584, 4376, 8988, 8873, 5921, 2716, 14679, 11947, 11981,\n", " 4649, 565, 12954, 10788, 10220, 10963, 9427, 1690, 5107,\n", " 7859, 5969, 1510, 2429, 847, 7845, 6410, 13931, 9840,\n", " 3706])" ] }, "metadata": { "tags": [] }, "execution_count": 62 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "X4Uf1_uZGHO2" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "XXdHrIN7GHO3" }, "source": [ "

3.4.3 Finding most similar movies using similarity matrix

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "g2S87T-0GHO4" }, "source": [ "__ Does Similarity really works as the way we expected...? __
\n", "_Let's pick some random movie and check for its similar movies...._" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "2d737e9e-a444-4ec5-aba0-6ad6363aa24d", "id": "VVQVMv5ZGHO4", "colab": {} }, "source": [ "# First Let's load the movie details into soe dataframe..\n", "# movie details are in 'netflix/movie_titles.csv'\n", "\n", "movie_titles = pd.read_csv(\"data_folder/movie_titles.csv\", sep=',', header = None,\n", " names=['movie_id', 'year_of_release', 'title'], verbose=True,\n", " index_col = 'movie_id', encoding = \"ISO-8859-1\")\n", "\n", "movie_titles.head()" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Tokenization took: 4.50 ms\n", "Type conversion took: 165.72 ms\n", "Parser memory cleanup took: 0.01 ms\n" ], "name": "stdout" }, { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
year_of_releasetitle
movie_id
12003.0Dinosaur Planet
22004.0Isle of Man TT 2004 Review
31997.0Character
41994.0Paula Abdul's Get Up & Dance
52004.0The Rise and Fall of ECW
\n", "
" ], "text/plain": [ " year_of_release title\n", "movie_id \n", "1 2003.0 Dinosaur Planet\n", "2 2004.0 Isle of Man TT 2004 Review\n", "3 1997.0 Character\n", "4 1994.0 Paula Abdul's Get Up & Dance\n", "5 2004.0 The Rise and Fall of ECW" ] }, "metadata": { "tags": [] }, "execution_count": 64 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "x_dc-9T1GHO6" }, "source": [ "

Similar Movies for 'Vampire Journals'

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "1665280e-124d-4e73-f508-808853ebba2d", "id": "hJNsE740GHO7", "colab": {} }, "source": [ "mv_id = 67\n", "\n", "print(\"\\nMovie ----->\",movie_titles.loc[mv_id].values[1])\n", "\n", "print(\"\\nIt has {} Ratings from users.\".format(train_sparse_matrix[:,mv_id].getnnz()))\n", "\n", "print(\"\\nWe have {} movies which are similarto this and we will get only top most..\".format(m_m_sim_sparse[:,mv_id].getnnz()))" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "\n", "Movie -----> Vampire Journals\n", "\n", "It has 270 Ratings from users.\n", "\n", "We have 17284 movies which are similarto this and we will get only top most..\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "GXMvP8xyGHO-", "colab": {} }, "source": [ "similarities = m_m_sim_sparse[mv_id].toarray().ravel()\n", "\n", "similar_indices = similarities.argsort()[::-1][1:]\n", "\n", "similarities[similar_indices]\n", "\n", "sim_indices = similarities.argsort()[::-1][1:] # It will sort and reverse the array and ignore its similarity (ie.,1)\n", " # and return its indices(movie_ids)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "2e929724-0612-4d54-cab4-e8a4b6081b37", "id": "igXbZvu4GHPA", "colab": {} }, "source": [ "plt.plot(similarities[sim_indices], label='All the ratings')\n", "plt.plot(similarities[sim_indices[:100]], label='top 100 similar movies')\n", "plt.title(\"Similar Movies of {}(movie_id)\".format(mv_id), fontsize=20)\n", "plt.xlabel(\"Movies (Not Movie_Ids)\", fontsize=15)\n", "plt.ylabel(\"Cosine Similarity\",fontsize=15)\n", "plt.legend()\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Ib3tzN3-GHQu" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "nByY611nGHQv" }, "source": [ "

4.4.2 Suprise BaselineModel

\n", " \n" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "t6t9A1gJGHQv", "colab": {} }, "source": [ "from surprise import BaselineOnly " ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "NvKt4O0RGHQx" }, "source": [ "__Predicted_rating : ( baseline prediction ) __\n", "\n", " - http://surprise.readthedocs.io/en/stable/basic_algorithms.html#surprise.prediction_algorithms.baseline_only.BaselineOnly \n", " >$ \\large {\\hat{r}_{ui} = b_{ui} =\\mu + b_u + b_i} $\n", "\n", "\n", "- $\\pmb \\mu $ : Average of all trainings in training data.\n", "- $\\pmb b_u$ : User bias\n", "- $\\pmb b_i$ : Item bias (movie biases) " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "57zPul1RGHQy" }, "source": [ "__Optimization function ( Least Squares Problem ) __\n", "\n", " - http://surprise.readthedocs.io/en/stable/prediction_algorithms.html#baselines-estimates-configuration \n", "\n", "> $ \\large \\sum_{r_{ui} \\in R_{train}} \\left(r_{ui} - (\\mu + b_u + b_i)\\right)^2 +\n", "\\lambda \\left(b_u^2 + b_i^2 \\right).\\text { [mimimize } {b_u, b_i]}$ " ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "118c4d00-a202-460b-dd78-a89e664d5570", "id": "dW7WNz8UGHQy", "colab": {} }, "source": [ "\n", "# options are to specify.., how to compute those user and item biases\n", "bsl_options = {'method': 'sgd',\n", " 'learning_rate': .001\n", " }\n", "bsl_algo = BaselineOnly(bsl_options=bsl_options)\n", "# run this algorithm.., It will return the train and test results..\n", "bsl_train_results, bsl_test_results = run_surprise(my_bsl_algo, trainset, testset, verbose=True)\n", "\n", "\n", "# Just store these error metrics in our models_evaluation datastructure\n", "models_evaluation_train['bsl_algo'] = bsl_train_results \n", "models_evaluation_test['bsl_algo'] = bsl_test_results" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", "Estimating biases using sgd...\n", "Done. time taken : 0:00:00.822391 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:00:01.116752\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.9347153928678286\n", "\n", "MAPE : 29.389572652358183\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.074418\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.0730330260516174\n", "\n", "MAPE : 35.04995544572911\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:00:02.014073\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "mfGIOsfVGHQ0" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "CvPjDdN8GHQ1" }, "source": [ "

4.4.3 XGBoost with initial 13 features + Surprise Baseline predictor

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "eKPn3wK0GHQ2" }, "source": [ "__Updating Train Data__" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "ad5d0309-054c-406d-dc87-c8384a5fbf12", "id": "KqCj5GvzGHQ3", "colab": {} }, "source": [ "# add our baseline_predicted value as our feature..\n", "reg_train['bslpr'] = models_evaluation_train['bsl_algo']['predictions']\n", "reg_train.head(2) " ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingbslpr
053406333.5816794.05.05.04.01.05.02.05.03.01.03.3703704.09243743.898982
199540333.5816795.05.05.04.05.03.04.04.03.05.03.5555564.09243733.371403
\n", "
" ], "text/plain": [ " user movie GAvg sur1 sur2 sur3 sur4 sur5 smr1 smr2 smr3 \\\n", "0 53406 33 3.581679 4.0 5.0 5.0 4.0 1.0 5.0 2.0 5.0 \n", "1 99540 33 3.581679 5.0 5.0 5.0 4.0 5.0 3.0 4.0 4.0 \n", "\n", " smr4 smr5 UAvg MAvg rating bslpr \n", "0 3.0 1.0 3.370370 4.092437 4 3.898982 \n", "1 3.0 5.0 3.555556 4.092437 3 3.371403 " ] }, "metadata": { "tags": [] }, "execution_count": 44 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Yrfrqx8oGHQ5" }, "source": [ "__Updating Test Data__" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "194d8d7f-a65a-4b67-f2a8-fd80daf2c5f4", "id": "KPfnztxzGHQ5", "colab": {} }, "source": [ "# add that baseline predicted ratings with Surprise to the test data as well\n", "reg_test_df['bslpr'] = models_evaluation_test['bsl_algo']['predictions']\n", "\n", "reg_test_df.head(2)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingbslpr
0808635713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167953.581679
1941866713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167943.581679
\n", "
" ], "text/plain": [ " user movie GAvg sur1 sur2 sur3 sur4 sur5 \\\n", "0 808635 71 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "1 941866 71 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "\n", " smr1 smr2 smr3 smr4 smr5 UAvg MAvg \\\n", "0 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "1 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "\n", " rating bslpr \n", "0 5 3.581679 \n", "1 4 3.581679 " ] }, "metadata": { "tags": [] }, "execution_count": 45 } ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "e51e11b3-f92e-4af9-dc65-f981eabab9c7", "id": "x7NO8ManGHQ7", "colab": {} }, "source": [ "# prepare train data\n", "x_train = reg_train.drop(['user', 'movie','rating'], axis=1)\n", "y_train = reg_train['rating']\n", "\n", "# Prepare Test data\n", "x_test = reg_test_df.drop(['user','movie','rating'], axis=1)\n", "y_test = reg_test_df['rating']\n", "\n", "# initialize Our first XGBoost model...\n", "xgb_bsl = xgb.XGBRegressor(silent=False, n_jobs=13, random_state=15, n_estimators=100)\n", "train_results, test_results = run_xgboost(xgb_bsl, x_train, y_train, x_test, y_test)\n", "\n", "# store the results in models_evaluations dictionaries\n", "models_evaluation_train['xgb_bsl'] = train_results\n", "models_evaluation_test['xgb_bsl'] = test_results\n", "\n", "xgb.plot_importance(xgb_bsl)\n", "plt.show()\n" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model..\n", "Done. Time taken : 0:00:02.388635\n", "\n", "Done \n", "\n", "Evaluating the model with TRAIN data...\n", "Evaluating Test data\n", "\n", "TEST DATA\n", "------------------------------\n", "RMSE : 1.0763419061709816\n", "MAPE : 34.491235560745295\n" ], "name": "stdout" }, { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "dkCFYIfxGHRa" }, "source": [ "

4.4.6 Matrix Factorization Techniques

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "_jSmfkoTGHRb" }, "source": [ "

4.4.6.1 SVD Matrix Factorization User Movie intractions

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "JNLdtZ30GHRb", "colab": {} }, "source": [ "from surprise import SVD" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "MSyKGXPkGHRc" }, "source": [ "http://surprise.readthedocs.io/en/stable/matrix_factorization.html#surprise.prediction_algorithms.matrix_factorization.SVD " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "kFy5-aZAGHRd" }, "source": [ "- __ Predicted Rating : __\n", " - \n", " - $ \\large \\hat r_{ui} = \\mu + b_u + b_i + q_i^Tp_u $\n", " \n", " - $\\pmb q_i$ - Representation of item(movie) in latent factor space\n", " \n", " - $\\pmb p_u$ - Representation of user in new latent factor space\n", " \n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "zHTRaqUHGHRd" }, "source": [ "- A BASIC MATRIX FACTORIZATION MODEL in https://datajobs.com/data-science-repo/Recommender-Systems-[Netflix].pdf" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "_uQA4NX7GHRe" }, "source": [ "- __Optimization problem with user item interactions and regularization (to avoid overfitting)__\n", " - \n", " - $\\large \\sum_{r_{ui} \\in R_{train}} \\left(r_{ui} - \\hat{r}_{ui} \\right)^2 +\n", "\\lambda\\left(b_i^2 + b_u^2 + ||q_i||^2 + ||p_u||^2\\right) $" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "26accf59-7e7b-4973-9e3f-6a47d2a7c32d", "id": "E5SvFo1BGHRe", "colab": {} }, "source": [ "# initiallize the model\n", "svd = SVD(n_factors=100, biased=True, random_state=15, verbose=True)\n", "svd_train_results, svd_test_results = run_surprise(svd, trainset, testset, verbose=True)\n", "\n", "# Just store these error metrics in our models_evaluation datastructure\n", "models_evaluation_train['svd'] = svd_train_results \n", "models_evaluation_test['svd'] = svd_test_results" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", "Processing epoch 0\n", "Processing epoch 1\n", "Processing epoch 2\n", "Processing epoch 3\n", "Processing epoch 4\n", "Processing epoch 5\n", "Processing epoch 6\n", "Processing epoch 7\n", "Processing epoch 8\n", "Processing epoch 9\n", "Processing epoch 10\n", "Processing epoch 11\n", "Processing epoch 12\n", "Processing epoch 13\n", "Processing epoch 14\n", "Processing epoch 15\n", "Processing epoch 16\n", "Processing epoch 17\n", "Processing epoch 18\n", "Processing epoch 19\n", "Done. time taken : 0:00:07.297438 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:00:01.305539\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.6574721240954099\n", "\n", "MAPE : 19.704901088660474\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.067811\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.0726046873826458\n", "\n", "MAPE : 35.01953535988152\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:00:08.671347\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "LYtjizREGHRg" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "igvo-ChaGHRh" }, "source": [ "

4.4.6.2 SVD Matrix Factorization with implicit feedback from user ( user rated movies )

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "8dbSFL97GHRi", "colab": {} }, "source": [ "from surprise import SVDpp" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Lt2dMwUBGHRj" }, "source": [ "- -----> 2.5 Implicit Feedback in http://courses.ischool.berkeley.edu/i290-dm/s11/SECURE/a1-koren.pdf" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "MtJ96Iu8GHRk" }, "source": [ "- __ Predicted Rating : __\n", " - \n", " - $ \\large \\hat{r}_{ui} = \\mu + b_u + b_i + q_i^T\\left(p_u +\n", " |I_u|^{-\\frac{1}{2}} \\sum_{j \\in I_u}y_j\\right) $ " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "ENt1oW5rGHRk" }, "source": [ " - $ \\pmb{I_u}$ --- the set of all items rated by user u\n", "\n", "- $\\pmb{y_j}$ --- Our new set of item factors that capture implicit ratings. " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "HAq-DaWoGHRl" }, "source": [ "- __Optimization problem with user item interactions and regularization (to avoid overfitting)__\n", " - \n", " - $ \\large \\sum_{r_{ui} \\in R_{train}} \\left(r_{ui} - \\hat{r}_{ui} \\right)^2 +\n", "\\lambda\\left(b_i^2 + b_u^2 + ||q_i||^2 + ||p_u||^2 + ||y_j||^2\\right) $ " ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "d4a9169f-e5da-4c71-9394-2de56687bad3", "id": "VXSVAgBnGHRl", "colab": {} }, "source": [ "# initiallize the model\n", "svdpp = SVDpp(n_factors=50, random_state=15, verbose=True)\n", "svdpp_train_results, svdpp_test_results = run_surprise(svdpp, trainset, testset, verbose=True)\n", "\n", "# Just store these error metrics in our models_evaluation datastructure\n", "models_evaluation_train['svdpp'] = svdpp_train_results \n", "models_evaluation_test['svdpp'] = svdpp_test_results\n" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", " processing epoch 0\n", " processing epoch 1\n", " processing epoch 2\n", " processing epoch 3\n", " processing epoch 4\n", " processing epoch 5\n", " processing epoch 6\n", " processing epoch 7\n", " processing epoch 8\n", " processing epoch 9\n", " processing epoch 10\n", " processing epoch 11\n", " processing epoch 12\n", " processing epoch 13\n", " processing epoch 14\n", " processing epoch 15\n", " processing epoch 16\n", " processing epoch 17\n", " processing epoch 18\n", " processing epoch 19\n", "Done. time taken : 0:01:56.765007 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:00:06.387920\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.6032438403305899\n", "\n", "MAPE : 17.49285063490268\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.071642\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.0728491944183447\n", "\n", "MAPE : 35.03817913919887\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:02:03.225068\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "JY6alxu4GHRn" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "PL2V49faGHRn" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "OChrCmcGGHRo" }, "source": [ "

4.4.7 XgBoost with 13 features + Surprise Baseline + Surprise KNNbaseline + MF Techniques

" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "jhzF7uV0GHRp" }, "source": [ "__Preparing Train data__" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "c33595e6-d05e-4807-e813-1ecd42da5e38", "id": "egHxbWBNGHRp", "colab": {} }, "source": [ "# add the predicted values from both knns to this dataframe\n", "reg_train['svd'] = models_evaluation_train['svd']['predictions']\n", "reg_train['svdpp'] = models_evaluation_train['svdpp']['predictions']\n", "\n", "reg_train.head(2) " ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2...smr4smr5UAvgMAvgratingbslprknn_bsl_uknn_bsl_msvdsvdpp
053406333.5816794.05.05.04.01.05.02.0...3.01.03.3703704.09243743.8989823.930023.8679584.3037643.621664
199540333.5816795.05.05.04.05.03.04.0...3.05.03.5555564.09243733.3714033.177333.0763023.2789673.538247
\n", "

2 rows × 21 columns

\n", "
" ], "text/plain": [ " user movie GAvg sur1 sur2 sur3 sur4 sur5 smr1 smr2 ... \\\n", "0 53406 33 3.581679 4.0 5.0 5.0 4.0 1.0 5.0 2.0 ... \n", "1 99540 33 3.581679 5.0 5.0 5.0 4.0 5.0 3.0 4.0 ... \n", "\n", " smr4 smr5 UAvg MAvg rating bslpr knn_bsl_u knn_bsl_m \\\n", "0 3.0 1.0 3.370370 4.092437 4 3.898982 3.93002 3.867958 \n", "1 3.0 5.0 3.555556 4.092437 3 3.371403 3.17733 3.076302 \n", "\n", " svd svdpp \n", "0 4.303764 3.621664 \n", "1 3.278967 3.538247 \n", "\n", "[2 rows x 21 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 59 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "AYR2mci0GHRr" }, "source": [ "__Preparing Test data __" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "39997a27-2a18-46b8-8b1f-f43f5b502151", "id": "7kLmXTQjGHRr", "colab": {} }, "source": [ "reg_test_df['svd'] = models_evaluation_test['svd']['predictions']\n", "reg_test_df['svdpp'] = models_evaluation_test['svdpp']['predictions']\n", "\n", "reg_test_df.head(2) " ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2...smr4smr5UAvgMAvgratingbslprknn_bsl_uknn_bsl_msvdsvdpp
0808635713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.581679...3.5816793.5816793.5816793.58167953.5816793.5816793.5816793.5816793.581679
1941866713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.581679...3.5816793.5816793.5816793.58167943.5816793.5816793.5816793.5816793.581679
\n", "

2 rows × 21 columns

\n", "
" ], "text/plain": [ " user movie GAvg sur1 sur2 sur3 sur4 sur5 \\\n", "0 808635 71 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "1 941866 71 3.581679 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "\n", " smr1 smr2 ... smr4 smr5 UAvg MAvg \\\n", "0 3.581679 3.581679 ... 3.581679 3.581679 3.581679 3.581679 \n", "1 3.581679 3.581679 ... 3.581679 3.581679 3.581679 3.581679 \n", "\n", " rating bslpr knn_bsl_u knn_bsl_m svd svdpp \n", "0 5 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "1 4 3.581679 3.581679 3.581679 3.581679 3.581679 \n", "\n", "[2 rows x 21 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 60 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "uobp0yUdGHRs" }, "source": [ " " ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "83ccbda0-527a-4e09-c9cf-ae86ac1cd7c1", "id": "Etf4AipqGHRt", "colab": {} }, "source": [ "# prepare x_train and y_train\n", "x_train = reg_train.drop(['user', 'movie', 'rating',], axis=1)\n", "y_train = reg_train['rating']\n", "\n", "# prepare test data\n", "x_test = reg_test_df.drop(['user', 'movie', 'rating'], axis=1)\n", "y_test = reg_test_df['rating']\n", "\n", "\n", "\n", "xgb_final = xgb.XGBRegressor(n_jobs=10, random_state=15)\n", "train_results, test_results = run_xgboost(xgb_final, x_train, y_train, x_test, y_test)\n", "\n", "# store the results in models_evaluations dictionaries\n", "models_evaluation_train['xgb_final'] = train_results\n", "models_evaluation_test['xgb_final'] = test_results\n", "\n", "\n", "xgb.plot_importance(xgb_final)\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model..\n", "Done. Time taken : 0:00:04.203252\n", "\n", "Done \n", "\n", "Evaluating the model with TRAIN data...\n", "Evaluating Test data\n", "\n", "TEST DATA\n", "------------------------------\n", "RMSE : 1.0763580984894978\n", "MAPE : 34.487391651053336\n" ], "name": "stdout" }, { "output_type": "display_data", "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('');\n", " button.click(method_name, toolbar_event);\n", " button.mouseover(tooltip, toolbar_mouse_event);\n", " nav_element.append(button);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = $('');\n", " nav_element.append(status_bar);\n", " this.message = status_bar[0];\n", "\n", " // Add the close button to the window.\n", " var buttongrp = $('
');\n", " var button = $('');\n", " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", " buttongrp.append(button);\n", " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", " titlebar.prepend(buttongrp);\n", "}\n", "\n", "mpl.figure.prototype._root_extra_style = function(el){\n", " var fig = this\n", " el.on(\"remove\", function(){\n", "\tfig.close_ws(fig, {});\n", " });\n", "}\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(el){\n", " // this is important to make the div 'focusable\n", " el.attr('tabindex', 0)\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " }\n", " else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "\n", "}\n", "\n", "mpl.figure.prototype._key_event_extra = function(event, name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager)\n", " manager = IPython.keyboard_manager;\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which == 13) {\n", " this.canvas_div.blur();\n", " event.shiftKey = false;\n", " // Send a \"J\" for go to next cell\n", " event.which = 74;\n", " event.keyCode = 74;\n", " manager.command_mode();\n", " manager.handle_keydown(event);\n", " }\n", "}\n", "\n", "mpl.figure.prototype.handle_save = function(fig, msg) {\n", " fig.ondownload(fig, null);\n", "}\n", "\n", "\n", "mpl.find_output_cell = function(html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] == html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "}\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel != null) {\n", " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", "}\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "display_data", "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "OTH9n3xoGHRw" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "BVDDPizEGHRx" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "kw26rJ3SGHRy" }, "source": [ "

4.5 Comparision between all models

" ] }, { "cell_type": "code", "metadata": { "scrolled": false, "colab_type": "code", "outputId": "9124baa4-ff9f-4ab4-c9f4-4d4af70f46f7", "id": "vSx1wSCDGHRy", "colab": {} }, "source": [ "# Saving our TEST_RESULTS into a dataframe so that you don't have to run it again\n", "pd.DataFrame(models_evaluation_test).to_csv('sample/small/small_sample_results.csv')\n", "models = pd.read_csv('sample/small/small_sample_results.csv', index_col=0)\n", "models.loc['rmse'].sort_values()" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "svd 1.0726046873826458\n", "knn_bsl_u 1.0726493739667242\n", "knn_bsl_m 1.072758832653683\n", "svdpp 1.0728491944183447\n", "bsl_algo 1.0730330260516174\n", "xgb_knn_bsl_mu 1.0753229281412784\n", "xgb_all_models 1.075480663561971\n", "first_algo 1.0761851474385373\n", "xgb_bsl 1.0763419061709816\n", "xgb_final 1.0763580984894978\n", "xgb_knn_bsl 1.0763602465199797\n", "Name: rmse, dtype: object" ] }, "metadata": { "tags": [] }, "execution_count": 67 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "WGZU19iSGHR0" }, "source": [ " " ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "530dd853-d632-4187-b1f8-be58f60b5e28", "id": "g0OB4lW0GHR1", "colab": {} }, "source": [ "print(\"-\"*100)\n", "print(\"Total time taken to run this entire notebook ( with saved files) is :\",datetime.now()-globalstart)" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "----------------------------------------------------------------------------------------------------\n", "Total time taken to run this entire notebook ( with saved files) is : 0:42:08.302761\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Av5WS6n2xrsZ", "colab_type": "text" }, "source": [ "

5. Assignment

" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "id": "JkK0HIzgxrsd", "colab_type": "text" }, "source": [ "1.Instead of using 10K users and 1K movies to train the above models, use 25K users and 3K movies (or more) to train all of the above models. Report the RMSE and MAPE on the test data using larger amount of data and provide a comparison between various models as shown above.\n", "\n", "NOTE: Please be patient as some of the code snippets make take many hours to compelte execution.\n", "\n", "2.Tune hyperparamters of all the Xgboost models above to improve the RMSE." ] }, { "cell_type": "code", "metadata": { "id": "C-s6Laykxrsd", "colab_type": "code", "outputId": "83116885-7860-48e2-befd-8eca1bd66286", "colab": {} }, "source": [ "%%javascript\n", "// Converts integer to roman numeral\n", "// https://github.com/kmahelona/ipython_notebook_goodies\n", "// https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js\n", "function romanize(num) {\n", " var lookup = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},\n", "\troman = '',\n", "\t i;\n", "\tfor ( i in lookup ) {\n", "\t while ( num >= lookup[i] ) {\n", "\t\troman += i;\n", "\t\tnum -= lookup[i];\n", "\t }\n", "\t}\n", "\treturn roman;\n", " }\n", "\n", "// Builds a
    Table of Contents from all in DOM\n", "function createTOC(){\n", " var toc = \"\";\n", " var level = 0;\n", " var levels = {}\n", " $('#toc').html('');\n", "\n", " $(\":header\").each(function(i){\n", "\t if (this.id=='tocheading'){return;}\n", " \n", "\t var titleText = this.innerHTML;\n", "\t var openLevel = this.tagName[1];\n", "\n", "\t if (levels[openLevel]){\n", "\t\tlevels[openLevel] += 1;\n", "\t } else{\n", "\t\tlevels[openLevel] = 1;\n", "\t }\n", "\n", "\t if (openLevel > level) {\n", "\t\ttoc += (new Array(openLevel - level + 1)).join('
      ');\n", "\t } else if (openLevel < level) {\n", "\t\ttoc += (new Array(level - openLevel + 1)).join(\"
    \");\n", "\t\tfor (i=level;i>openLevel;i--){levels[i]=0;}\n", "\t }\n", "\n", "\t level = parseInt(openLevel);\n", "\n", "\n", "\t if (this.id==''){this.id = this.innerHTML.replace(/ /g,\"-\")}\n", "\t var anchor = this.id;\n", " \n", "\t toc += '
  • ' + titleText + '
  • ';\n", " \n", "\t});\n", "\n", " \n", " if (level) {\n", "\ttoc += (new Array(level + 1)).join(\"
\");\n", " }\n", "\n", " \n", " $('#toc').append(toc);\n", "\n", "};\n", "\n", "// Executes the createToc function\n", "setTimeout(function(){createTOC();},100);\n", "\n", "// Rebuild to TOC every minute\n", "setInterval(function(){createTOC();},60000);" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "application/javascript": [ "// Converts integer to roman numeral\n", "// https://github.com/kmahelona/ipython_notebook_goodies\n", "// https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js\n", "function romanize(num) {\n", " var lookup = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},\n", "\troman = '',\n", "\t i;\n", "\tfor ( i in lookup ) {\n", "\t while ( num >= lookup[i] ) {\n", "\t\troman += i;\n", "\t\tnum -= lookup[i];\n", "\t }\n", "\t}\n", "\treturn roman;\n", " }\n", "\n", "// Builds a
    Table of Contents from all in DOM\n", "function createTOC(){\n", " var toc = \"\";\n", " var level = 0;\n", " var levels = {}\n", " $('#toc').html('');\n", "\n", " $(\":header\").each(function(i){\n", "\t if (this.id=='tocheading'){return;}\n", " \n", "\t var titleText = this.innerHTML;\n", "\t var openLevel = this.tagName[1];\n", "\n", "\t if (levels[openLevel]){\n", "\t\tlevels[openLevel] += 1;\n", "\t } else{\n", "\t\tlevels[openLevel] = 1;\n", "\t }\n", "\n", "\t if (openLevel > level) {\n", "\t\ttoc += (new Array(openLevel - level + 1)).join('
      ');\n", "\t } else if (openLevel < level) {\n", "\t\ttoc += (new Array(level - openLevel + 1)).join(\"
    \");\n", "\t\tfor (i=level;i>openLevel;i--){levels[i]=0;}\n", "\t }\n", "\n", "\t level = parseInt(openLevel);\n", "\n", "\n", "\t if (this.id==''){this.id = this.innerHTML.replace(/ /g,\"-\")}\n", "\t var anchor = this.id;\n", " \n", "\t toc += '
  • ' + titleText + '
  • ';\n", " \n", "\t});\n", "\n", " \n", " if (level) {\n", "\ttoc += (new Array(level + 1)).join(\"
\");\n", " }\n", "\n", " \n", " $('#toc').append(toc);\n", "\n", "};\n", "\n", "// Executes the createToc function\n", "setTimeout(function(){createTOC();},100);\n", "\n", "// Rebuild to TOC every minute\n", "setInterval(function(){createTOC();},60000);" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "id": "RqU78-8S6ER_", "colab_type": "code", "outputId": "47a85ab7-ae6c-4e11-b747-426f9a110d1e", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "tuned_models_evaluation_train = dict()\n", "tuned_models_evaluation_test = dict()\n", "\n", "tuned_models_evaluation_train, tuned_models_evaluation_test" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "({}, {})" ] }, "metadata": { "tags": [] }, "execution_count": 13 } ] }, { "cell_type": "markdown", "metadata": { "id": "ZFCtXdAh6Dcy", "colab_type": "text" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "16u9RhlD6LZW" }, "source": [ "

5.1 XGBoost with hyperparameter tuning with initial 13 features

" ] }, { "cell_type": "code", "metadata": { "id": "iqJ7mlWKoHVV", "colab_type": "code", "colab": {} }, "source": [ "param_grid = dict(\n", " learning_rate = [0.0001,0.001,0.01,0.1],\n", " max_depth = [3,4,5,6],\n", " n_estimators = [100,150,200,250]\n", "\n", ")" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "HpFO-ggkoHVX", "colab_type": "code", "colab": {} }, "source": [ "from sklearn.model_selection import GridSearchCV\n", "from xgboost.sklearn import XGBRegressor" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "IeRYzpW8oHVY", "colab_type": "text" }, "source": [ "### 5.1 Tuning XGBoost with initial 13 features" ] }, { "cell_type": "code", "metadata": { "id": "NlFNg8JRoHVZ", "colab_type": "code", "colab": {} }, "source": [ "# prepare Train data\n", "x_train = reg_train.drop(['user','movie','rating'], axis=1)\n", "y_train = reg_train['rating']\n", "\n", "# Prepare Test data\n", "x_test = reg_test_df.drop(['user','movie','rating'], axis=1)\n", "y_test = reg_test_df['rating']\n" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "NAcgFLWboHVd", "colab_type": "code", "colab": {} }, "source": [ "# making model ready for tuning\n", "xgb_model = XGBRegressor(silent=False, n_jobs=-1,random_state=15,verbosity=1,nthread=-1)\n", "xgb_knn_bsl = GridSearchCV(xgb_model,param_grid,n_jobs=-1,cv = 3,verbose=10,return_train_score=True)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "scrolled": true, "id": "WJxy3amqoHVf", "colab_type": "code", "colab": {} }, "source": [ "train_results, test_results = run_xgboost(xgb_knn_bsl, x_train, y_train, x_test, y_test)\n", "\n", "# store the results in models_evaluations dictionaries\n", "tuned_models_evaluation_train['first_algo'] = train_results\n", "tuned_models_evaluation_test['first_algo'] = test_results" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "1PCfMLyeJVzS", "colab_type": "text" }, "source": [ "Done. Time taken : 0:34:43.292529\n", "\n", "Done \n", "\n", "Evaluating the model with TRAIN data...\n", "Evaluating Test data\n", "\n", "> TEST DATA Scores\n", "------------------------------\n", "* RMSE : 1.074079123678349\n", "* MAPE : 34.74543952747899\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "code", "metadata": { "id": "iQA0HwZoLZG9", "colab_type": "code", "outputId": "7fac3368-8ac8-4ba2-ad17-a3ec4459f4d0", "colab": { "base_uri": "https://localhost:8080/", "height": 119 } }, "source": [ "print(x_train.columns)\n", "print(xgb_knn_bsl.best_estimator_.feature_importances_)" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Index(['GAvg', 'sur1', 'sur2', 'sur3', 'sur4', 'sur5', 'smr1', 'smr2', 'smr3',\n", " 'smr4', 'smr5', 'UAvg', 'MAvg'],\n", " dtype='object')\n", "[0. 0.09263241 0.07177851 0.07284065 0.05912598 0.06930886\n", " 0.18233553 0.07926813 0.03691885 0.02542087 0.01437838 0.1986779\n", " 0.0973139 ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "EgWg9WRPMJkD", "colab_type": "code", "outputId": "0f0c0651-670f-4761-e035-0f32380bdfb8", "colab": { "base_uri": "https://localhost:8080/", "height": 295 } }, "source": [ "import xgboost as xgb\n", "xgb.plot_importance(xgb_knn_bsl.best_estimator_)\n", "plt.show()" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "image/png": "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\nJGVqIiIikrJI3Z0lIlKVVq1axY033siXX35JTk4Ot99+O2+99RYzZ84kNzeXRo0aMWrUKBo3bszq\n1av505/+xLJly9i8eTO///3v6du3b1W/hUqX1iYSfjL9hfjp2s1sOLDG3e+KC6p62N2HprMWEZGd\nddttt3H88cdz3333sXHjRjZs2ECrVq248sorAZg0aRL3338/I0eO5PHHH6dly5Y88MADrFixgu7d\nu3P66adHKuMoGVU9nNUN+BI4y8xKfzq9UkTpP1iUw3OyWVRqjUqdsGvVGguGWr16NR9++CFnnnkm\nEPxu2XPPPalf/5fJOdavX09OTvCrLCcnh7Vr17J161bWrl1LgwYNSqZqr06q+h31I5hkcTBwLPCu\nmXUHBrj7WQBm1gW41t17mtkA4HrgJ+BToMjd/1jeARRKJSI7IzYL+JIlS2jYsCHDhg1j3rx5HHbY\nYfz5z3+mXr16jB49mueff5499tiDSZMmAXDuuecyePBgjj/+eNauXcvo0aPJza3qv9srX5U1ETOr\nA5wEXAzsRdBQ3gVmAA+a2e7uvpYgV+QpMzsAuAnoAKwmmB7+06qoXUR2Lfn5+SxYsIAvvviC/v37\nc8EFFzB+/Hhuv/12zj33XLp370737t2ZPHkyY8aMoV+/frz77rs0btyYYcOG8d1333HTTTcxZswY\n6tWrV+ZxNmzYEKlZhyH9TWRrOct7Am+4+3ozexa4ycyudPdNZvYycLqZTSaI170OOBF4y91XAJjZ\nM8ChFRWgPBER2RkbijeTl5fH3nvvzf7770+vXr0A6NevHw8++OA2w2UDBgxg0KBBjBw5ktGjRzNo\n0CDatGlDmzZtmDhxIrvttlu5w2v5+flZM1SYbChVus+tfiQInorXEFhOcOZxkpkVAHMIAqu6hts8\nRRBa1RWY7e6rUy1AeSLpoVorX1TqhF2r1limxz777MN+++3H119/DcB7771Hy5YtKSgoKNl25syZ\ntGjRAoD999+f994LgliXL1/OwoULOfDAA3eqlmyU7njcNWb2rZl1dffXw6TC7sDDwN+Apu5eBGBm\nFxE0ltcIskImAH8gaCgQhFSNMbNfEQxn9QVKB12JiKTNTTfdxLXXXktxcTFNmzZl1KhR3HjjjSxc\nuJCcnByaNGnCiBEjALj00ksZNmwYp59+Olu3buXaa6+lYcOGVfwOKl8mromcD9xvZveEz0cARwCv\n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\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "yx-NFQWyb84m", "colab": {} }, "source": [ "" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "ELnx7ypkoHVm", "colab_type": "text" }, "source": [ "### 5.2 Tuning XGBoost with initial 13 features + Surprise Baseline predictor" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "TCybeBBdOLOY", "colab": {} }, "source": [ "from surprise import BaselineOnly " ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "ramGwIIxOLOm" }, "source": [ "__Predicted_rating : ( baseline prediction ) __\n", "\n", " - http://surprise.readthedocs.io/en/stable/basic_algorithms.html#surprise.prediction_algorithms.baseline_only.BaselineOnly \n", " >$ \\large {\\hat{r}_{ui} = b_{ui} =\\mu + b_u + b_i} $\n", "\n", "\n", "- $\\pmb \\mu $ : Average of all trainings in training data.\n", "- $\\pmb b_u$ : User bias\n", "- $\\pmb b_i$ : Item bias (movie biases) " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "C6vhbbSAOLOo" }, "source": [ "__Optimization function ( Least Squares Problem ) __\n", "\n", " - http://surprise.readthedocs.io/en/stable/prediction_algorithms.html#baselines-estimates-configuration \n", "\n", "> $ \\large \\sum_{r_{ui} \\in R_{train}} \\left(r_{ui} - (\\mu + b_u + b_i)\\right)^2 +\n", "\\lambda \\left(b_u^2 + b_i^2 \\right).\\text { [mimimize } {b_u, b_i]}$ " ] }, { "cell_type": "code", "metadata": { "id": "_3fCU9RAoHVo", "colab_type": "code", "outputId": "552c14c6-e0fc-4aef-e518-0e6d0ededcad", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "# create the traindata from the dataframe...\n", "train_data = Dataset.load_from_df(reg_train[['user', 'movie', 'rating']], reader)\n", "\n", "# build the trainset from traindata.., It is of dataset format from surprise library..\n", "trainset = train_data.build_full_trainset() \n", "\n", "testset = list(zip(reg_test_df.user.values, reg_test_df.movie.values, reg_test_df.rating.values))\n", "testset[:3]" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[(808635, 71, 5), (941866, 71, 4), (1737912, 71, 3)]" ] }, "metadata": { "tags": [] }, "execution_count": 22 } ] }, { "cell_type": "code", "metadata": { "id": "a5-T-79BoHVq", "colab_type": "code", "outputId": "522da646-1d78-451b-8623-88c64806c0b1", "colab": { "base_uri": "https://localhost:8080/", "height": 493 } }, "source": [ "# options are to specify.., how to compute those user and item biases\n", "bsl_options = {'method': 'sgd',\n", " 'learning_rate': .001\n", " }\n", "bsl_algo = BaselineOnly(bsl_options=bsl_options)\n", "# run this algorithm.., It will return the train and test results..\n", "bsl_train_results, bsl_test_results = run_surprise(bsl_algo, trainset, testset, verbose=True)\n", "\n", "\n", "# Just store these error metrics in our models_evaluation datastructure\n", "tuned_models_evaluation_train['bsl_algo'] = bsl_train_results \n", "tuned_models_evaluation_test['bsl_algo'] = bsl_test_results" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", "Estimating biases using sgd...\n", "Done. time taken : 0:00:01.676659 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:00:02.528766\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.9552562205339807\n", "\n", "MAPE : 30.353233415224267\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.070667\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.0731636807255809\n", "\n", "MAPE : 34.989136338308896\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:00:04.278548\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "D4Yj8qwaPNTG" }, "source": [ "__Updating Train Data__" ] }, { "cell_type": "code", "metadata": { "id": "owzIgPVEoHVz", "colab_type": "code", "outputId": "a114673e-e359-480c-ccff-40e6ab91d278", "colab": { "base_uri": "https://localhost:8080/", "height": 111 } }, "source": [ "# add our baseline_predicted value as our feature..\n", "reg_train['bslpr'] = tuned_models_evaluation_train['bsl_algo']['predictions']\n", "reg_train.head(2) \n" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingknn_bsl_uknn_bsl_mbslpr
0174683103.5875815.05.03.04.04.03.05.04.03.02.03.8823533.61111154.9967934.9775543.672848
1233949103.5875814.04.05.01.03.02.03.02.03.03.02.6923083.61111133.0624533.0517253.688917
\n", "
" ], "text/plain": [ " user movie GAvg sur1 ... rating knn_bsl_u knn_bsl_m bslpr\n", "0 174683 10 3.587581 5.0 ... 5 4.996793 4.977554 3.672848\n", "1 233949 10 3.587581 4.0 ... 3 3.062453 3.051725 3.688917\n", "\n", "[2 rows x 19 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 54 } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "b2LKcf0FPSi5" }, "source": [ "__Updating Train Data__" ] }, { "cell_type": "code", "metadata": { "id": "E8m67TjMOr8J", "colab_type": "code", "outputId": "0544e615-59b2-4d4f-a008-cb3884f5808c", "colab": { "base_uri": "https://localhost:8080/", "height": 131 } }, "source": [ "# add that baseline predicted ratings with Surprise to the test data as well\n", "reg_test_df['bslpr'] = tuned_models_evaluation_test['bsl_algo']['predictions']\n", "reg_test_df.head(2)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingknn_bsl_uknn_bsl_mbslpr
0808635713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167953.5799493.5799493.579949
1941866713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167943.5799493.5799493.579949
\n", "
" ], "text/plain": [ " user movie GAvg sur1 ... rating knn_bsl_u knn_bsl_m bslpr\n", "0 808635 71 3.581679 3.581679 ... 5 3.579949 3.579949 3.579949\n", "1 941866 71 3.581679 3.581679 ... 4 3.579949 3.579949 3.579949\n", "\n", "[2 rows x 19 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 55 } ] }, { "cell_type": "code", "metadata": { "id": "C5FcFpDIO7FE", "colab_type": "code", "colab": {} }, "source": [ "#here" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "pJ3IvsMFoHV1", "colab_type": "code", "colab": {} }, "source": [ "# prepare train data\n", "x_train = reg_train.drop(['user', 'movie','rating'], axis=1)\n", "y_train = reg_train['rating']\n", "\n", "# Prepare Test data\n", "x_test = reg_test_df.drop(['user','movie','rating'], axis=1)\n", "y_test = reg_test_df['rating']\n", "\n", "# making model ready for tuning\n", "xgb_model = XGBRegressor(silent=False, n_jobs=-1,random_state=15,verbosity=1,nthread=-1)\n", "xgb_bsl = GridSearchCV(xgb_model,param_grid,n_jobs=-1,cv = 3,verbose=10,return_train_score=True)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "scrolled": true, "id": "BIuMvqu1oHV4", "colab_type": "code", "outputId": "404de5e1-117e-47b9-c424-96cd8c8ab705", "colab": { "base_uri": "https://localhost:8080/", "height": 666 } }, "source": [ "train_results, test_results = run_xgboost(xgb_bsl, x_train, y_train, x_test, y_test)\n", "\n", "# store the results in models_evaluations dictionaries\n", "tuned_models_evaluation_train['xgb_bsl'] = train_results\n", "tuned_models_evaluation_test['xgb_bsl'] = test_results" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model..\n", "Fitting 3 folds for each of 64 candidates, totalling 192 fits\n" ], "name": "stdout" }, { "output_type": "stream", "text": [ "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n", "[Parallel(n_jobs=-1)]: Done 5 tasks | elapsed: 49.6s\n", "[Parallel(n_jobs=-1)]: Done 10 tasks | elapsed: 1.6min\n", "[Parallel(n_jobs=-1)]: Done 17 tasks | elapsed: 2.5min\n", "/usr/local/lib/python3.6/dist-packages/joblib/externals/loky/process_executor.py:706: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.\n", " \"timeout or by a memory leak.\", UserWarning\n", "[Parallel(n_jobs=-1)]: Done 24 tasks | elapsed: 4.0min\n", "[Parallel(n_jobs=-1)]: Done 33 tasks | elapsed: 5.9min\n", "[Parallel(n_jobs=-1)]: Done 42 tasks | elapsed: 8.0min\n", "[Parallel(n_jobs=-1)]: Done 53 tasks | elapsed: 10.5min\n", "[Parallel(n_jobs=-1)]: Done 64 tasks | elapsed: 12.2min\n", "[Parallel(n_jobs=-1)]: Done 77 tasks | elapsed: 14.6min\n", "[Parallel(n_jobs=-1)]: Done 90 tasks | elapsed: 17.8min\n", "[Parallel(n_jobs=-1)]: Done 105 tasks | elapsed: 21.1min\n", "[Parallel(n_jobs=-1)]: Done 120 tasks | elapsed: 23.9min\n", "[Parallel(n_jobs=-1)]: Done 137 tasks | elapsed: 28.3min\n", "[Parallel(n_jobs=-1)]: Done 154 tasks | elapsed: 32.0min\n", "[Parallel(n_jobs=-1)]: Done 173 tasks | elapsed: 35.5min\n", "[Parallel(n_jobs=-1)]: Done 192 out of 192 | elapsed: 41.1min finished\n", "/usr/local/lib/python3.6/dist-packages/xgboost/core.py:587: FutureWarning: Series.base is deprecated and will be removed in a future version\n", " if getattr(data, 'base', None) is not None and \\\n", "/usr/local/lib/python3.6/dist-packages/xgboost/core.py:588: FutureWarning: Series.base is deprecated and will be removed in a future version\n", " data.base is not None and isinstance(data, np.ndarray) \\\n" ], "name": "stderr" }, { "output_type": "stream", "text": [ "[13:10:57] WARNING: /workspace/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n", "Done. Time taken : 0:41:17.495814\n", "\n", "Done \n", "\n", "Evaluating the model with TRAIN data...\n", "Evaluating Test data\n", "\n", "TEST DATA\n", "------------------------------\n", "RMSE : 1.0743350336895106\n", "MAPE : 34.68804607716922\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "0j1wguEOQLA5", "colab_type": "code", "outputId": "54af9f69-cf5d-4f99-d5ee-3072176e6269", "colab": { "base_uri": "https://localhost:8080/", "height": 295 } }, "source": [ "xgb.plot_importance(xgb_bsl.best_estimator_)\n", "plt.show()\n" ], "execution_count": 0, "outputs": [ { "output_type": "display_data", "data": { "image/png": "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\nYII=\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "Y_Uvkqq9dTuD", "colab": {} }, "source": [ "" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "5bE97Eqpb_vA" }, "source": [ "### 5.3 Tuning XGBoost with initial 13 features + Surprise Baseline predictor + KNNBaseline predictor" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "yOaogYbRcHtW", "colab": {} }, "source": [ "from surprise import KNNBaseline" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "un30QyKncHtb" }, "source": [ "- KNN BASELINE\n", " - http://surprise.readthedocs.io/en/stable/knn_inspired.html#surprise.prediction_algorithms.knns.KNNBaseline " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "VXUki-DZcHtd" }, "source": [ "- PEARSON_BASELINE SIMILARITY\n", " - http://surprise.readthedocs.io/en/stable/similarities.html#surprise.similarities.pearson_baseline " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Cb2tlnR_cHte" }, "source": [ "- SHRINKAGE\n", " - _2.2 Neighborhood Models_ in http://courses.ischool.berkeley.edu/i290-dm/s11/SECURE/a1-koren.pdf " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "BuIMn6H4cHtf" }, "source": [ "- __predicted Rating__ : ( ___ based on User-User similarity ___ )\n", "\n", "\\begin{align} \\hat{r}_{ui} = b_{ui} + \\frac{ \\sum\\limits_{v \\in N^k_i(u)}\n", "\\text{sim}(u, v) \\cdot (r_{vi} - b_{vi})} {\\sum\\limits_{v \\in\n", "N^k_i(u)} \\text{sim}(u, v)} \\end{align}\n", "\n", "- $\\pmb{b_{ui}}$ - _Baseline prediction_ of (user,movie) rating\n", "\n", "- $ \\pmb {N_i^k (u)}$ - Set of __K similar__ users (neighbours) of __user (u)__ who rated __movie(i)__ \n", "\n", "- _sim (u, v)_ - __Similarity__ between users __u and v__ \n", " - Generally, it will be cosine similarity or Pearson correlation coefficient. \n", " - But we use __shrunk Pearson-baseline correlation coefficient__, which is based on the pearsonBaseline similarity ( we take base line predictions instead of mean rating of user/item)\n", " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "84Z2TlR5cHtg" }, "source": [ " " ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "U8EjcEr_cHti" }, "source": [ "- __ Predicted rating __ ( based on Item Item similarity ):\n", " \\begin{align} \\hat{r}_{ui} = b_{ui} + \\frac{ \\sum\\limits_{j \\in N^k_u(i)}\\text{sim}(i, j) \\cdot (r_{uj} - b_{uj})} {\\sum\\limits_{j \\in N^k_u(j)} \\text{sim}(i, j)} \\end{align}\n", "\n", " - ___Notations follows same as above (user user based predicted rating ) ___" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "csAgHpeKb_vI" }, "source": [ "- Surprise KNNBaseline with user user similarities" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "luqHC5rHd8l_" }, "source": [ "

4.4.4.1 Surprise KNNBaseline with user user similarities

" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "65d7d76b-6f70-428f-bfc1-0ef485221242", "id": "0iK9J9k9b_vJ", "colab": { "base_uri": "https://localhost:8080/", "height": 527 } }, "source": [ "# we specify , how to compute similarities and what to consider with sim_options to our algorithm\n", "sim_options = {'user_based' : True,\n", " 'name': 'pearson_baseline',\n", " 'shrinkage': 100,\n", " 'min_support': 2\n", " } \n", "# we keep other parameters like regularization parameter and learning_rate as default values.\n", "bsl_options = {'method': 'sgd'} \n", "\n", "knn_bsl_u = KNNBaseline(k=40, sim_options = sim_options, bsl_options = bsl_options)\n", "knn_bsl_u_train_results, knn_bsl_u_test_results = run_surprise(knn_bsl_u, trainset, testset, verbose=True)\n" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", "Estimating biases using sgd...\n", "Computing the pearson_baseline similarity matrix...\n", "Done computing similarity matrix.\n", "Done. time taken : 0:03:13.078602 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:09:40.598949\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.3278050914466148\n", "\n", "MAPE : 9.027978982373568\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.088058\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.072409004806261\n", "\n", "MAPE : 34.936622813459635\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:12:53.767892\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "bVd-S6qMb_vR", "colab": {} }, "source": [ "# Just store these error metrics in our models_evaluation datastructure\n", "tuned_models_evaluation_train['knn_bsl_u'] = knn_bsl_u_train_results \n", "tuned_models_evaluation_test['knn_bsl_u'] = knn_bsl_u_test_results" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "NThs5mlBkxBP", "colab_type": "code", "colab": {} }, "source": [ "import pickle\n", "with open(\"/content/drive/My Drive/Netflix_recommender/tuned_result.pkl\",\"wb\") as f:\n", " pickle.dump(tuned_models_evaluation_train,f)\n", " pickle.dump(tuned_models_evaluation_test,f)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "dFzjHYVKnuTx", "colab_type": "code", "colab": {} }, "source": [ "import pickle\n", "with open(\"/content/drive/My Drive/Netflix_recommender/tuned_result.pkl\",\"rb\") as f:\n", " tuned_models_evaluation_train = pickle.load(f)\n", " tuned_models_evaluation_test = pickle.load(f)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "DxGX2xkwb_vU" }, "source": [ "- Surprise KNNBaseline with movie movie similarities" ] }, { "cell_type": "code", "metadata": { "scrolled": true, "colab_type": "code", "outputId": "1c73debb-b00b-4c4c-80ca-0ef277ee9c0f", "id": "HV3JUUfFb_vW", "colab": { "base_uri": "https://localhost:8080/", "height": 527 } }, "source": [ "# we specify , how to compute similarities and what to consider with sim_options to our algorithm\n", "\n", "# 'user_based' : Fals => this considers the similarities of movies instead of users\n", "\n", "sim_options = {'user_based' : False,\n", " 'name': 'pearson_baseline',\n", " 'shrinkage': 100,\n", " 'min_support': 2\n", " } \n", "# we keep other parameters like regularization parameter and learning_rate as default values.\n", "bsl_options = {'method': 'sgd'}\n", "\n", "\n", "knn_bsl_m = KNNBaseline(k=40, sim_options = sim_options, bsl_options = bsl_options)\n", "\n", "knn_bsl_m_train_results, knn_bsl_m_test_results = run_surprise(knn_bsl_m, trainset, testset, verbose=True)" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", "Estimating biases using sgd...\n", "Computing the pearson_baseline similarity matrix...\n", "Done computing similarity matrix.\n", "Done. time taken : 0:00:02.171294 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:00:19.100806\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.32316657950987937\n", "\n", "MAPE : 8.404159172327828\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.076235\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.0723215145319687\n", "\n", "MAPE : 34.92807707883072\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:00:21.350482\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "M6a-Lh2Nb_vb", "colab": {} }, "source": [ "# Just store these error metrics in our models_evaluation datastructure\n", "tuned_models_evaluation_train['knn_bsl_m'] = knn_bsl_m_train_results \n", "tuned_models_evaluation_test['knn_bsl_m'] = knn_bsl_m_test_results" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "rJcv7SEZpQWE", "colab": {} }, "source": [ "import pickle\n", "with open(\"/content/drive/My Drive/Netflix_recommender/tuned_result.pkl\",\"wb\") as f:\n", " pickle.dump(tuned_models_evaluation_train,f)\n", " pickle.dump(tuned_models_evaluation_test,f)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "a3l5j5__pQWc", "colab": {} }, "source": [ "import pickle\n", "with open(\"/content/drive/My Drive/Netflix_recommender/tuned_result.pkl\",\"rb\") as f:\n", " tuned_models_evaluation_train = pickle.load(f)\n", " tuned_models_evaluation_test = pickle.load(f)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "xg0Iob7e9ZhR", "colab_type": "code", "outputId": "99208339-ab33-4294-98fa-1814fbeffbb9", "colab": { "base_uri": "https://localhost:8080/", "height": 204 } }, "source": [ "# add the predicted values from both knns to this dataframe\n", "reg_train['knn_bsl_u'] = tuned_models_evaluation_train['knn_bsl_u']['predictions']\n", "reg_train['knn_bsl_m'] = tuned_models_evaluation_train['knn_bsl_m']['predictions']\n", "\n", "reg_train.head(2)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingknn_bsl_uknn_bsl_m
0174683103.5875815.05.03.04.04.03.05.04.03.02.03.8823533.61111154.9967934.977554
1233949103.5875814.04.05.01.03.02.03.02.03.03.02.6923083.61111133.0624533.051725
2555770103.5875814.05.04.04.05.04.02.05.04.04.03.7954553.61111145.0000005.000000
3767518103.5875812.05.04.04.03.05.05.04.04.03.03.8846153.61111154.8340404.875339
4894393103.5875813.05.04.04.03.04.04.04.04.04.04.0000003.61111144.0384463.904309
\n", "
" ], "text/plain": [ " user movie GAvg sur1 ... MAvg rating knn_bsl_u knn_bsl_m\n", "0 174683 10 3.587581 5.0 ... 3.611111 5 4.996793 4.977554\n", "1 233949 10 3.587581 4.0 ... 3.611111 3 3.062453 3.051725\n", "2 555770 10 3.587581 4.0 ... 3.611111 4 5.000000 5.000000\n", "3 767518 10 3.587581 2.0 ... 3.611111 5 4.834040 4.875339\n", "4 894393 10 3.587581 3.0 ... 3.611111 4 4.038446 3.904309\n", "\n", "[5 rows x 18 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 53 } ] }, { "cell_type": "code", "metadata": { "id": "rb70N_yD_Y8a", "colab_type": "code", "outputId": "11e049f0-d05c-4621-db9e-ee4433870f68", "colab": { "base_uri": "https://localhost:8080/", "height": 131 } }, "source": [ "reg_test_df.head(2)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingknn_bsl_uknn_bsl_mbslpr
0808635713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167953.5799493.5799493.579949
1941866713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167943.5799493.5799493.579949
\n", "
" ], "text/plain": [ " user movie GAvg sur1 ... rating knn_bsl_u knn_bsl_m bslpr\n", "0 808635 71 3.581679 3.581679 ... 5 3.579949 3.579949 3.579949\n", "1 941866 71 3.581679 3.581679 ... 4 3.579949 3.579949 3.579949\n", "\n", "[2 rows x 19 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 58 } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "outputId": "c3f81b89-d4eb-41c0-f661-caab80fee53b", "id": "YKNqsLCyb_vm", "colab": { "base_uri": "https://localhost:8080/", "height": 131 } }, "source": [ "reg_test_df['knn_bsl_u'] = tuned_models_evaluation_test['knn_bsl_u']['predictions']\n", "reg_test_df['knn_bsl_m'] = tuned_models_evaluation_test['knn_bsl_m']['predictions']\n", "\n", "reg_test_df.head(2)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingknn_bsl_uknn_bsl_m
0808635713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167953.5799493.579949
1941866713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167943.5799493.579949
\n", "
" ], "text/plain": [ " user movie GAvg sur1 ... MAvg rating knn_bsl_u knn_bsl_m\n", "0 808635 71 3.581679 3.581679 ... 3.581679 5 3.579949 3.579949\n", "1 941866 71 3.581679 3.581679 ... 3.581679 4 3.579949 3.579949\n", "\n", "[2 rows x 18 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 50 } ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "zYeQcgbYb_vr", "colab": {} }, "source": [ "# prepare the train data....\n", "x_train = reg_train.drop(['user', 'movie', 'rating'], axis=1)\n", "y_train = reg_train['rating']\n", "\n", "# prepare the train data....\n", "x_test = reg_test_df.drop(['user','movie','rating'], axis=1)\n", "y_test = reg_test_df['rating']\n", "\n", "# making model ready for tuning\n", "xgb_model = XGBRegressor(silent=False, n_jobs=-1,random_state=15,verbosity=1,nthread=-1)\n", "xgb_knn_bsl_um = GridSearchCV(xgb_model,param_grid,n_jobs=-1,cv = 3,verbose=10,return_train_score=True)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "1CQhUcxDb_vy", "colab": {} }, "source": [ "train_results, test_results = run_xgboost(xgb_knn_bsl_um, x_train, y_train, x_test, y_test)\n", "\n", "# store the results in models_evaluations dictionaries\n", "tuned_models_evaluation_train['xgb_knn_bsl_um'] = train_results\n", "tuned_models_evaluation_test['xgb_knn_bsl_um'] = test_results\n" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "__RFAG1xcsVW", "colab_type": "text" }, "source": [ "Done. Time taken : 0:53:27.148315\n", "\n", "Done " ] }, { "cell_type": "code", "metadata": { "id": "QZFRbyvAAimg", "colab_type": "code", "outputId": "3e472181-a0a1-491c-e7a9-fb969c365c3a", "colab": { "base_uri": "https://localhost:8080/", "height": 102 } }, "source": [ "y_train_pred = xgb_knn_bsl_um.predict(x_train)\n", "# get the rmse and mape of train data...\n", "rmse_train, mape_train = get_error_metrics(y_train.values, y_train_pred)\n", "\n", "# store the results in train_results dictionary..\n", "train_results = {'rmse': rmse_train,\n", " 'mape' : mape_train,\n", " 'predictions' : y_train_pred}\n", "\n", "print('\\nTrain DATA')\n", "print('-'*30)\n", "print('RMSE : ', rmse_train)\n", "print('MAPE : ', mape_train)\n" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "\n", "Train DATA\n", "------------------------------\n", "RMSE : 0.8643350724897788\n", "MAPE : 25.960364353971094\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "lVRJJ1qP-yfR", "colab_type": "code", "outputId": "7f6fac9a-dbcc-4f13-efef-74c883be56b1", "colab": { "base_uri": "https://localhost:8080/", "height": 119 } }, "source": [ "print('Evaluating Test data')\n", "y_test_pred = xgb_knn_bsl_um.predict(x_test) \n", "rmse_test, mape_test = get_error_metrics(y_true=y_test.values, y_pred=y_test_pred)\n", "# store them in our test results dictionary.\n", "test_results = {'rmse': rmse_test,\n", " 'mape' : mape_test,\n", " 'predictions':y_test_pred}\n", "if verbose:\n", " print('\\nTEST DATA')\n", " print('-'*30)\n", " print('RMSE : ', rmse_test)\n", " print('MAPE : ', mape_test)\n", " " ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Evaluating Test data\n", "\n", "TEST DATA\n", "------------------------------\n", "RMSE : 1.0743360765716838\n", "MAPE : 34.68765743120491\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "A3pSxpN5A-mE", "colab_type": "code", "colab": {} }, "source": [ "tuned_models_evaluation_train['xgb_knn_bsl_um'] = train_results\n", "tuned_models_evaluation_test['xgb_knn_bsl_um'] = test_results" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "8CSGo8rBBBrp", "colab_type": "code", "outputId": "27f63d75-347a-4d09-9e56-07ce29561c8b", "colab": { "base_uri": "https://localhost:8080/", "height": 312 } }, "source": [ "xgb.plot_importance(xgb_knn_bsl_um.best_estimator_)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 67 }, { "output_type": "display_data", "data": { "image/png": "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\nLiRAN5EAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "id": "6LbHreqRBY9Y", "colab_type": "code", "colab": {} }, "source": [ "from surprise import SVD" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "YMhWPtuGoHW9", "colab_type": "text" }, "source": [ "### 5.4 XgBoost with Surprise Baseline + Surprise KNNbaseline + MF Techniques" ] }, { "cell_type": "markdown", "metadata": { "id": "VV8FEgQYoHW-", "colab_type": "text" }, "source": [ "- svd" ] }, { "cell_type": "code", "metadata": { "id": "miEei8sooHW_", "colab_type": "code", "outputId": "23b0c05c-7105-4755-a872-03be002bd67d", "colab": { "base_uri": "https://localhost:8080/", "height": 816 } }, "source": [ "# initiallize the model\n", "svd = SVD(n_factors=100, biased=True, random_state=15, verbose=True)\n", "svd_train_results, svd_test_results = run_surprise(svd, trainset, testset, verbose=True)\n", "\n", "# Just store these error metrics in our models_evaluation datastructure\n", "tuned_models_evaluation_train['svd'] = svd_train_results \n", "tuned_models_evaluation_test['svd'] = svd_test_results" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", "Processing epoch 0\n", "Processing epoch 1\n", "Processing epoch 2\n", "Processing epoch 3\n", "Processing epoch 4\n", "Processing epoch 5\n", "Processing epoch 6\n", "Processing epoch 7\n", "Processing epoch 8\n", "Processing epoch 9\n", "Processing epoch 10\n", "Processing epoch 11\n", "Processing epoch 12\n", "Processing epoch 13\n", "Processing epoch 14\n", "Processing epoch 15\n", "Processing epoch 16\n", "Processing epoch 17\n", "Processing epoch 18\n", "Processing epoch 19\n", "Done. time taken : 0:00:17.447190 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:00:03.140872\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.6616921280231969\n", "\n", "MAPE : 20.092740147412886\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.068572\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.0724398179398351\n", "\n", "MAPE : 34.91362328393122\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:00:20.659189\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "YCkvVS3KoHXC", "colab_type": "text" }, "source": [ "- svd++" ] }, { "cell_type": "code", "metadata": { "id": "rYTfxOeFCs94", "colab_type": "code", "colab": {} }, "source": [ "from surprise import SVDpp" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "0R-1RuPDoHXD", "colab_type": "code", "outputId": "23b9cb4c-b1ac-41a5-a0ea-c902a96e472d", "colab": { "base_uri": "https://localhost:8080/", "height": 816 } }, "source": [ "# initiallize the model\n", "svdpp = SVDpp(n_factors=50, random_state=15, verbose=True)\n", "svdpp_train_results, svdpp_test_results = run_surprise(svdpp, trainset, testset, verbose=True)\n", "\n", "# Just store these error metrics in our models_evaluation datastructure\n", "tuned_models_evaluation_train['svdpp'] = svdpp_train_results \n", "tuned_models_evaluation_test['svdpp'] = svdpp_test_results\n" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model...\n", " processing epoch 0\n", " processing epoch 1\n", " processing epoch 2\n", " processing epoch 3\n", " processing epoch 4\n", " processing epoch 5\n", " processing epoch 6\n", " processing epoch 7\n", " processing epoch 8\n", " processing epoch 9\n", " processing epoch 10\n", " processing epoch 11\n", " processing epoch 12\n", " processing epoch 13\n", " processing epoch 14\n", " processing epoch 15\n", " processing epoch 16\n", " processing epoch 17\n", " processing epoch 18\n", " processing epoch 19\n", "Done. time taken : 0:04:21.207708 \n", "\n", "Evaluating the model with train data..\n", "time taken : 0:00:15.423787\n", "---------------\n", "Train Data\n", "---------------\n", "RMSE : 0.6111215770571189\n", "\n", "MAPE : 17.916043542679418\n", "\n", "adding train results in the dictionary..\n", "\n", "Evaluating for test data...\n", "time taken : 0:00:00.322898\n", "---------------\n", "Test Data\n", "---------------\n", "RMSE : 1.073107287201817\n", "\n", "MAPE : 34.90611294334286\n", "\n", "storing the test results in test dictionary...\n", "\n", "---------------------------------------------\n", "Total time taken to run this algorithm : 0:04:36.957996\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "kRiyaXaWoHXF", "colab_type": "code", "outputId": "e7a3db36-038d-4310-dec5-a14aa478151c", "colab": { "base_uri": "https://localhost:8080/", "height": 131 } }, "source": [ "# add the predicted values from both knns to this dataframe\n", "reg_train['svd'] =tuned_models_evaluation_train['svd']['predictions']\n", "reg_train['svdpp'] = tuned_models_evaluation_train['svdpp']['predictions']\n", "\n", "reg_train.head(2) " ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingknn_bsl_uknn_bsl_mbslprsvdsvdpp
0174683103.5875815.05.03.04.04.03.05.04.03.02.03.8823533.61111154.9967934.9775543.6728484.2207623.997242
1233949103.5875814.04.05.01.03.02.03.02.03.03.02.6923083.61111133.0624533.0517253.6889173.7449453.671130
\n", "
" ], "text/plain": [ " user movie GAvg sur1 ... knn_bsl_m bslpr svd svdpp\n", "0 174683 10 3.587581 5.0 ... 4.977554 3.672848 4.220762 3.997242\n", "1 233949 10 3.587581 4.0 ... 3.051725 3.688917 3.744945 3.671130\n", "\n", "[2 rows x 21 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 74 } ] }, { "cell_type": "code", "metadata": { "id": "I32shRohD7gu", "colab_type": "code", "outputId": "7fd54f94-eab6-4ea6-de49-1f88299bede8", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "reg_train.shape" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(281949, 21)" ] }, "metadata": { "tags": [] }, "execution_count": 75 } ] }, { "cell_type": "code", "metadata": { "id": "IhucL0gUoHX6", "colab_type": "code", "outputId": "80dd73af-5640-4538-a746-d189970fcbe3", "colab": { "base_uri": "https://localhost:8080/", "height": 131 } }, "source": [ "reg_test_df['svd'] = tuned_models_evaluation_test['svd']['predictions']\n", "reg_test_df['svdpp'] = tuned_models_evaluation_test['svdpp']['predictions']\n", "\n", "reg_test_df.head(2) " ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
usermovieGAvgsur1sur2sur3sur4sur5smr1smr2smr3smr4smr5UAvgMAvgratingknn_bsl_uknn_bsl_mbslprsvdsvdpp
0808635713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167953.5799493.5799493.5799493.5799493.579949
1941866713.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.5816793.58167943.5799493.5799493.5799493.5799493.579949
\n", "
" ], "text/plain": [ " user movie GAvg sur1 ... knn_bsl_m bslpr svd svdpp\n", "0 808635 71 3.581679 3.581679 ... 3.579949 3.579949 3.579949 3.579949\n", "1 941866 71 3.581679 3.581679 ... 3.579949 3.579949 3.579949 3.579949\n", "\n", "[2 rows x 21 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 76 } ] }, { "cell_type": "code", "metadata": { "id": "0cNHOz-ioHX_", "colab_type": "code", "colab": {} }, "source": [ "# prepare x_train and y_train\n", "x_train = reg_train.drop(['user', 'movie', 'rating',], axis=1)\n", "y_train = reg_train['rating']\n", "\n", "# prepare test data\n", "x_test = reg_test_df.drop(['user', 'movie', 'rating'], axis=1)\n", "y_test = reg_test_df['rating']\n", "\n", "# making model ready for tuning\n", "xgb_model = XGBRegressor(silent=False, n_jobs=-1,random_state=15,verbosity=1,nthread=-1)\n", "xgb_final = GridSearchCV(xgb_model,param_grid,n_jobs=-1,cv = 3,verbose=10,return_train_score=True)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "XbIxKBNroHYB", "colab_type": "code", "outputId": "5efd228a-962f-4e90-c804-a8c3a66d5cc1", "colab": { "base_uri": "https://localhost:8080/", "height": 666 } }, "source": [ "train_results, test_results = run_xgboost(xgb_final, x_train, y_train, x_test, y_test)\n", "\n", "# store the results in models_evaluations dictionaries\n", "tuned_models_evaluation_train['xgb_final'] = train_results\n", "tuned_models_evaluation_test['xgb_final'] = test_results" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model..\n", "Fitting 3 folds for each of 64 candidates, totalling 192 fits\n" ], "name": "stdout" }, { "output_type": "stream", "text": [ "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n", "[Parallel(n_jobs=-1)]: Done 5 tasks | elapsed: 1.2min\n", "[Parallel(n_jobs=-1)]: Done 10 tasks | elapsed: 2.4min\n", "/usr/local/lib/python3.6/dist-packages/joblib/externals/loky/process_executor.py:706: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.\n", " \"timeout or by a memory leak.\", UserWarning\n", "[Parallel(n_jobs=-1)]: Done 17 tasks | elapsed: 3.9min\n", "[Parallel(n_jobs=-1)]: Done 24 tasks | elapsed: 6.2min\n", "[Parallel(n_jobs=-1)]: Done 33 tasks | elapsed: 9.1min\n", "[Parallel(n_jobs=-1)]: Done 42 tasks | elapsed: 12.3min\n", "[Parallel(n_jobs=-1)]: Done 53 tasks | elapsed: 16.3min\n", "[Parallel(n_jobs=-1)]: Done 64 tasks | elapsed: 19.0min\n", "[Parallel(n_jobs=-1)]: Done 77 tasks | elapsed: 22.7min\n", "[Parallel(n_jobs=-1)]: Done 90 tasks | elapsed: 27.5min\n", "[Parallel(n_jobs=-1)]: Done 105 tasks | elapsed: 32.4min\n", "[Parallel(n_jobs=-1)]: Done 120 tasks | elapsed: 36.7min\n", "[Parallel(n_jobs=-1)]: Done 137 tasks | elapsed: 43.3min\n", "[Parallel(n_jobs=-1)]: Done 154 tasks | elapsed: 48.8min\n", "[Parallel(n_jobs=-1)]: Done 173 tasks | elapsed: 54.2min\n", "[Parallel(n_jobs=-1)]: Done 192 out of 192 | elapsed: 63.0min finished\n", "/usr/local/lib/python3.6/dist-packages/xgboost/core.py:587: FutureWarning: Series.base is deprecated and will be removed in a future version\n", " if getattr(data, 'base', None) is not None and \\\n", "/usr/local/lib/python3.6/dist-packages/xgboost/core.py:588: FutureWarning: Series.base is deprecated and will be removed in a future version\n", " data.base is not None and isinstance(data, np.ndarray) \\\n" ], "name": "stderr" }, { "output_type": "stream", "text": [ "[17:21:21] WARNING: /workspace/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n", "Done. Time taken : 1:03:19.336545\n", "\n", "Done \n", "\n", "Evaluating the model with TRAIN data...\n", "Evaluating Test data\n", "\n", "TEST DATA\n", "------------------------------\n", "RMSE : 1.0761202825525833\n", "MAPE : 34.48325107967784\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "OPC3szFJTmhn", "colab_type": "code", "outputId": "b9ff3642-0ed6-44b8-b642-e95059f36462", "colab": { "base_uri": "https://localhost:8080/", "height": 318 } }, "source": [ "xgb.plot_importance(xgb_final.best_estimator_)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 82 }, { "output_type": "display_data", "data": { "image/png": "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\n+yv7v//++/Ts2dNgN6iq6ebYoqh9fCBjNDZGlS3p7OzM4cOHSU9P11v/cIhxbm5uibaVhr29PTt3\n7sTW1paQkBC9WKfH0Wg0aLVaZblgyLIo+pPi43IlX3zxRS5cuMCePXvIzMxkzZo12NjYKI0tPj6e\n1NRUsrKyCAkJ4ciRI7zxxhuVOi4hhHExWHObPHkyPXr0YNy4caSmplbI78jOziYsLAyAmJgYMjIy\naN26NVevXsXS0pKBAwfi5+fHuXPn9BrWo7Ro0YKzZ88CefdmFQxSFo+2bt067Ozs2LBhA6GhodjZ\n2bFu3ToaNmyIv78/q1atolu3bpw5c0Yvs/Pw4cN4eHjg5OTEtm3b2LRpU6Hv6IQQoiCDTiiZOHEi\nNWvWZOzYsWzatKncj9+gQQNiY2OVY69cuRILCwuOHTtGQEAApqamaLVa5s+fX+Jk/2nTpuHr68vW\nrVvp3r07TZs2Lfe61WrKlClMmTKlyG09evRg9+7dRW4bO3YsY8eOrcDKhBBqI8HJlUiCk9VB7WNU\n+/hAxmhsJDhZCCGEQAXPc5s7dy6nT5/WW6fRaAgKCirzMQ8ePFjkc9pmzJhB3759y3xctYuPj+fT\nTz/lypUrNGzYkA8//JAXX3xR7zWrV6/G39+fb7/9lh49ehioUiGE2hl9c1uwYEG5HGf06NG8+eab\nuLq60rdvX2lipZSTk8O7775Lz549+emnn5TIrJ07d9KqVSsArly5wp49e2jcuLGBqxVCqJ1clhTl\n4u+//+bmzZsMGDAAjUaDi4sLDg4OhISEKK+ZP38+H3zwARYWFgasVAhRHRj9mVu+9PR0Zs2axcWL\nFzEzM6NVq1akpKTw2muv4eHhAcD+/fv55ptv2LJlCxcvXsTPz48HDx7Qrl07vfvVRo8eTfv27fnj\njz9ISUnBy8uLGTNmPHab0FcwA/Lnn3/GwsJCzoiFEJVCNc3tyJEjpKWlERERAeRFah04cIDg4GCl\nuQUFBSmPW/nwww8ZPXo0Pj4+nDp1ihEjRugdLz4+nm3btpGZmcnw4cOxt7fH1dX1sduqo6zsXFq1\nakXDhg0JDw+nc+fOREdHc/z4cZydnUlNTWXVqlV88803hi5VCFFNqKa5tW/fnvj4eObPn4+TkxMv\nvPACnp6efP7559y9exeAY8eOsWTJElJTU4mLi2PIkCEAdOnSpVDw8dChQzEzM8PMzIwBAwYQFRWl\n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\nFFwAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "id": "KdGfYz1oEq3q", "colab_type": "code", "colab": {} }, "source": [ "import pickle\n", "with open(\"/content/drive/My Drive/Netflix_recommender/tuned_result.pkl\",\"wb\") as f:\n", " pickle.dump(tuned_models_evaluation_train,f)\n", " pickle.dump(tuned_models_evaluation_test,f)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "QcWi12vOoHYR", "colab_type": "text" }, "source": [ "### 5.5 XgBoost with Surprise Baseline + Surprise KNNbaseline + MF Techniques" ] }, { "cell_type": "code", "metadata": { "id": "qG75DLAVoHYS", "colab_type": "code", "colab": {} }, "source": [ "# prepare train data\n", "x_train = reg_train[['knn_bsl_u', 'knn_bsl_m', 'svd', 'svdpp']]\n", "y_train = reg_train['rating']\n", "\n", "# test data\n", "x_test = reg_test_df[['knn_bsl_u', 'knn_bsl_m', 'svd', 'svdpp']]\n", "y_test = reg_test_df['rating']\n", "\n", "\n", "# making model ready for tuning\n", "xgb_model = XGBRegressor(silent=False, n_jobs=-1,random_state=15,verbosity=1,nthread=-1)\n", "xgb_all_models = GridSearchCV(xgb_model,param_grid,n_jobs=-1,cv = 3,verbose=10,return_train_score=True)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "fw2SbfQcoHYU", "colab_type": "code", "outputId": "d1a2aced-eb8c-4f00-c992-afc8925fc2ba", "colab": { "base_uri": "https://localhost:8080/", "height": 612 } }, "source": [ "train_results, test_results = run_xgboost(xgb_all_models, x_train, y_train, x_test, y_test)\n", "\n", "# store the results in models_evaluations dictionaries\n", "tuned_models_evaluation_train['xgb_all_models'] = train_results\n", "tuned_models_evaluation_test['xgb_all_models'] = test_results" ], "execution_count": 0, "outputs": [ { "output_type": "stream", "text": [ "Training the model..\n", "Fitting 3 folds for each of 64 candidates, totalling 192 fits\n" ], "name": "stdout" }, { "output_type": "stream", "text": [ "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.\n", "[Parallel(n_jobs=-1)]: Done 5 tasks | elapsed: 34.3s\n", "[Parallel(n_jobs=-1)]: Done 10 tasks | elapsed: 1.1min\n", "[Parallel(n_jobs=-1)]: Done 17 tasks | elapsed: 1.8min\n", "[Parallel(n_jobs=-1)]: Done 24 tasks | elapsed: 2.6min\n", "[Parallel(n_jobs=-1)]: Done 33 tasks | elapsed: 3.8min\n", "[Parallel(n_jobs=-1)]: Done 42 tasks | elapsed: 4.9min\n", "[Parallel(n_jobs=-1)]: Done 53 tasks | elapsed: 6.3min\n", "[Parallel(n_jobs=-1)]: Done 64 tasks | elapsed: 7.6min\n", "[Parallel(n_jobs=-1)]: Done 77 tasks | elapsed: 9.4min\n", "[Parallel(n_jobs=-1)]: Done 90 tasks | elapsed: 11.7min\n", "[Parallel(n_jobs=-1)]: Done 105 tasks | elapsed: 13.9min\n", "[Parallel(n_jobs=-1)]: Done 120 tasks | elapsed: 16.2min\n", "[Parallel(n_jobs=-1)]: Done 137 tasks | elapsed: 19.6min\n", "[Parallel(n_jobs=-1)]: Done 154 tasks | elapsed: 22.3min\n", "[Parallel(n_jobs=-1)]: Done 173 tasks | elapsed: 25.2min\n", "[Parallel(n_jobs=-1)]: Done 192 out of 192 | elapsed: 29.6min finished\n", "/usr/local/lib/python3.6/dist-packages/xgboost/core.py:587: FutureWarning: Series.base is deprecated and will be removed in a future version\n", " if getattr(data, 'base', None) is not None and \\\n", "/usr/local/lib/python3.6/dist-packages/xgboost/core.py:588: FutureWarning: Series.base is deprecated and will be removed in a future version\n", " data.base is not None and isinstance(data, np.ndarray) \\\n" ], "name": "stderr" }, { "output_type": "stream", "text": [ "[17:59:13] WARNING: /workspace/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n", "Done. Time taken : 0:29:43.030055\n", "\n", "Done \n", "\n", "Evaluating the model with TRAIN data...\n", "Evaluating Test data\n", "\n", "TEST DATA\n", "------------------------------\n", "RMSE : 1.0750524068075662\n", "MAPE : 35.18174702798547\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "pR39eiA5ZB2H", "colab_type": "code", "outputId": "c898fb6f-1f00-4fc5-923c-e5a4f55be8f6", "colab": { "base_uri": "https://localhost:8080/", "height": 318 } }, "source": [ "xgb.plot_importance(xgb_all_models.best_estimator_)" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 85 }, { "output_type": "display_data", "data": { "image/png": "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\nSc7/A4BhG5+WDBYkAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "code", "metadata": { "id": "e2XratD1aD90", "colab_type": "code", "colab": {} }, "source": [ "import pickle\n", "with open(\"/content/drive/My Drive/Netflix_recommender/tuned_result.pkl\",\"wb\") as f:\n", " pickle.dump(tuned_models_evaluation_train,f)\n", " pickle.dump(tuned_models_evaluation_test,f)" ], "execution_count": 0, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "XRtfh-xaadIv", "colab_type": "code", "outputId": "33841ee6-b88d-42cd-9120-f7ebd5136f75", "colab": { "base_uri": "https://localhost:8080/", "height": 170 } }, "source": [ "# Saving our TEST_RESULTS into a dataframe so that you don't have to run it again\n", "pd.DataFrame(tuned_models_evaluation_test).to_csv('drive/My Drive/Netflix_recommender/tuned_small_sample_results.csv')\n", "models = pd.read_csv('drive/My Drive/Netflix_recommender/tuned_small_sample_results.csv', index_col=0)\n", "models.loc['rmse'].sort_values()" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "knn_bsl_m 1.0723215145319687\n", "knn_bsl_u 1.072409004806261\n", "svd 1.0724398179398351\n", "svdpp 1.073107287201817\n", "bsl_algo 1.0731636807255809\n", "xgb_knn_bsl_um 1.0743360765716838\n", "xgb_all_models 1.0750524068075662\n", "xgb_final 1.0761202825525833\n", "Name: rmse, dtype: object" ] }, "metadata": { "tags": [] }, "execution_count": 87 } ] }, { "cell_type": "code", "metadata": { "id": "llx_FBU4ec6N", "colab_type": "code", "outputId": "5837ac3e-cb3f-4285-e838-658fbd75047d", "colab": { "base_uri": "https://localhost:8080/", "height": 111 } }, "source": [ "df_25k_train = pd.DataFrame(data=tuned_models_evaluation_train)\n", "df_25k_train.drop(\"predictions\",inplace = True)\n", "df_25k_train" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
knn_bsl_uknn_bsl_mbsl_algoxgb_knn_bsl_umsvdsvdppxgb_finalxgb_all_models
mape9.027988.4041630.353225.960420.092717.91625.954235.9301
rmse0.3278050.3231670.9552560.8643350.6616920.6111220.8642081.08742
\n", "
" ], "text/plain": [ " knn_bsl_u knn_bsl_m bsl_algo ... svdpp xgb_final xgb_all_models\n", "mape 9.02798 8.40416 30.3532 ... 17.916 25.9542 35.9301\n", "rmse 0.327805 0.323167 0.955256 ... 0.611122 0.864208 1.08742\n", "\n", "[2 rows x 8 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 89 } ] }, { "cell_type": "code", "metadata": { "id": "P_E_v-42eqFr", "colab_type": "code", "outputId": "9ff87c72-3a59-48ff-926a-a04a1e279c01", "colab": { "base_uri": "https://localhost:8080/", "height": 111 } }, "source": [ "df_25k_test = pd.DataFrame(data=tuned_models_evaluation_test)\n", "df_25k_test.drop(\"predictions\",inplace = True)\n", "df_25k_test" ], "execution_count": 0, "outputs": [ { "output_type": "execute_result", "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
knn_bsl_uknn_bsl_mbsl_algoxgb_knn_bsl_umsvdsvdppxgb_finalxgb_all_models
mape34.936634.928134.989134.687734.913634.906134.483335.1817
rmse1.072411.072321.073161.074341.072441.073111.076121.07505
\n", "
" ], "text/plain": [ " knn_bsl_u knn_bsl_m bsl_algo ... svdpp xgb_final xgb_all_models\n", "mape 34.9366 34.9281 34.9891 ... 34.9061 34.4833 35.1817\n", "rmse 1.07241 1.07232 1.07316 ... 1.07311 1.07612 1.07505\n", "\n", "[2 rows x 8 columns]" ] }, "metadata": { "tags": [] }, "execution_count": 90 } ] }, { "cell_type": "markdown", "metadata": { "id": "vheIp8ZURGmi", "colab_type": "text" }, "source": [ " ## **Note:**\n", " ### All the results are computed on 25k data points" ] }, { "cell_type": "markdown", "metadata": { "id": "tRMeajT3QkzY", "colab_type": "text" }, "source": [ "## Observations\n", "\n", "1. We have got slight better scores as compared to scores on 10k data.\n", "2. Compute time has increased drasticaly as we have increased points.\n", "3. We have plot feature_importance for each models that helps in understanding features.\n", "4. **knn_bsl_u and knn_bsl_m** have got slightly better scores as compared to other models.\n", "5. Surprise library features yeild similar as compared with other Self computed features." ] } ] }