0
$\begingroup$

I am using a book and a video to learn how to use KNN method to classify movies according to their genres.This is my code:

import numpy as np
import pandas as pd

r_cols = ['user_id', 'movie_id', 'rating']

ratings = pd.read_csv('C:/Users/dell/Downloads/DataScience/DataScience-Python3/ml-100k/u.data', sep='\t', engine='python', names=r_cols, usecols=range(3))                         # The file is u.data from MovieLens
print(ratings.head())   


movieProperties = ratings.groupby('movie_id').agg({'rating': [np.size, np.mean]})
print(movieProperties.head())


movieNumRatings = pd.DataFrame(movieProperties['rating']['size'])
movieNormalizedNumRatings = movieNumRatings.apply(lambda x: (x - np.min(x)) / (np.max(x) - np.min(x)))
print(movieNormalizedNumRatings.head())


movieDict = {}
with open('C:/Users/dell/Downloads/DataScience/DataScience-Python3/ml-100k/u.item') as f:                       # The file is u.item from MovieLens
    temp = ''
    for line in f:
        fields = line.rstrip('\n').split('|')
        movieID = int(fields[0])
        name = fields[1]
        genres = fields[5:25]
        genres = map(int, genres)
        movieDict[movieID] = (name, genres, 
movieNormalizedNumRatings.loc[movieID].get('size'),           movieProperties.loc[movieID].rating.get('mean'))

print(movieDict[1])

from scipy import spatial
def ComputeDistance(a, b):
    genresA = a[1]
    genresB = b[1]
    genreDistance = spatial.distance.cosine(genresA, genresB)
    popularityA = a[2]
    popularityB = b[2]
    popularityDistance = abs(popularityA - popularityB)
    return genreDistance + popularityDistance        # Everything seems fine up to this point. But the problem seems to be the next line of code.

print(ComputeDistance(movieDict[2], movieDict[4]))

Note: This code can be found here: https://hendra-herviawan.github.io/Movie-Recommendation-based-on-KNN-K-Nearest-Neighbors.html

Note: This code can also be found on pg 245-250, chp7, Hands-On Data Science and Python Machine Learning by Frank Kane. I have an e-copy and I can send it on request.

Note: I don't know how to share the csv files here. I will appreciate it if somebody can tell me how I can do that here.

$\endgroup$
  • $\begingroup$ What are the types of movieDict[2][1] and movieDict[4][1] (it is the objets which are passed to spatial.distance.cosine)? $\endgroup$ – Stanislas Morbieu Nov 3 '19 at 12:55
  • $\begingroup$ Please avoid giving code as an image, see meta.stackoverflow.com/a/285557/891919 $\endgroup$ – Erwan Nov 3 '19 at 23:48
  • $\begingroup$ The return genreDistance([...]) line is strange. genreDistance is a double precision float, it cannot be called as a function. Not sure what is the point of this instruction. $\endgroup$ – Romain Reboulleau Nov 4 '19 at 6:01
  • 2
    $\begingroup$ Ok, now what's the error message and the line raising it? $\endgroup$ – Romain Reboulleau Nov 4 '19 at 22:02
  • 1
    $\begingroup$ @MrProf please edit the question to include add the error, not only in comments. $\endgroup$ – Itamar Mushkin Nov 5 '19 at 6:22
0
$\begingroup$

I think I have bumped into what works. I am posting the correct code since somebody may need this someday:

import numpy as np

import pandas as pd

r_cols = ['user_id', 'movie_id', 'rating']

ratings = pd.read_csv('C:/Users/dell/Downloads/DataScience/DataScience-Python3/ml-100k/u.data', sep='\t', engine='python', names=r_cols, usecols=range(3))  # please enter your file path here. The file is u.data

print(ratings.head())  


movieProperties = ratings.groupby('movie_id').agg({'rating': [np.size, np.mean]})

print(movieProperties.head())


movieNumRatings = pd.DataFrame(movieProperties['rating']['size'])

movieNormalizedNumRatings = movieNumRatings.apply(lambda x: (x - np.min(x)) / (np.max(x) - np.min(x)))

print(movieNormalizedNumRatings.head())


movieDict = {}

with open('C:/Users/dell/Downloads/DataScience/DataScience-Python3/ml-100k/u.item') as f:     # The file is u.item

    temp = ''

    for line in f:

        fields = line.rstrip('\n').split('|')

        movieID = int(fields[0])

        name = fields[1]

        genres = fields[5:25]

        genres = map(int, genres)

        movieDict[movieID] = (name, genres, movieNormalizedNumRatings.loc[movieID].get('size'), movieProperties.loc[movieID].rating.get('mean'))

print(movieDict[1])


from scipy import spatial

def ComputeDistance(a, b):

    genresA = np.array(list(a[1]))

    genresB = np.array(list(b[1]))

    genreDistance = spatial.distance.cosine(genresA, genresB)

    popularityA = np.array(a[2])

    popularityB = np.array(b[2])

    popularityDistance = abs(popularityA - popularityB)

    return genreDistance + popularityDistance  

print(ComputeDistance(movieDict[2], movieDict[4])) 

I am using this opportunity to thank those who gave me one or two suggestions.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.