sirin05137 / CSE364_Project

2 stars 0 forks source link

Make recommendation system filtered by genre input #25

Closed sirin05137 closed 3 years ago

sirin05137 commented 3 years ago

Make recommendation system filtered by genre input

Milestone2 part2에서는 user data와 genre 입력받아 해당 user data와 genre를 기반으로 Top10의 영화를 추천해준다. 우선 user에 대한 data를 아무것도 입력 받지 않고 genre에 대한 입력만 받았을 때 추천해주는 기능을 구현하였다. 즉 command가 아래와 같을 때의 결과값을 구현하였다.

java -cp target/cse364-project-1.0-SNAPSHOT-jar-with-dependencies.jar gourp11.milestone2 “” “” “” "Adventure"

구현 방법은 issue 24에 설명한 것과 매우 유사하다.

issue 24에서 생성한 ArrayList movie_rating_matrix를 이용한다. (movie_rating_matrix는 movieID, Title, Genre, total rating, vote counter를 멤버변수로 가지는 class Movie_data_node로 생성한 ArrayList이다.)

movie_rating_matrix 의 각 객체가 가진 genre와 입력받은 genre를 비교한다. 만약 객체의 gnere가 입력받은 genre 값 중 적어도 하나의 같은 genre를 가진다면 해당 객체를 ArrayList movie_rating_matrix_genre_classified로 복사한다. (이 ArrayList 또한 class Movie_data_node로 생성한 ArrayList이다.)

이 이후는 issue 24에 설명한 내용과 같다. 편의를 위해 issue 24의 내용을 그대로 가져왔다.

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 메소드에서 p는 임의로 설정할 수 있다. 나는 issue 24에서는 p로 0.95를 사용하였고 여기서는 0.8을 사용하였다(genre로 분류하면서 영화의 개수가 줄 었기 때문). p 값이 잘 이해가 되지 않는다면 Percentile` 메소드가 투표받은 수 상위 (1-p)*100%의 값을 반환한다고 생각하면 이해하기 쉬울 것이다.

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

issue 24를 이해했다면 무리없이 이해할 수 있을것이다.

sanghun17 commented 3 years ago

코드 읽어보았음! 자잘한 버그까지는 못봤고 전체 알고리즘만 보았는데, | !!! 데이터가 적거나 없을 경우 문제가 발생!!! 예를 들어서, 1) F::56::4 인 조건을 가진 유저는 0명임. -> 현재 알고리즘은 완벽히 일치하는 유저들의 평가만을 취급하기 떄문에 사용할 수 있는 RATING DATA가 하나도 없음!! -> TOP10 랭킹 생성자체가 불가능 해짐. 2) F::56::8 인 조건을 가진 유저는 1명임. -> RATING DATA가 과거 스스로 한 것 뿐임. -> 이미 봤던 영화 중 점수가 높은 영화만 추천 됨. 3) 이건 위에 2) 보면서 생각난건데.. total_rating이 동점일 떄 어떻게 처리되는지가 없는 것 같음.. (영화데이터가 많을 수록 동점이 나오긴 힘들겠지만)

대충 생각한 해결방법은,, 1) INPUT 조건과 완벽히 일치하는 유저들뿐만 아니라 "비슷한 유저들"의 RATING 데이터도 사용하면 되지 않을까.. F::56::8이 INPUT 이라면 M::56::8과 F::50::8 유저들의 데이터도 이용한다던지.. "비슷한 유저들"을 어떻게 정의할지만 정한다면, 그 외 부분은 아주 간단히 될 것 같음!! 2) 저떄 유진이 누나가 말한걸 이용해서, 만약 두 영화가 동점일 시, "INPUT GENRE와 영화GENRE의 유사도"를 각각 구해서 유사도가 더 높은 영화에 높은 랭크를 메긴다던지,, 하면 되지 않을까..!

이건 위에거에 비해 사소한 문제인데 make_intersection_list 구할 떄 인풋마다 따로 따로 따로 3개 저장 후, 교집합 두번 구하는 부분만 조금 수정해 볼게..! ( 기존코드를 nested 로 합친다음에 . 한번에 체크하고 한번에 저장하면 뭔가 빨라질 것 같은..? 사실 그냥 냅둬도 될 것 같음.)

sirin05137 commented 3 years ago

비슷한 유저들의 데이터 이용하는 거 관련해서 만약에 F::56::4인 조건이 입력되면 "f","56","" 이랑 "","56","4" 랑 "f","","4"인 경우 해당되는 유저를 합집합으로 만들어서 영화 추천시스템이 작동하게 만들면 어떨까?너무 범위가 넓을라나? 코사인 유사도 쓰는 방법도 생각해봤는데 논리적인 부분에서나 구현하는 부분에서 좀 힘든 부분이 많은거 같아서.

yuujinleee commented 3 years ago

현재코드 f / 56 / "" 합침 f / / 4 합침 / 56 / 4 안합침