BLOG

Amazon SageMaker에서 factorization machine을 사용하여 동영상 추천 프로그램 구축하기
작성일: 2018년 7월 9일

추천 시스템(Recommender system)은 기계 학습(ML)에서 가장 많이 사용되는 응용프로그램 중 하나입니다. 이 글에서는 Amazon SageMaker내장된 알고리즘 중 하나인 factorization machine에 기반한 동영상 추천 모델과 인기 있는 MovieLens 데이터셋을 구축하는 방법을 보여 드리겠습니다.

 

Factorization Machine이란?

 

FM(Factorization Machine)은 2010년에 도입되어 지도식 기계 학습 기법입니다(연구 논문, PDF). FM은 매트릭스 요소화를 통해 문제의 치수를 줄이는 기능에서 이름을 얻습니다.

 

Factorization Machine은 분류 또는 회귀에 사용될 수 있으며 선형 회귀와 같은 기존의 알고리즘보다 대형 스파스(sparse) 데이터셋에서 훨씬 더 효율적입니다. FM이 추천 시스템으로 널리 사용되는 이유가 바로 이 속성 때문입니다. 실제 추천 사항 수가 매우 적지만 사용자 수와 항목 수는 일반적으로 매우 큽니다(사용자는 사용 가능한 모든 항목을 평가하지 않습니다!).

 

여기 간단한 예가 있습니다. 스파스(sparse) 등급 매트릭스(치수 4×4)를 고밀도 사용자 매트릭스(치수 4×2)와 고밀도 항목 매트릭스(2×4)로 간주합니다. 보시다시피 요인(2)의 수가 등급 매트릭스(4)의 열의 수보다 작습니다. 또한 이 곱셈을 사용하면 모든 빈 값을 등급 매트릭스로 채울 수 있으며, 이 값을 사용하여 새 항목을 사용자에게 추천할 수 있습니다.

 

Source: data-artisans.com

 

이 글에서는, 영화 추천인을 만들기 위해 Factorization Machine을 사용할 것입니다. S3 또는 Github에서 companion Jupyter 노트북을 다운로드 할 수 있습니다.

 

MovieLens 데이터셋

 

데이터셋은 추천 시스템을 위한 훌륭한 출발점입니다. 여러 사이즈가 존재합니다. 이 글에서는 ml100k: 1682편의 동영상에서 943명의 사용자로부터 10만 등급을 받았습니다. 보시다시피 ml100k 등급 매트릭스는 가능한 1,586,126(943*1682)중 10만 등급만 유지하므로 상당히 희박합니다(정확하게는 93.6%).

 

데이터셋의 처음 10개 행은 다음과 같습니다. 사용자 754는 영화 595에 별 2개 등급을 매겼습니다.

 

# user id, movie id, rating,      timestamp
754          595          2             879452073
932          157          4             891250667
751          100          4             889132252
101          820          3             877136954
606          1277        3             878148493
581          475          4             879641850
13            50            5             882140001
457          59            5             882397575
111          321           3             891680076
123          657          4             879872066

 

데이터셋 준비

 

앞서 설명한 것처럼 FM은 고해상도 데이터셋에서 가장 잘 작동합니다. 따라서 사용자 ID와 동영상 ID를 한번에 인코딩할 수 있습니다.(타임스탬프는 무시하겠습니다.) 따라서 데이터셋의 각 샘플은 2,625개의 Boolean 벡터(943+1682)로, 사용자 ID 및 동영상 ID와 관련하여 두 개의 값만 1로 설정됩니다.

 

우리는 2진수 판독기를 만들 것입니다. 별 4개 등급과 별 5개 등급이 1로 설정됩니다. 낮은 등급은 0으로 설정됩니다.

 

마지막으로, Amazon SageMaker에서 FM을 구현하려면 훈련 및 테스트 데이터를 protobuf 형식으로 float32 Tensors에 저장해야 합니다. (복잡할 것 같지만, Amazon SageMaker SDK는 이 문제를 해결하는 편리한 유틸리티 기능을 제공하므로 너무 걱정하지 마십시오.)

 

개괄적인 견해

 

다음은 구현해야 하는 단계입니다.

 

  1. 디스크에서 MovieLens 훈련셋과 테스트셋을 로드합니다.
  2. 각 셋에 대해 한번에 인코딩된 데이터 샘플을 저장하는 스파스(sparse) 매트릭스를 만듭니다.
  3. 각 셋에 대해 레이블 벡터 고정 등급을 작성합니다.
  4. 두 셋을 모두 protobuf 인코딩 파일에 작성합니다.
  5. 이 파일들을 Amazon S3 버킷에 복사합니다.
  6. Amazon SageMaker에서 factorization machine 훈련 작업을 구성하고 실행합니다.
  7. 해당 모델을 엔드포인트에 배포합니다
  8. 몇가지 예측을 실행합니다.

 

