Backend
💻

상품 정보와 리뷰 기반 컨텐츠 필터링 추천 시스템

Django - Musinsa Topic Based Clothes Recommendation

추천시스템 2조.pdf
5701.9KB

개요 및 소개

개요
리뷰 기반 토픽 모델링 + 이미지 기반 추천 시스템
상품 정보 + 리뷰데이터(토픽 모델링) + 상품 이미지를 활용한 추천시스템 개발
총 상품 8745개
프로젝트 소개
파이썬 기반의 웹 프레임워크인 ‘Django’를 활용하여 의류 쇼핑 플랫폼 '무신사'에서 직접 크롤링한 ‘패션 데이터’를 이용한 컨텐츠 기반 의류 추천 서비스를 만들었습니다. 데이터 수집에는 fastapi를 이용하여 수집 API를 만들어 활용했습니다. 수집할 데이터가 많아 비동기적으로 의류 데이터를 scraping하여 CSV로 변환하여 저장하였습니다. 모델링에 사용되는 데이터가 30만 건 이상이므로 의류 카테고리 별로 수집 API를 병렬적으로 실행시켜 적재했습니다. 이후 병합한 CSV와 pandas를 활용하여 추천 시스템 모델링을 진행했습니다.
EDA를 거쳐 서비스에 필요한 데이터만을 추출하여 SQLite로 저장하고, pandas를 이용하여 Django 내부에서 학습시킨 모델을 활용하여 프로젝트를 진행했습니다. 상품 메타 정보와 리뷰 데이터, 상품의 이미지 유사도 정보를 이용하여 컨텐츠 유사도 기반 추천 시스템을 만들었습니다.
해당 추천 시스템을 만들어낼 때, 상품 정보와 리뷰 데이터를 이용하여 Word2vec을 학습하였고, 원하는 토픽 키워드와 아이템 간의 유사도를 계산하여 컨텐츠 유사도 기반 추천 시스템을 만들어냈습니다. 하지만 리뷰 데이터를 비롯한 상품의 텍스트 데이터 만으로는 추천 성능에 한계가 발생하였습니다. 이때, 콘텐츠 기반 추천 성능을 높이기 위하여 VGG16을 통해 이미지의 Feature을 추출한 후, 상품의 이미지 유사도 정보를 이용하여 성능을 보완하는 CBIR(Content-based image retrieval)을 사용하였습니다. 이를 통해 텍스트로는 표현하기 어려운 상품의 형태, 색상 등의 특징을 사전훈련된 딥러닝 모델을 통해 추출하여 저희 추천 시스템에 추가하여 성능을 보완하였습니다. 이를 통해, 이전보다 키워드와 유사한 상품을 찾을 수 있게 되었습니다.
또한, 추천된 서비스를 다시 SQLite에 적재하여 향후 사용자 추천 경향을 분석할 수 있도록 구성했습니다.

프로젝트 진행 사항

KoBERT를 이용한 코디 분류를 통한 결측치 보완

Korean BERT (Bidirectional Encoder Representations from Transformers)
KoBERT는 SKTBrain에서 기존 BERT의 한국어 성능 한계를 극복하기 위해 개발
위키피디아나 뉴스 등에서 수집한 수백만 개의 한국어 문장으로 이루어진 대규모말뭉치(corpus)를 학습하였으며, 한국어의 불규칙한 언어 변화의 특성을 반영하기 위해 데이터 기반 토큰화(Tokenization) 기법을 적용하여 기존 대비 27%의 토큰만으로 2.6% 이상의 성능 향상을 이끌어 낸 BERT 모델.
많은 BERT 모델 중에서도 KoBERT를 사용한 이유는 "한국어"에 대해 많은 사전 학습이 이루어져 있고, 감정을 분석할 때, 긍정과 부정만으로 분류하는 것이 아닌 다중 분류가 가능한 것이 강점이기 때문입니다.
데이터를 전처리를 하던 와중 데이터 내 코디(coordi) 칼럼에 결측치가 많이 존재하는 것을 발견하였습니다 ⇒ 5477개 (25360개의 상품 리뷰 데이터 중)
상품, 리뷰 데이터 기반으로 KoBERT 모델 학습을 진행하여 코디 분류 모델을 만들어 해당 모델을 이용하여 코디 결측치를 채우기로 하였습니다.
input data : name(상품 이름), review data(리뷰 데이터), tags(상품 태그 목록), 코디(coordi)
(25360, )
predict target : coordi(코디)
⇒ '스트릿', '캐주얼', '스포츠', '걸리시', '아메리칸 캐주얼', '포멀', '댄디', '시크', '로맨틱', '레트로', '홈웨어', '골프' ⇒ 총 12개의 클래스
train / test data set ⇒ coordi 값이 존재하는 데이터 (19883, 6)
applying data set ⇒ coordi가 결측치인 데이터 (5477, 6)
epoch
train accuracy
test accuracy
5
0.84
0.765
10
0.97
0.835
10 epoch을 돌려서 진행하였습니다.
그 이후부터는 성능의 향상이 유의미해보이지 않았습니다.
predict 결과(단일 열벡터) 중 값이 최대인 행(argmax)을 예측되는 라벨로 정의.
아래와 같은 방법으로 결측값을 채웠습니다.

