{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Importing the libraries\n", "import numpy as np\n", "import pandas as pd\n", "import torch\n", "import torch.nn.parallel\n", "import torch.utils.data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Importing the dataset\n", "movies = pd.read_csv('ml-1m/movies.dat', sep = '::', header = None, engine = 'python', encoding = 'latin-1')\n", "users = pd.read_csv('ml-1m/users.dat', sep = '::', header = None, engine = 'python', encoding = 'latin-1')\n", "ratings = pd.read_csv('ml-1m/ratings.dat', sep = '::', header = None, engine = 'python', encoding = 'latin-1')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Preparing the training set and the test set\n", "training_set = pd.read_csv('ml-100k/u1.base', delimiter = '\\t')\n", "training_set = np.array(training_set, dtype = 'int')\n", "test_set = pd.read_csv('ml-100k/u1.test', delimiter = '\\t')\n", "test_set = np.array(test_set, dtype = 'int')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Getting the number of users and movies\n", "nb_users = int(max(max(training_set[:,0]), max(test_set[:,0])))\n", "nb_movies = int(max(max(training_set[:,1]), max(test_set[:,1])))\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Converting the data into an array with users in lines and movies in columns\n", "def convert(data):\n", " new_data = []\n", " for id_users in range(1, nb_users + 1):\n", " id_movies = data[:,1][data[:,0] == id_users]\n", " id_ratings = data[:,2][data[:,0] == id_users]\n", " ratings = np.zeros(nb_movies)\n", " ratings[id_movies - 1] = id_ratings\n", " new_data.append(list(ratings))\n", " return new_data\n", "training_set = convert(training_set)\n", "test_set = convert(test_set)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Converting the data into Torch tensors\n", "training_set = torch.FloatTensor(training_set)\n", "test_set = torch.FloatTensor(test_set)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Converting the ratings into binary ratings 1 (Liked) or 0 (Not Liked)\n", "training_set[training_set == 0] = -1\n", "training_set[training_set == 1] = 0\n", "training_set[training_set == 2] = 0\n", "training_set[training_set >= 3] = 1\n", "test_set[test_set == 0] = -1\n", "test_set[test_set == 1] = 0\n", "test_set[test_set == 2] = 0\n", "test_set[test_set >= 3] = 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Creating the architecture of the Neural Network\n", "class RBM():\n", " def __init__(self, nv, nh):\n", " self.W = torch.randn(nh, nv)\n", " self.a = torch.randn(1, nh)\n", " self.b = torch.randn(1, nv)\n", " def sample_h(self, x):\n", " wx = torch.mm(x, self.W.t())\n", " activation = wx + self.a.expand_as(wx)\n", " p_h_given_v = torch.sigmoid(activation)\n", " return p_h_given_v, torch.bernoulli(p_h_given_v)\n", " def sample_v(self, y):\n", " wy = torch.mm(y, self.W)\n", " activation = wy + self.b.expand_as(wy)\n", " p_v_given_h = torch.sigmoid(activation)\n", " return p_v_given_h, torch.bernoulli(p_v_given_h)\n", " def train(self, v0, vk, ph0, phk):\n", " # self.W += torch.mm(v0.t(), ph0) - torch.mm(vk.t(), phk)\n", " self.W += torch.mm(ph0, v0) - torch.mm(phk, vk)\n", " self.b += torch.sum((v0 - vk), 0)\n", " self.a += torch.sum((ph0 - phk), 0)\n", "nv = len(training_set[0])\n", "nh = 100\n", "batch_size = 100\n", "rbm = RBM(nv, nh)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Training the RBM\n", "nb_epoch = 10\n", "for epoch in range(1, nb_epoch + 1):\n", " train_loss = 0\n", " s = 0.\n", " for id_user in range(0, nb_users - batch_size, batch_size):\n", " vk = training_set[id_user:id_user+batch_size]\n", " v0 = training_set[id_user:id_user+batch_size]\n", " ph0,_ = rbm.sample_h(v0)\n", " for k in range(10):\n", " _,hk = rbm.sample_h(vk)\n", " _,vk = rbm.sample_v(hk)\n", " vk[v0<0] = v0[v0<0]\n", " phk,_ = rbm.sample_h(vk)\n", " rbm.train(v0, vk, ph0, phk)\n", " train_loss += torch.mean(torch.abs(v0[v0>=0] - vk[v0>=0]))\n", " s += 1.\n", " print('epoch: '+str(epoch)+' loss: '+str(train_loss/s))\n", " \n", "rbm.W += torch.mm(ph0, v0) - torch.mm(phk, vk)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Testing the RBM\n", "test_loss = 0\n", "s = 0.\n", "for id_user in range(nb_users):\n", " v = training_set[id_user:id_user+1]\n", " vt = test_set[id_user:id_user+1]\n", " if len(vt[vt>=0]) > 0:\n", " _,h = rbm.sample_h(v)\n", " _,v = rbm.sample_v(h)\n", " test_loss += torch.mean(torch.abs(vt[vt>=0] - v[vt>=0]))\n", " s += 1.\n", "print('test loss: '+str(test_loss/s))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "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.10" } }, "nbformat": 4, "nbformat_minor": 4 }