시작합시다!

 

MovieLens 데이터셋 로드

 

ml-100k에는 여러 텍스트 파일이 포함되어 있지만 이 중 두 개만 사용하여 모델을 만들 예정입니다.

 

  • ua.base(90,570개의 샘플)가 저희 훈련 셋이 될 것입니다.
  • ua.test(9,430개의 샘플)은 저희의 시험 셋이 될 것입니다.

 

두 파일의 형식은 동일합니다.

 

  • 사용자 ID(1에서 943 사이의 정수)
  • 동영상 ID(1에서 1682 사이의 정수)
  • 등급(1과 5사이의 정수)
  • 타임 스탬프(Epoch 기반 정수)

 

따라서 다음과 같은 데이터 구조를 구축합니다.

 

  • 훈련 스파스 매트릭스: 90,570개의 행과 2,625개의 열(943개의 사용자 ID에 대한 한번에 하는 인코딩 기능 및 동영상 ID에 대한 1682개의 한번에 하는 인코딩 기능)
  • 교육 라벨 배열: 90,570 등급
  • 테스트 스파스 매트릭스: 9,430개 행 및 2,625개 열
  • 시험 라벨 배열: 9,430 등급

 

알림: 각 샘플은 단일의 한번에 인코딩된 feature 벡터여야 합니다. 사용자 ID, 동영상 ID 및 추가할 수 있는 추가 기능에 대해 한번에 인코딩된 값을 연결해야 합니다. 고유 벡터 목록(사용자 ID용, 동영상 ID용 등)을 만드는 것은 올바른 방법이 아닙니다.

 

훈련 매트릭스는 현재 237,746,250개(90,570*2,625개)중 0이 아닌 것은 181,140개(90,570*2)에 불과합니다. 즉, 매트릭스가 99.92% 희박합니다. 이를 고밀도 매트릭스로 저장하는 것은 스토리지와 컴퓨팅 성능의 엄청난 낭비가 될 것입니다.

 

이를 방지하려면 샘플에는 scipy.lil_matrix 스파스 매트릭스를 사용하고 레이블에는  numpy 배열을 사용하십시오.

 

우리는 클래스당 대략 같은 수의 샘플이 있는지 확인해야 합니다. 데이터셋의 불균형은 분류기에 심각한 문제입니다.

 

print(np.count_nonzero(Y_train)/nbRatingsTrain)

0.55

print(np.count_nonzero(Y_test)/nbRatingsTest)

0.58

약간 균형이 맞지 않지만, 나쁜 것은 아닙니다. 계속하시죠.

 

protobuf 파일에 입력 중

 

다음은 Amazon S3에 저장된 두 개의 protobuf 파일에 대한 교육 셋과 테스트 셋을 작성하겠습니다. 다행히도, 저희는 write_spmatrix_to_sparse_tensor() 유틸리티 기능에 의존할 수 있습니다. 그것은 저희의 샘플과 라벨을 인 메모리 protobuf로 인코딩된 스파스 멀티 치수 배열(AKA tensor)에 입력합니다.

 

그리고 아마존 S3에 버퍼를 투입합니다. 이 단계가 완료되면 데이터 준비가 완료되고 이제 훈련 업무에 집중할 수 있습니다.

 

훈련을 위한 문제 해결 팁

 

  • 샘플과 라벨이 모두 float32 값입니까?
  • 샘플이 스파스 매트릭스에 저장되어 있습니까(샘플 배열 또는 다른 것이 아닙니까)?
  • 라벨이 벡터에 저장되어 있습니까(매트릭스의 종류가 아닙니까)?
  • write_spmatrix_to_sparse_tensor()가 정의되지 않았습니까? SDK 1.0.2에 추가되었으며 Amazon SageMaker SDK를 업그레이드해야 할 수도 있습니다. 게시물 끝에 있는 부록을 참조하십시오.

 

참고: 최신 Amazon SageMaker SDK로 업그레이드하십시오.

 

  1. 노트북 인스턴스를 엽니다.
  2. 인스턴스에서 Jupyter 터미널을 엽니다.
  3. 다음과 같이 SDK를 업그레이드할 Conda 환경을 활성화하십시오.

 

source activate python2

pip install -U sagemaker

 

