안녕하세요. 이번 시간엔 Incremental Singular Value Decomposition Algorithms을 구현해보겠습니다.
참고한 자료는 다음과 같습니다(지난 번과 유사합니다).
Incremental Singular Value Decomposition Algorithms for Highly Scalable Recommender Systems (B Sarwar외, 2002)
: 알고리즘 논문
Evaluation of standard SVD-based techniques for Collaborative Filtering (M Vozalis외, 2009)
: matrix factorization을 할 때 평가하는 방법에 대한 논문
https://drive.google.com/file/d/0BylQe2cRVWE_RmZoUTJYSGZNaXM/viewdrive.google.com/file/d/0BylQe2cRVWE_RmZoUTJYSGZNaXM/view
: matrix factorization을 할 때 평가하는 방법에 대한 논문
기본 준비
아래에 올라오는 jupyter 파일은 제 github에 모두 있으니 필요하신 분들은 여기서 코드 복사하셔서 사용하시면 되겠습니다.
github.com/Hwan-I/Study/tree/master/Recommend/incremental_SVD
* 데이터 링크입니다.
grouplens.org/datasets/movielens/100k/
코드실행
1. 패키지를 불러옵니다. 여기서 utils는 제가 경로 설정을 위해 만든 py파일이라 저 부분은 없애시고 실행하시면 됩니다.
2. 기본셋팅(main 위의 함수 중 experiment를 제외하면 전처리하는 코드라 따로 설명을 넣지 않았습니다. 자세한 부분은 주석을 참조하시거나 질문 주시면 답변 드리겠습니다)
- data_path와 raw_path : 점수 데이터를 불러오기 위한 path입니다.
- ratings : 점수 데이터입니다. (위의 링크에서 다운 받으시고 압축을 푼 뒤, raw_path를 다운 받으신 폴더로 하시면 열 수 있습니다)
- seed_num : 랜덤으로 값을 추출할 때 똑같은 결과가 나오게 하기 위해 번호를 지정합니다. 저는 0번으로 했지만 아무 번호를 하셔도 상관없습니다.
- X_ind : ratings의 index 값을 저장하는 변수입니다.
3. 실험셋팅 : 실험 관련 변수를 셋팅합니다.
- k : SVD로 matrix 분해 이후 몇 차원을 사용하여 복구할지 정하는 값입니다. 저는 논문에서 나온대로 14차원을 선택했습니다.
- origin_pivot : user x item matrix로 구성된 dataframe입니다.
- key_dict : 'user'와 'item'을 key값으로 가지는 dict입니다.
- user : key값은 user번호, value는 key값에 해당하는 origin_pivot의 index값입니다.
- item : key값은 user번호, value는 key값에 해당하는 origin_pivot의 column값입니다.
4. 실험
- 저는 test_rate를 0.2, 0.5, 0.8로 주어 실험했습니다. 여기서 test_rate란 test 데이터의 비율을 의미하는데 0.2면 전체 데이터의 20%를 test 데이터로 쓴다는 의미입니다.
- 추천시스템에서 test 데이터를 어떻게 써야하는지는 여러 기준이 있는데 저는 test에 해당하는 user, item 값을 NaN으로 처리한 뒤에 train 했습니다. 이후 예측값이 나오면 그 값과 실제값을 비교하여 mae를 구했습니다. 이러한 기준은 위의 참고 자료를 참조하시기 바랍니다.
- experiment의 매개변수에 대한 설명입니다.
- 0.2 : test_rate
- seed_num : 위의 기본셋팅에서 설정한 랜덤 고정 값입니다.
- ratings : u.data 파일입니다. UserID, MovieID, Ratings 등을 column으로 가진 dataframe입니다.
- origin_pivot : user x item matrix로 구성된 dataframe입니다.
- key_dict : 'user'와 'item'을 key값으로 가지는 dict입니다.
- True : 결과값을 반환할 때 True면 예측값, 예측 matrix 등을 추가로 반환하는 옵션입니다.
5. 실험과정 (experiment 함수 부분입니다)
5-1. 실험 기본 셋팅
user x item matrix를 정규화하고 test 할 user와 item을 추출하는 과정입니다. 여기서 정규화는 user x item matrix에 대해 test data는 NaN으로 처리하고 NaN 값을 채울 때 train의 모든 item의 평균값을 사용합니다(NaN 데이터 제외). 그 후 user x item matrix에서 user 단위로 각 user의 평균값을 뺍니다.(함수 normalized_df 부분을 참고하시기 바랍니다)
실험 기본셋팅
- 변수 설명
- X_ind : ratings의 index 값입니다.
- test_dict : basis_num 단위로 mae값을 저장할 dict입니다.
- rg : 랜덤으로 번호를 추출할 때 결과를 고정하기 위한 변수입니다.
- test_index : test_rate를 기준으로 test 데이터 index를 추출합니다.
- basis_num_list : basis 값을 가진 list로 for문을 활용하기 위해 list로 넣습니다.
- count : 실험 진행을 나타내는 변수입니다.
- test_ind : ratings에서의 최종 test_index값입니다.
- test_pairs : [([(userid1, movieid1, rating1),(userid2, movieid2, rating2),...]와 같은 형태의 list입니다.
- changed_origin_pivot : test값인 user, item에 대한 점수 값을 NaN으로 처리한 user x item matrix입니다.
- norm_pivot : 정규화된 user x item matrix입니다.
- mean_dict : key값은 index 번호, value는 index에 해당하는 user의 평균 점수 값을 가진 dict입니다.
- result_dict : key값은 basis_num, value는 pred, true 값 등을 가진 dict입니다.
5-2. 반복 실험 : basis_num 단위로 실험을 진행합니다.
- 변수 설명
- model, model.fit() : incremental_svd를 만들고 fit합니다.
- pred_list : test data에 해당하는 예측값입니다.
- true_list : test data의 실제값입니다.
- matrix : 예측값에 해당하는 user x item matrix입니다.
- test_dict에 basis_num을 key값으로 각 mae를 저장합니다.
- result_return_option이 True면 basis_num에 해당하는 pred 값 등도 result_dict에 저장합니다.
- 이를 basis_num_list 만큼 진행합니다.
6. 결과
x축은 basis 값, y축은 mae값입니다. basis가 600일 때는 별 차이가 없었으나 그 이후로는 test_rate가 0.2일 때 확실히 mae가 더 낮은 것을 볼 수 있습니다. user가 총 943명인데 800을 basis로 놓고 만든 incremental_SVD 모델과 단순히 SVD를 쓴 결과를 비교하면 크게 차이가 나지 않는 것을 볼 수 있습니다. 데이터가 작아서 모델링하는 시간은 2개 서로 비슷했습니다.
7. 결론
- 논문과 다른 결과가 나오긴 했으나 랜덤 seed 값을 어떻게 주느냐에 따라 결과가 상당히 달라지기 때문에 실험결과와 똑같이 구현하는 것은 불가능하다고 판단했습니다.(test 데이터에 대한 처리도 다를 수 있음)
- item의 평균값으로 아무래도 채우다보니 오차는 아마 실제값이 평균값에서 멀수록 크게 나올 것입니다. 이러한 부분을 개선한다면 해당 모델의 성능이 더 높아질 것이라고 생각합니다.
긴글인데 읽어주셔서 감사합니다. 혹시 궁금하신 사항이나 잘못된 부분있으면 말씀해주세요!
'모델 > 추천시스템' 카테고리의 다른 글
Neural Collaborative Filtering(2) - 알고리즘 및 결과 (0) | 2020.11.15 |
---|---|
Neural Collaborative Filtering(1) - 도입부 (0) | 2020.11.10 |
추천시스템 - Incremental Singular Value Decomposition Algorithms(1) (0) | 2020.10.12 |
추천시스템 - 기초2 (0) | 2020.10.08 |
추천시스템 - 기초 (0) | 2020.10.08 |