sirin05137 / CSE364_Project

2 stars 0 forks source link

[Note] Movie Recommendation System Operating Algorithm #29

Closed sirin05137 closed 3 years ago

sirin05137 commented 3 years ago

Movie Recommendation System Operating Algorithm

코드로 작성되어 있는 영화 추천 시스템의 알고리즘을 문서로 작성하여 가독성을 높이고 README 파일을 작성할 때 참고하고자 해당 Issue를 작성하였다.

Part 1

1. Input validity test

우선 입력된 성별, 나이가 적절한지 파악한다. 만약 성별 입력값이 공백이거나 M, F(소문자로 입력한 경우도 상관없음)일 때를 제외하고는 아래와 같은 에러 메세지를 출력하도록 설정하였다.

InputInvalidError : Entered gender input is invalid.

나이의 경우 우선 입력값이 숫자인지를 확인한다. 만약 숫자가 아니거나 0 또는 음수이면 아래와 같은 에러메세지를 출력한다.

InputInvalidError : Age must be natural number.

성별과 나이의 입력값에 오류가 없다면 직업 입력값을 확인한다. 직업 입력값이 data/README 파일에 명시 되어 있는 직업과 다를 경우 아래와 같은 경고 메세지를 출력하고 Input value를 other로 인식하여 사용자 데이터를 처리한다.

InputInvalidWarning : Entered occupation doesn't exist. Based on the movie rated by other, it is recommended instead.

입력값에 대하여 모든 공백은 무시되어 처리된다. 예를들어 나이 입력값이 "2 5"로 입력되면 프로그램 내부에서 자동으로 "25"로 인식한다. 또 다른 예로 " grad student"로 입력을 하거나 "gradstudent"로 입력해도 같은 결과값을 보여주게 된다. 또한 대문자나 소문자로 입력된 데이터를 서로 다른 것으로 구분하지 않는다. 즉, "GraD StuDent" 또한 "grad student"로 인식한다.

2. Movie recommendation system

사용자 데이터 입력값에 문제가 없다면 영화 추천 시스템을 작동시킨다. 영화 추천 시스템의 작동 방식은 다음과 같다. user.dat 를 기반으로, 입력받은 사용자 데이터와 같은 유저를 추출해서 List로 만든다. 그 후 추출한 사용자들의 영화 평가 내용과 해당 영화들의 데이터를 ratings.dat 파일과 movies.dat 파일에서 각각 뽑아낸다.

만약 추출한 영화의 개수가 100보다 작을 때는 영화의 개수가 100개보다 많아질 때까지 입력받은 사용자 데이터와 유사도가 높은 순서로 유저 List에 "추가"하는 반복을 수행한다. 우리가 정의한 사용자 데이터와의 유사도 순위는 다음과 같다.

  1. "성별", "나이", "직업"이 모두 같은 경우
  2. "성별", "직업" 만 같은 경우
  3. "나이", "직업" 만 같은 경우
  4. "직업"만 같은 경우
  5. "성별", "나이"만 같은 경우
  6. "성별"만 같은 경우
  7. "나이"만 같은 경우
  8. 전체 유저

이를 이용하여 movieID, Title, Genre, total rating, vote counter를 멤버변수로 가지는 class Movie_data_node로 ArrayList를 생성한다. 이 ArrayList를 movie_rating_table이라고 하자. 그런 다음 IMDB의 weighted rating 방법을 통해 각 영화의 가중평균을 구한다.

IMDB의 Weighted rating을 구하는 방법은 다음과 같다.

W = (vR+mC)/(v+m)

v = 해당 영화의 총 투표수 m = Top 차트에 들기 위한 최소한의 투표수 R = 해당 영화의 평균 평점 C = 모든 영화의 평균 평점

v와 R 값은 Movie_data_node에서 쉽게 구할 수 있으며 m과 C는 각각 다음과 같은 메소드를 이용하여 구할 수 있다. 해당 메소드의 헤더는 다음과 같다

static int Percentile(ArrayList<Movie_data_node> movie_rating_matrix, double p)
static double total_average_rating(ArrayList<Movie_data_node> movie_rating_matrix)

+++추가적으로 해당하는 영화의 개수에 따라 percentile의 비율을 달리하여 조금 더 영화를 추천해주는 데 있어서 타당성을 더하였다. 영화의 개수에 따라 percentile의 비율은 다음과 같은 함수에 의해 구해진다.

static double set_p(int size){
        if(size<100){
            return 0.5;
        }
        else if(size<200){
            return 0.6;
        }
        else if(size<500){
            return 0.7;
        }
        else{
            return 0.8;
        }
    } 

그런 다음 movie_rating_table에서 vote count가 m 이상인 객체만 골라서 classified_table라는 ArrayList를 만든다. 그 후 Weighted rating에 따라 내림차순으로 List를 sort 하고 상위 10개의 영화만 출력한다.

sirin05137 commented 3 years ago

Part 2

Input validity check

Part 1과 같은 방식으로 사용자 데이터가 올바른지 확인한다. 그 후 장르에 대한 입력값이 올바른지 확인한다. 장르 입력값이 올바르게 입력되지 않았다면 에러 메세지를 출력한다. 이것은 milestone 1에서 했던 것과 거의 유사하므로 생략 하겠다. 그 후 장르 입력값에 대한 확인도 part 1과 같다

Movie recommendation system

영화 추천시스템 또한 Part 1과 같은 방식으로 구현된다. 한가지 차이점은 사용자를 추출한 후 그 사용자가 평가한 영화가 우리가 원하는 영화의 장르인 경우가 매우 적다. 이런 상황에 더하여 영화의 개수가 100개보다 많아질 때까지 입력받은 사용자 데이터와 유사도가 높은 순서로 유저 List에 "추가"하는 반복을 수행하는 것은 입력받은 사용자 데이터와 유사도가 적어지는 것이라 파악하였다. 그래서 영화의 개수가 50보다 많아질 때까지 위의 반복을 수행하도록 설정 하였다. 나머지는 Part 1 과 동일하다.

sirin05137 commented 3 years ago

[추가]

위에서 "만약 추출한 영화의 개수가 100보다 작을 때는 영화의 개수가 100개보다 많아질 때까지 입력받은 사용자 데이터와 유사도가 높은 순서로 유저 List에 "추가"하는 반복을 수행한다." 라고 명시해 놨다. 그런데 이 경우 2명의 사람이 100개 이상 평가한 경우가 존재한다. 2명만의 평가를 믿는 것은 타당하지 않다고 판단하였다. 영화에 대해 적어도 10명 이상이 평가해야 믿을만 하다고 생각한다. 그래서 장르가 입력되지 않았을 경우에는 영화의 개수가 100개보다 많아지고 percentile로 구한 최소 투표수 m이 10 이상이 될 때까지 유사도 순서대로 유저 리스트에 추가하는 작업을 반복한다.