OK so now that you understand how everything works conceptually let's talk about how it will work in
code.
First of all the data itself is going to be very different from what you're used to before.
Whenever we wanted to use an ends we remembered the rule.
All data is the same.
But now it appears that my rule has been broken.
All data is in fact not the same.
Recall that with the recommended systems we want to look at all the data comes in the form of triples
the inputs or the user and movie while the target is the rating.
Clearly a sample of users and movies does not make up an end by D matrix of features
so an end by the matrix of features is what we want but what do we actually have.
Well we can still have n items that's clear.
That's just the number of samples.
But let's look at it this way a list of end users which by the way can contain duplicates will be an
N length array of categorical objects.
Similarly a list of n movies which also may contain duplicates will be another in length array of categorical
objects.
Now you might wonder how can the list of users and movies contain duplicates.
Of course this must be the case the same user may have watched multiple different movies in which case
that user will show up multiple times in the data.
Conversely multiple users will of course rate the same movie in which case that movie will show up multiple
times in the data
as we discussed.
The key operation inspired by NRP is the embedding in A.P. we have an end by Team matrix of word indexes
which we use to index the embedding matrix mapping each word to a feature vector.
We get back in end by t by D.
Array of word vectors.
Similarly both users and movies which since they are categorical will be represented by user indexes
and movie indexes so the users will be an end length array of integers and the movies will also be an
end length array of integers.
After we index an embedding matrix we will get back and by these arrays of feature vectors for both
users and movies.
As a side note unlike LP where we have to do a lot of text processing this is not the case with recommenders
as a quiz question.
I would like you to think about why.
Please take a moment to think about this or pause the video until you think you have the answer.
OK.
So why do we not need all the text pre processing that we do for A.P. with recommenders.
Well we have to think of the natural state of the data data like this is usually stored in a database
in databases.
We don't pass around strings all the time because strings take up lots of space and they're inefficient.
For example checking whether or not one string is the same as another string.
It's not efficient.
On the other hand comparing whether two numbers are equal is efficient.
So in a database when you store a movie you you'll probably have a table just for movies where you give
each movie an integer IDB and then in that table you'll have a column for the movie name.
Its synopsis the director the producer.
It's duration and so forth.
By the way the director and producer will probably also just be integer ideas.
Similarly users will be stored the same way so you'll give users a user I.D. and then along with that
you'll store their name email address and so on therefore in the ratings table you would not say something
like Bob rated star was a 5 although that would be its interpretation.
Instead you'll say user 3 4 5 rates movie 6 7 8 5
okay.
So we've established that there won't be any need to do tax pre processing and we've established that
the first thing we need to do is map each user and movie to a feature vector using in buildings.
Now what.
Well now we can count Nate the user vectors and the movie vectors that make up each batch.
This will give us a matrix of size end by 2D and so now we come back to the situation where we can again
say all data is the same.
Since this is nothing but a two dimensional data matrix we can do anything with it anything that we
would normally do in machine learning on data of the same kind i.e. we can pass this through a neural
network.
So here's what the code might look like for a recommender model in the constructor we take in some arguments
for the total number of users the total number of movies the embedding dimension and the number of hidden
units.
Of course you could make this more fancy and let your model be a neuron that work with multiple hidden
layers but we won't do that.
You may want to try that as an exercise you can think of the total number of users and the total number
of movies like vocabulary sizes for the users and movies.
So if we call the number of users N and the number of movies M and the embedding the mentioned D then
the user embedding will be a matrix of size and by D.
And the movie embedding will be a matrix of size embody by the way don't confuse this n with the end
that we used previously which meant the number of samples in a batch on this slide and within the code.
That's not what we mean.
And the reason for this sort of overloaded use of the letter N is because that's what people normally
use in recommender systems.
So just make sure you're paying attention to the context.
Once we create art to embed things all we need to do is create our own CNN layers which for our simple
model can just be too linear layers.
And by the way since this is a scalar regression problem we'll have one output
okay.
So what does the forward function look like.
Probably exactly what you expect.
Well maybe not since there's one thing you haven't seen before.
Earlier in the course we started by looking at very simple ways to build models modules themselves our
models.
So if I create a linear module I can call that a model or I can take a whole sequence of modules and
wrap that in a sequential and I can call that a model later we talked about custom models.
We saw that with our own ends.
There's a little extra work that we need to do.
That can't be done in a sequential model at least not yet.
So custom models were necessary.
There was another reason I mentioned for why custom models are useful and this is it.
This model is unique in this course because it's the first one we've seen that takes in multiple inputs.
As you can see the arguments into the Ford function are not just a single X like we had before but now
we have to you and Em you and them in this case are both one dimensional arrays containing user I.D.
and corresponding movie ideas a sequential model would not be able to handle an input like this.
So the first thing we do is pass you and them into their respective embedding.
After that both the users and movies will be represented by arrays of size num samples by the.
The next step is to merge or concatenate these two matrices together along Axis 1 to get back in array
of size num samples by 2D finally it's just business as usual to pass this to the end end layers.
Okay.
So the next thing to consider is how will we load in the data the data is going to come in the form
of a C S V or a T S V or something like that.
So we can use pandas to load in this dataset.
We can even just turn it into a num pie array right away since we don't actually need any Panda's functionality.
But here is one thing to consider ratings data sets are usually huge.
You might have millions of data points if your business has millions of users.
This is pretty much guaranteed.
So just like with vision and text you probably want to use some kind of data generator or data iterator
but unlike vision and text there aren't any specialized libraries that will do all these steps for you
luckily there are generic data set objects that we can use that just loop over arrays without any regard
to what's in them.
So here's an example of how to use tensor data set which takes in an arbitrary length sequence of data
tensor.
For us we'll pass in three sensors the users the movies and the ratings
later in order to loop over each data set for training.
We use the data loader object which we've already seen.
The first argument is the data set objects which we just looked at.
The second argument is the backside and the third argument is whether or not to shuffle the data.
And once you have this it's just business as usual defined your training function and inside that function
to iterate over the data loader.