Word2vec 학습

학습할 코퍼스 만들기
리뷰 데이터
아이템 정보들(상품명, 카테고리, 브랜드명, 상품 이름을 구성하는 단어들)
코디, 태그
데이터 사이즈가 크지 않기 때문에 Vocab 사이즈가 작아 Out of Vocabulary (OOV) 문제가 발생
이를 방지하기 위해 위와 같이 구성
데이터 사이즈가 크지 않기 때문에 word2vec 은닉층 사이즈는 50으로 설정.
skip gram을 채택, window 사이즈가 작을 수록 미세하게 우세하다는 논문을 참고하였습니다 (window = 5)
중심 단어 이웃에 포함되지 않는 단어 (negative sample)은 20개로 설정
통상적으로 주변 단어 + 10~20개를 선택한다고 합니다.
아래의 공식을 적용하면 조금 더 적합한 숫자를 이끌어낼 수 있습니다.

토픽 모델링

토픽 추천 시스템 로직

아이템을 추천해주는 함수를 구성하였습니다.
유사도 로직 = Cosine Similarity
모든 벡터는 word2vec 모델을 통해 산출된 수치 벡터입니다.
아이템 유사도 벡터 * 아이템 유사도 벡터
cosine_similarity(전체 아이템 열 벡터, 전체 아이템 열 벡터)
⇒ item마다 모든 item들에 관한 유사도 벡터 생성
(8745 * 8745)
키워드(Input string) 벡터 * 아이템 유사도 벡터
(8745, )
1. 리뷰를 토대로 토픽 모델링을 거쳐 나온 토픽들을 키워드로 입력
2.
키워드를 인풋으로 넣었을 때 해당 키워드와 아이템들 간 유사도를 계산한 후 키워드와 유사성이 높은 순서대로 정렬
3.
아이템간 유사도를 이용하여 키워드와 유사도가 제일 높은 아이템과 가장 유사한 아이템들을 가져온다.

Word2vec + CNN(VGG16) 추천

토픽 모델링과 동일한 word2vec 모델 사용
1.
키워드를 인풋으로 넣었을 때 해당 키워드와 아이템들 간 유사도를 계산한 후
키워드와 유사성이 높은 순서대로 정렬
2.
키워드와 유사성이 높은 상품 상위 3가지를 가져옵니다.
3.
아이템마다 vgg16으로 feature를 추출한 정보를 바탕으로 이미지 벡터 유사도가 높은 상품 2000개씩 가져와 교집합에 속하는 상품들을 추출합니다
4.
해당 상품들에 대한 정보를 가져와 키워드와의 코사인 유사도를 기준으로 내림차순 정렬합니다.
5.
보고 싶은 아이템의 개수만큼 슬라이싱합니다. (Top-n)
6.
슬라이싱한 데이터를 보완한 가중 평점으로 내림차순 정렬하여 사용자에게 보여줍니다.

추천 결과

추천되는 항목들의 사진, 상품명, 리뷰, 가격을 정리해서 카드 형태로 보여줬습니다.
그리고 추천되는 상품 리뷰들에 기반하여 워드 클라우드를 시각화해보았습니다.

보완 가능성

토픽 추천 시 리뷰에 관련된 긍정, 부정 수치를 넣어서 볼 수 있게 했다면 더 좋았을 것 같습니다.
상품이 추천되었을 때 해당 상품이 키워드와 관련해서 긍정인지, 부정인지 알 수 있다면 더 좋은 추천 성능을 보장할 수 있어 보입니다.