A regression approach to recommendations

An alternative to neighborhoods is to formulate recommendations as a regression problem and apply the methods that we learned in the Chapter 6, Clustering - Finding Related Posts.

We first consider why this problem is not a good fit for a classification formulation. We could certainly attempt to learn a five-class model, using one class for each possible movie rating. However, there are two problems with this approach:

  • The different possible errors are not at all the same. For example, mistaking a 5-star movie for a 4-star one is not as serious a mistake as mistaking a 5-star movie for a 1-star one
  • Intermediate values make sense. Even if our inputs are only integer values, it is perfectly meaningful to say that the prediction is 4.3. We can see that this is a different prediction than 3.5, even if they both round to 4

These two factors together mean that classification is not a good fit for the problem. The regression framework is a better fit.

For a basic approach, we again have two choices: We can build movie-specific or user-specific models. In our case, we are going to first build user-specific models. This means that, for each user, we take the movies that the user has rated as our target variable. The inputs are the ratings of other users. We hypothesize that this will give a high value to users who are similar to our user (or a negative value to users who like the same movies that our user dislikes).

Setting up the train and test matrices is the same method as before (including running the normalization steps). Therefore, we jump directly to the learning step:

  1. First, we instantiate a regression object as follows (recall that, in Chapter 2, Classifying with Real-World Examples, we had reached the conclusion that an elastic net with an automatic parameter search was a good general-purpose regression method):
reg = ElasticNetCV(alphas=[0.0125, 0.025, 0.05, .125, .25, .5, 1., 2., 4.]) 
  1. We then build a data matrix that will contain a rating for every user–movie pair. We initialize it as a copy of the training data:
filled = train.copy() 
  1. Now, we iterate over all the users, and each time learn a regression model based only on the data that that user has given us:
for u in range(train.shape[0]): 
     curtrain = np.delete(train, u, axis=0) 
     # binary records whether this rating is present 
     bu = binary[u] 
     # fit the current user based on everybody else 
     reg.fit(curtrain[:,bu].T, train[u, bu]) 
     # Fill in all the missing ratings 
     filled[u, ~bu] = reg.predict(curtrain[:,~bu].T) 
  1. Evaluating the method can be done exactly as before:
predicted = norm.inverse_transform(filled) 
r2 = metrics.r2_score(test[test > 0], predicted[test > 0]) 
print('R2 score (user regression): {:.1%}'.format(r2)) 
R2 score (user regression): 32.3% 

As before, we can adapt this code to perform movie regression by using the transposed matrix (see the companion code repository for an example of this).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset