Movie Recommender System Built With Vue and Bulma

? Group Members

  • Michael Pereira (500896409)
  • Hitarth Chudgar (500888845)
  • Dhanayush Raninga (500967245)

??️ Movie Recommender System

This project requires node.js.

Build Setup

# install dependencies
$ yarn install 

# serve with hot reload at localhost:8080
$ yarn dev

# build for production and launch server
$ yarn build
$ yarn start

Alternatively, can use npm instead of yarn.

? Frameworks

  • Nuxt.js – for building user interfaces and connecting Javascript/Typescript code
  • Bulma – for UI components and styling

? Back-End

Dependencies

  • express – for running a server locally to access local files

? Front-End

Dependencies

  • Buefy – for using UI components for Vue.js based on Bulma
  • axios – for the promise based HTTP client to handle requests

? Gallery

View more images under the ./static/gallery/ directory.

? Program Details

Recommendation algorithm – User Based Collaborative Filtering

  • We made use of the collaborative filtering method to recommend relevant movies to the user based on the similarity score and by using the formula to predict the rating that user would give for the movie.

  • User-Based Collaborative Filtering is a technique for predicting which products a user would enjoy based on the ratings provided to that item by other users with similar tastes to the target user.

  • Firstly, we made use of average aggregate function to determine the averages of user ratings as follows:

  • Secondly, for the similarity score calculation we used the average based formula as follows:
    Sim(X,Y) = Numerator/Denominator

  • Lastly, we made use of predictive rating formula to predict the rating of the movie by the user, and pass it through the threshold:
    R(X, Runknown) = (sim(X, A)*r(A, Rknown) + sim(X, D)*r(D, Rknown))/(sim..+sim..)

Main functions/methods used

  • User Rating and Mapping
    This is used to declare random initial ratings that map to the relevant movies (this can set up initial recommendations, and it changes later on as new users are signing up and rating movies)

  // Predefined User Ratings (Randomly Generated from 0-5)
  private static randomUsersOriginalRatings: any = {
    Alice: [3, 0, 1, 2, 3, 3, 4, 3, 4, 3, 4, 3, 5, 5, 4, 5, 4, 5],
    Ashley: [5, 4, 5, 4, 4, 5, 5, 0, 4, 3, 4, 5, 4, 2, 5, 2, 3, 1],
    Bob: [0, 3, 2, 2, 1, 3, 5, 5, 5, 3, 3, 5, 2, 4, 3, 5, 3, 2],
  }
  
   // Mapping of transformed the ratings' data
  // Each predefined user is denoted as a 'random user'
  private static usersRatingsMap: any = {
    Alice: {
      name: 'Alice',
      randomUsersAverage: 0,
      randomUsersRatings: [],
      currentUsersAverage: 0,
      currentUsersRatings: [],
      similarityScore: 0,
    }
  • calculateUserCF

This is the main function that calculates the similarity scores and determines the predictive movies.

1)Calculate the Average of Each Person

const users = Object.keys(this.usersRatingsMap)

2)Hold array of similarity scores

const similarityScoreRanking: SimilarityScores[] = []

3)Calculate Similarity Scores
4)Must be greater than 3.5 (a rating of 3.5-5 means the user likes the movie, therefore is a recommendation)

 if (predictedMovieScore > 3.5) {
          recommendedMovies.push({
            id: movieIds[i],
            score: predictedMovieScore,
     })
 }
  • Movie Dataset Information
    This is used to store the sample diverse movie dataset (17 movies in total to maintain performance and loading speed)
    1)An array is used to store the movies as constant variable (the movie name and their cover image)

export const movies = [
  'Shang-Chi and the Legend of the Ten Rings',
  'Captain America: Civil War',
  'Spider-Man: Homecoming',
]

export const movieImgUrls = [
  'https://mx.web.img3.acsta.net/pictures/21/08/10/10/22/2091196.jpg',
  'https://m.media-amazon.com/images/M/MV5BMjQ0MTgyNjAxMV5BMl5BanBnXkFtZTgwNjUzMDkyODE@._V1_.jpg',
  • Login/Register
    This is used to create the login and register page for users to login and create new account to rate movies respectively. Made use of live password checklist to make sure that the user selects a secure password.

export default class Register extends Vue {
  private username: string = '';
  private password: string = '';

  private async login() {
    await BuefyService.startLoading()
    await axios.post('/login', {
      username: this.username,
      password: this.password,
      db: WebStorageService.checkForData()
    }).then(() => {
      WebStorageService.authorizeUser(this.username);
      BuefyService.successToast('User Authorized')
      this.$router.push('/movies')
    }).catch(error => {
      BuefyService.dangerToast(error.response.data.error)
    })
    await BuefyService.stopLoading()
  }

  get invalid() {
    return this.username.length < 3 || this.username.length > 32 || this.password.length < 3 || this.password.length > 64
  }

  mounted() {
    if (WebStorageService.getCurrentAuthorizedUser() !== null) {
      this.$router.push('/movies')
    }
  }
}

GitHub

View Github