다음은 아마존 S3에 세워진 훈련셋입니다: 5.5MB에 불과합니다. 희소 매트릭스 FTW!

 

$ aws s3 ls s3://jsimon-sagemaker-us/sagemaker/fm-movielens/train/train.protobuf2018-01-28 16:50:29    5796480 train.protobuf

 

훈련 작업 실행하기

 

먼저 AWS 리전에서 사용할 수 있는 FM 컨테이너를 기반으로 Estimator를 생성해 보겠습니다. 그런 다음 일부 FM 전용 하이퍼파라미터를 설정해야 합니다(설명서의 전체 목록).

 

  • feature_dim: 각 샘플의 feature 수(이 경우 2,625개).
  • predictor_type :  ‘binary_classifier’ 가 사용됩니다.
  • num_factors: 사용자 및 항목 매트릭스에 대한 공통 치수입니다(글 시작 부분의 예제에서 설명).

 

여기에 사용되는 다른 것들은 선택 사항입니다.

 

마지막으로, 훈련 업무를 시작해 봅시다. S3에서 호스팅된 훈련과 테스트셋을 모두 통과하면서 fit() API를 호출하기만 하면 됩니다. 간단하고 우아합니다.

 

몇 분 후, 훈련이 완료됩니다. Jupyter 노트북이나 Amazon CloudWatch 로그/aws/sagemaker/trainingjobs 로그 그룹)에서 훈련 로그를 확인할 수 있습니다.

 

50번의 epoch 후 테스트 정확도는 71.5%이고 F1 점수(이진 분류자의 일반적인 메트릭)는 0.75입니다(1은 완벽한 분류기임을 나타냄). 좋지는 않지만, 스파스 매트릭스와 protobuf 흥분 때문에, 하이퍼파라미터를 조율하는데 많은 시간을 보내지는 않았습니다. 확실히 더 잘하실 것입니다.

 

[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : binary_classification_accuracy
[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : 0.7159
[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : binary_classification_cross_entropy
[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : 0.581087609863
[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : binary_f_1.000
[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : 0.74558968389

 

모델 구축에 대한 마지막 단계가 있습니다.

 

모델 배포

 

모델을 배치하는데 필요한 것은 간단한 API호출뿐입니다. 예전에는(6개월쯤 전)AWS에서도 상당한 작업이 필요했습니다. 여기서는 deploy()만 호출하면 됩니다.

 

이제 predict() API를 사용하여 모델의 HTTP 엔드포인트를 호출할 준비가 되었습니다. 요청 및 응답 데이터의 형식은 JSON으로, 스파스 매트릭스 샘플을 JSON으로 변환하려면 단순 직렬화기가 필요합니다.

 

이제 모든 사용자의 동영상을 분류할 수 있습니다. 새 데이터셋을 구축하고 훈련 및 테스트셋과 동일한 방식으로 처리한 다음 predict()을 사용하여 결과를 얻으면 됩니다. 또한 다른 예측 임계값(특정 점수 위에서 예측을 1로, 그 아래에서 0으로 설정)을 사용하여 실험하고 어떤 값이 가장 효율적인 추천 사항을 제공하는지 확인해야 합니다. MovieLens 데이터셋에는 동영상 제목도 포함되므로 더 많은 내용을 살펴볼 수 있습니다.

 

결론

 

내장된 알고리즘을 사용하면 훈련 코드를 작성하지 않고도 작업을 신속하게 완료할 수 있습니다. 데이터 준비 작업이 상당히 많이 수반되지만 이 글에서 보았듯이, 대규모 훈련 작업을 빠르고 확장 가능하게 만드는 것이 핵심입니다.

 

다른 Amazon SageMaker 기본 제공 알고리즘에 대해 알고 싶다면 다음과 같은 이전 게시물을 참조하십시오.

 

 

또한 추천 시스템에 대해 자세히 알아보려면 다음과 같은 몇 가지 리소스를 참조하십시오.

 

 

항상 읽어 주셔서 감사합니다.

 

원문 URL: https://aws.amazon.com/ko/blogs/machine-learning/build-a-movie-recommender-with-factorization-machines-on-amazon-sagemaker/

** 메가존 TechBlog는 AWS BLOG 영문 게재글중에서 한국 사용자들에게 유용한 정보 및 콘텐츠를 우선적으로 번역하여 내부 엔지니어 검수를 받아서, 정기적으로 게재하고 있습니다. 추가로 번역및 게재를 희망하는 글에 대해서 관리자에게 메일 또는 SNS페이지에 댓글을 남겨주시면, 우선적으로 번역해서 전달해드리도록 하겠습니다.