글쟁이, 코딩한다

0217/ k_digital 47 일차 / 파이널프로젝트 본문

나는 코딩도 한다/TIL

0217/ k_digital 47 일차 / 파이널프로젝트

Algori 2021. 2. 17. 23:59

0.

 이상형 월드컵 기반 영화 추천 사이트 만들기

 

1.

 프로젝트 수행중

 

  오늘 한 일

 

1) 데이터 전처리

 

우리가 만지는 데이터는 무비렌즈(movielens)의 영화 데이터다. 굉장히 다양한 영화 메타 데이터, IMDB 기반 평점, 유저 rating 등 추천을 위한 모든 데이터를 갖추고 있다. 타이타닉 데이터셋이 ML을 위한, MNIST 데이터셋이 DL을 위한 기본 데이터셋이라면, 이 데이터는 추천시스템을 위한 기본 데이터셋이라 할 수 있다. 따라서 Kaggle에서도 다양한 추천시스템과 결과값들을 확인할 수 있다. 

무비렌즈의 영화 데이터셋은 크기, 종류가 다양한 데이터들을 가지고 있다. 우리는 그중에서도 영화가 약 10000여개, rating이 100000여개인 데이터를 골랐다. 2018년 영화까지 있어 다소 최근 데이터지만, 일반적인 데이터셋보다는 크기가 작다. 기본적으로 우리의 목적은 배운 적 없던 추천시스템의 기초를 확립하는 것, 이상형월드컵을 통한 색다른 Explict 데이터 수집에 있다. 그렇기에 큰 데이터를 활용하며 힘을 뺄 필요가 없다는 판단이었다. 각자 노트북으로 작업하고 웹 배포도 생각하고 있는 만큼 작은 데이터가 유리하다고 생각했다.

 

결과적으로는 이것보다 큰 데이터셋에서 다양한 정보들을 빼와 합치느라 더 고생했다. 사실 그렇게 차이가 큰 것도 아닌데 말이다. merge하는 과정에서 꽤나 여러 데이터들이 사라지기도 했다. 어쨌든 덕분에 데이터프레임을 다루는 다양한 방식을 익히기는 했다. 아, 네이버 영화 검색 api를 활용해서 데이터도 받았다. 이미지 url을 받을 수 있어 유용했지만, 이유를 알 수 없는 오류들로 데이터가 꽤나 소실됐다. 시간을 낸다면 오류의 이유를 분석하겠지만 곁다리 작업이라 있는 것만 쓰기로 했다.

대부분 이미 알고 있던 함수들을 바탕으로 이리저리 매만져서 크게 새로 안 지식은 많지 않다. 굉장히 자주 쓰일법하지만, 존재만 알고 있던 여러 기능들을 실제로 써본 것에 의의가 있다.

 

 

1. os 

다른 폴더에 있는 파일들을 경로 기반으로 얻어오기

참고용 블로그 yganalyst.github.io/data_handling/memo_1/ (기초 라이브러리들의 활용법과 결과를 깔끔하게 보여줘 애용하는 블로그)

 

2. map과 lambda

 

map은 데이터프레임의 한 Series(쉽게 열 하나라 생각하자)에 일괄적으로 명령어를 적용한다. 임시로 값을 변환해주는 lambda와 잘 붙어나온다. lambda는 x를 : 뒤의 형태로 바꿔준다. if문 등도 한 줄로 깔끔하게 처리할 수 있다. 

title 열에서 (1995) 같은 숫자를 깔끔하게 떼어내 only_title열에 저장했다. 원본이 필요없다면 title 열에 그대로 붙여놔도 큰 문제 없다. lambda로는 str의 index를 활용해 ( 전까지만 나타나도록 조정했다. 

참고용 블로그 www.leejungmin.org/post/2018/04/21/pandas_apply_and_map/ (map, apply의 차이점 비교)

 

3. pandas.str

 

str은 데이터프레임 시리즈 안에 속한 str들에게 취할 수 있는 기능들을 많이 제공한다. 추출의 extract, 안에 속했는지 확인하는 contains, 대체하는 replace 등을 따로 map과 lambda를 쓰지 않고 곧장 적용할 수 있다. str을 다루는 시간을 많이 줄여준다. 개꿀이다.

이번에는 title에서 괄호안 내용만 따로 옮겨냈다. 추출을 의미하는 extract를 썼고, 정규표현식도 썼다. 정규표현식은 익숙하지가 않아서 한참 헤매다 얻어걸렸다. 

참고용 블로그 : yganalyst.github.io/data_handling/memo_9/

 

이외에도 서로 다른 데이터프레임을 중심 열로 합치는 merge, 시리즈 안 str을 list와 dict 등 형태로 바꿔주는 literal_eval(ast 라이브러리), 데이터프레임의 표기를 돕는 pd.set_option 등 기능을 여러번 쓸 수 있었다.

 

 

2) 추천 시스템 : 콘텐츠 기반 필터링

 

전처리를 거쳐 실제 추천에 사용할 데이터프레임을 얻고 나서는 추천 시스템 만들기에 들어갔다.

 

처음 시작한 것은 콘텐츠 기반 필터링이다. 이용자가 좋아한 콘텐츠 자체 값을 비교해 추천하는 거다. 실제 콘텐츠를 구별하는 정보가 세밀할수록, 이용자로부터 정확한 선호도 점수를 받을수록 정확도가 올라간다. 고전적인 방식이지만 데이터에 노력을 많이 할애하는 만큼 추천 자체는 더 믿을만하다고 느껴졌다. 

이상형월드컵이라는 방식도 결국 이 선호도 점수를 색다르게 받기 위한 장치다. 우리는 콘텐츠 기반 필터링을 위한 정보로 장르, 배우, 감독을 활용했다. 영화 overview와 review 등도 썼다면 더 다양한 추천을 진행할 수 있었을텐데 아쉽다. 기본적으로 장르는 벡터화와 유사도 분석을 진행했고, 배우, 감독은 데이터셋에서 단순한 찾기 기능을 활용해 끌어왔다. 

 

나는 장르 기반 추천에서 모두 무언가 좋은 추천이라고 느낄 수 있게 평점 개수가 상위 25% 이상인 영화들만 추려 비교군을 꾸렸다. 유사도로 비교해 후보군을 20여개 추려낸 후에는 다시 또 평점을 기반으로 줄을 세웠다. 결과적으로 추천으로 나온 영화들은 이미 유명한 영화들이었고, 실제로 느낌도 비슷함을 확인할 수 있었다. 

일반 기업들의 추천 시스템을 활용하다보면 맨 그 나물에 그 밥 이라는 점이 아쉬웠다. '실패하지 않는 추천'이 중요해서일까. 협업 필터링은 다른 이들의 정보에 기반하다보니 더 이런 longtail 문제가 크다고 한다. 잘 알려지지 않았지만 좋은 콘텐츠들을 발굴해 추천하는 일은 무척 어려운 일일 테다. 사람한테나 기계한테나. 이런 추천 시스템이 콘텐츠 양극화를 더 불러오지 않아야 할텐데 말이다.

추천이 취향이라고 굳건히 믿어갈수록 이런 문제도 조심해야 할테다.

 

최종 추천 시스템은 장르에 태그 정보도 더하고 가중치를 준 다른 팀원분의 시스템으로 쓰게 됐다. 결과값들은 이렇다. 나름 쓸만하다.

Comments