본문 바로가기

ML Recommendation

포트폴리오를 위한 추천 알고리즘 구현 [2장] : Scikit-Surprise

반응형
 

포트폴리오를 위한 추천 알고리즘 구현 [1장] : Scikit-Surprise

포트폴리오 구성을 위한 첫 번째 시간입니다. 추천 알고리즘 구현을 위해 포트폴리오를 구성하기 위한 실습을 하겠습니다. 본 과정을 통해 초급자로서 기본적인 추천 알고리즘을 구현하고 차

nicola-ml.tistory.com

 

포트폴리오 구성을 위한 두 번째 시간입니다.

먼저 이전 시간에 보충하기로 했던 내용에 대해 알아보겠습니다.

 

! 다음에 공부해야 할 내용 - 잠재요인 협업 필터링(Latent Factor), SVD

협업 필터링주요 목표는 사용자-아이템 평점 매트릭스와 같은 축적된 사용자 행동 데이터를 기반으로 사용자가 아직 평가하지 않은 아이템을 예측 평가(Predicted Rating)하는 것입니다.  예를 들어 특정 사용자가 아직 구매하지 않은 제품이 있다면 협업 필터링은 사용자가 평가한 다른 아이템을 기반으로 사용자가 평가하지 않은 아이템의 예측 평가를 도출하는 방식입니다.  

이 중 Latent Factor(잠재 요인 협업 필터링)은 잠재 요인 협업 필터링으로 사용자-아이템 평점 매트릭스 속에 숨어 있는 잠재 요인을 추출해 예측을 할 수 있게 하는 기법입니다. 잠재 요인 협업 필터링은 사용자-아이템 평점 행렬 데이터만을 이용해 말 그대로 '잠재 요인'을 끄집어내는 것을 의미합니다. '잠재 요인'이 어떤 거인지는 명확히 정의할 수 없습니다.

 

대규모 다차원 행렬을 SVD와 같은 차원 감소 기법으로 분해하는 과정에서 잠재 요인을 추출하는데, 이러한 기법을 행렬 분해라고 합니다.  차원 축소에는 PCA, LDA, SVD, NMF 방식이 있습니다. 자세한 사항은 [이곳]

 

이 강좌에서는 SVD의 경우 행렬 분해를 통한 잠재 요인 협업 필터링을 위한 SVD알고리즘이라고 생각하면 됩니다. 관련된 파라미터로 n_factors와 n_epochs의 값을 변경해 튜닝할 수 있으나 튜닝 효과는 크지 않습니다. baised의 경우는 큰 이슈가 없는 한 기본값인 True로 설정을 유지하는 것이 좋습니다.

  • n_factors: 잠재 요인 K의 개수. 기본값은 100, 값이 커질수록 정확도가 높아질 수 있으나 과접합 문제가 발생할 수 있습니다. 
  • n_epochs: SGD(Stochastic Gradient Descent) 수행 시 반복 횟수, 기본값은 20
  • biased (bool): 베이스라인 사용자 편향 적용 여부이며,디폴트는 True입니다. 

 

 

! 다음에 공부해야 할 내용 - 데이터형(튜플과 여러가지 데이터 유형) 

자세한 사항은 [이곳]

 

! 다음에 공부해야 할 내용 - 알고리즘 Accuracy에 대해 RMSE, MSE.. 방법에 대해

 회귀분석의 정확성을 측정하기 위한 모델 예측지표입니다. 자세한 사항은 [이곳]

 


 

 

일단 테스트 데이터를 다운로드 합니다. 

 

다운로드한 데이터 파일을 읽은 후 인덱스와 칼럼명을 삭제하고 ratings_noh.csv로 저장합니다.

ratings = pd.read_csv(r'C:\Users\ratings.csv')
ratings.to_csv('C:\\Users\\ratings_noh.csv', index=False, header=False)

 

 

이 ratings_noh.csv를 DataSet에 적용하기 위해 load_from_file()을 이용합니다. 이 작동을 하기 전 Reader클래스를 이용해 데이터 파일의 파싱 포맷을 정의해야 합니다. Reader 클래스는 로딩될 ratings_noh.csv 파일의 파싱 정보를 알려주기 위해 사용됩니다. Reader클래스의 생성자에 각 필드의 칼럼명과 칼럼 분리분자, 그리고 최소~최대 평점을 입력해 객체를 생성하고, load_from_file()로 생성된 Reader객체를 참조해 데이터 파일을 파싱 하면서 로딩합니다. 

 

from surprise import Reader, Dataset
reader = Reader(line_format='user item rating timestamp', sep=',', rating_scale=(0.5, 5))
data = Dataset.load_from_file(r'C:\\Users\\ratings_noh.csv', reader=reader)

 

위의 내용은 Reader 객체 생성 시에 line_format 인자로 4개의 칼럼으로 데이터가 구성돼 있음을 명시했고, 각 칼럼의 분리 문자는 콤마, 평점의 단위는 0.5, 최대 평점은 5점으로 설정했습니다.

 

이제 SVD행렬 분해 기법을 이용해 추천을 예측해 보겠습니다. 잠재 요인 크기 K값을 나타내는 파라미터 n_factors를 50으로 설정해 데이터를 학습한 뒤에 테스트 데이터 세트를 적용해 예측 평점을 구한 후 예측 평점과 실제 평점 데이터를 RMSE로 평가하겠습니다.

 

trainset, testset = train_test_split(data, test_size=.25, random_state=0)
algo = SVD(n_factors=50, random_state=0)
algo.fit(trainset)
predictions = algo.test(testset)
accuracy.rmse(predictions)

→ RMSE: 0.8028


교차 검증과 하이퍼 파라미터 튜닝과 관련하여 surprise는 사이킷런과 유사한 cross_validate()와 GridSearchCV클래스를 제공합니다.  cross_validate() 함수는 교차 검증을 위한 함수이며 사용법은 다음과 같습니다.

 

다음 예제에서는 cross_validate()를 이용해 ratings.csv를 DataFrame으로 로딩한 데이터를 5개의 학습/검증 Fold 데이터 세트로 분리해 교차 검증을 수행하고 RMSE, MAE로 성능 평가를 진행합니다.

 

 

from surprise.model_selection import cross_validate
ratings = pd.read_csv(r'C:\\Users\\HANA\\Downloads\\ml-latest-small\\ratings.csv')
reader = Reader(rating_scale=(0.5, 5.0))
data = Dataset.load_from_df(ratings[['userId', 'movieId', 'rating']], reader)

algo = SVD(random_state=0)
cross_validate(algo, data, measures=['RMSE', 'MAE'], cv=5, verbose=True)

 

 

surprise의 GridSearchCV도 사이킷런의 GridSearchCV와 유사하게 교차 검증을 통한 하이퍼 파라미터 최적화를 수행합니다. 하이퍼 파라미터 최적화는 알고리즘 유형에 따라 다를 수 있지만, SVD의 경우 주로 점진적 하강법 (Stochastic Gradient Descnt)의 반복 횟수를 지정하는 n_pochs와 SVD의 잠재 요인 K의 크기를 지정하는 n_facor를 튜닝합니다. 

 

 

from surprise.model_selection import GridSearchCV
param_grid = {'n_epochs': [20,40,60], 'n_factors': [50,100,200]}
gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mse'], cv=3)
gs.fit(data)
print(gs.best_score['rmse'])
print(gs.best_params['rmse'])

n_epochs가 20, n_factors가 50일 때 RMSE가 0.877로 가장 좋은 값이 도출됩니다. 

 

 

다음 시간은 프로그램을 실제로 만들어 보겠습니다.

반응형