Skip to content

사용자의 취향에 따라 서울 내의 데이트 코스를 추천해주는 앱

Notifications You must be signed in to change notification settings

DAC-KHUPID/seoul-date-course-recommendation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

데이트 마이닝: 빅데이터 기반 서울 데이트 코스 추천 알고리즘

Flowchart

Introduction

Needs

    빅데이터 기반의 추천 시스템은 오래 전부터 연구되어왔고, 유튜브, 넷플릭스, 왓챠 등 미디어 플랫폼과 인터넷 쇼핑몰에서 좋은 성능을 발휘했으나, 현재 시장에 출시된 데이트 명소를 추천해주는 애플리케이션은 수요가 높음에도 불구하고 빅데이터 기반의 추천 알고리즘을 사용하지 않고 있음을 발견했다. 따라서 본 프로젝트에서는 머신러닝을 통해 사용자의 취향을 분석하고 이를 통해 데이트 코스를 추천해주는 알고리즘을 개발한다. 이 알고리즘은 데이트 코스를 결정하는 데에 어려움을 겪었던 커플들에게 도움을 줄 것이며, 랜덤 데이트 코스라는 재미 요소도 줄 수 있을 것이다.

Goals

  • 정성적 목표
    이 프로젝트의 최종 결과물은 데이트 취향과 위치를 고려한 데이트 코스 추천 알고리즘이며 데이트 코스에는 사용자의 취향에 맞춘 맛집/카페, 데이트 명소(유명 방문지, 보드게임 카페, 볼링장, 방탈출 카페 등등), 영화가 포함되어 있다. 또한 데이트를 하고자 하는 지역구를 선택한다면, 이에 대한 코스 필터링 기능을 제공하는 것 또한 최종 결과물에 포함되도록 한다.

  • 정량적 목표
    정형화된 데이터 셋이 아닌 점과 선행 연구에 대한 오픈소스 프로젝트가 없는 관계로, 선행 연구와 비교한 정량적 목표 설정은 무리가 있다는 점을 인지하였다. 따라서 표본을 모집 후 만족도를 조사하여 MOS 기법을 바탕으로 만족도를 조사하는 것을 대체 방안으로 채택하였다. 테스터들은 구글 설문지를 통해 몇가지 문항들에 답변한 후, 메일로 알고리즘이 추천한 데이트 코스 결과를 받고 이후 다시 메일에 첨부된 만족도 조사에 답하게 된다. 만족도 조사는 알고리즘이 추천한 코스에 대한 만족도를 묻는 총 1개의 문항으로, 1점 '매우 불만족한다' 부터 시작하여 5점 '매우 만족한다까지'로 구분하여 응답을 받는다.

Packages

본 프로젝트에서는 다음과 같은 패키지를 활용하였다.

Table of contents

  1. Introduction
  2. Data crawling
  3. Data preprocessing
  4. Review clustering
  5. Modeling
  6. Results
  7. Limitations
  8. Conclusion

Data crawling

데이터 크롤링은 각각 맛집/카페(이하 EAT), 데이트 명소(이하 GO), 영화(이하 WATCH)로 구분하여 카테고리별로 진행하였으며 각 카테고리별로 크롤링을 위해 이용한 플랫폼은 아래와 같다.

Eat

mango_plate dining_code
  • 망고 플레이트 (장소 및 리뷰 데이터)
  • 다이닝 코드 (장소 및 리뷰 데이터)

Go

korea_tour trip_advisor kakao_map
  • 대한민국 구석구석 (장소 정보 데이터)
  • TripAdvisor (대한민국 구석구석에서 수집한 장소에 대한 리뷰 데이터)
  • 카카오맵 (장소 및 리뷰 데이터)

Watch

watcha_play naver_movie
  • 왓챠 플레이
  • 네이버 영화

Data preprocessing

  • Review translation
    기존에 수집한 한글 리뷰 데이터는 불용어처리에 시간이 많이 소요되고 또한 한글의 특수성으로 인해 형용사/느낌만을 추출하는데에 어려움을 느꼈고 결과적으로 클러스터링의 성능도 저하됨을한계점으로 파악하였다. 따라서 수집한 한글 리뷰 데이터를 pypapago 라이브러리를 사용해 영어로 변환하는 작업을 수행했다.

  • Review tokenizing
    NLTK 라이브러리를 사용하여 리뷰 문장에서 형용사들을 추출하고 불용어를 제거하는 작업을 수행한다. 이때 tokenizing한 리뷰 내의 형용사들은 이후 review clustering 단계에 인풋으로 사용된다.

Review clustering

Word2Vec을 사용하여 앞선 tokenizing 단계에서 추출해낸 형용사를 300차원의 벡터로 변형한 후, K-means 알고리즘을 사용해 클러스터링 작업을 수행했다. 각 카테고리별 클러스터링 결과는 아래의 링크에서 볼 수 있다.

Modeling

Contents Based Filtering

user_matrix user matrix example item_matrix item matrix example
  • 모델 설명
    위에서 생성한 matrix를 통해 각 user row와 각 item row를 vector로 보고 두 vector의 유사도를 구하는 방식으로 CBF score를 도출했다. 여기서 vector size는 각 분야별 word cluster의 개수 이다. 유사도를 구하는 방법으로는 가장 많이 쓰이는 cosine similarity를 이용했다. 각 카테고리별 User, Item Matrix는 아래 링크된 파일을 통해 볼 수 있다.

Neural Collaborative Filtering

NCF_flowchart
  • 모델 설명
    NCF는 기존의 collaborative filtering 기법과는 달리 DNN 적용을 통해 implicit feedback을 사용하기 위함으로, 크게 ‘GMF(Generalized Matrix Factorization)’과 ‘MLP(Multi-Layer Perceptron)’파트로 나뉘어져 있다.
    본 프로젝트에서는 PreferredAI에서 개발한 corncac 패키지를 이용해 NCF 모델을 구현하였다. 모델에 들어가는 input은 [(userID, ItemID, rating), …]과 같이 유저가 각 아이템에 남긴 평점이 튜플형으로 묶여있는 값들이 들어간 리스트이며, output으로는 유저가 경험하지 않은 다른 아이템들에 대해서 추후에 해당 아이템을 소비할 가능성을 0부터 1사이의 수로 예측한 값이다.

  • FineTuning

batch size learning rate number of epochs number of factors
EAT 512 0.0057864483 50 8
GO 512 0.0022595564 50 4
WATCH 128 0.0075019904 100 8

NCF모델의 hyper parameter는 Random Search를 이용해 구했고, early stopping기법 patience값을 5로 주어 분야별 최적 파라미터를 위의 표와 같이 구하게 되었다.

  • 최종 모델 성능
F1@10 NDCG@10 Precision@10 Recall@10 Train(s) Test(s)
EAT 0.0149 0.0313 0.0097 0.0540 14024.7585 11.2788
GO 0.0970 0.2482 0.0556 0.4532 3795.3764 2.3491
WATCH 0.0150 0.0283 0.0098 0.0535 4831.9023 1.0951

참고한 논문에서는 NDCG@10가 평균적으로 약 0.43 정도였으며 마이크로소프트가 NCF 논문을 재구성한 라이브러리 예시로 제시한 결과 값에서는 NDCG@10가 0.198938였다는 점을 고려했을때 GO의 경우 논문보다는 낮고 라이브러리 예시보다는 높은 점수를, EAT과 WATCH는 전체적으로 모델 자체의 성능이 낮았다는 아쉬움이 남는다. 위와 같은 결과에 대한 원인으로 EAT과 WATCH에서는 리뷰의 갯수가 적은 유저가 많기 때문인 것으로 예상하였다. 이와 같은 한계점은 직접 플랫폼을 운영하는 서비스가 구축되어 데이터 문제가 해결된다면, 어느정도 극복할 수 있을 것이라 예상된다.

Hybird Method

hybrid

CBF 모델과 NCF 모델의 결과값을 결합하는 방식으로 최종 prediction score를 도출한다. 이때 최종 score는 두 모델의 score를 단순 곱하는 식으로 사용했다.
이때 결합 방식을 산술평균, 조화평균으로도 생각해보았지만 이는 다른 한 모델이 낮게 예측한 item을 추천해주는 상황을 야기했다. 따라서 단순 곱을 통해 두 모델이 모두 높은 점수를 낸 item을 추천하도록 했다.

Results

Result

최종적으로는 UserID를 인풋으로 입력하면 추천할만한 데이트 코스를 두가지 추천해주는 것으로 알고리즘이 종료된다.

  • code
def main():
    u_id = input('Enter User ID: ')
    go = Go_recommendation(u_id)
    eat = Eat_recommendation(u_id)
    watch = Watch_recommendation(u_id)
    result = Search_Recommendable_Places(eat, go, u_id)
    if len(result) == 2:
        eat_result = result[0]
        go_result = result[1]
        print(f'{u_id}님께 추천드릴 맛집은 {eat_result["district"]}에 위치한 {eat_result["name"]}입니다.')
        print(f'{u_id}님께 추천드릴 데이트 장소는 {go_result["district"]}에 위치한 {go_result["p_name"]}입니다.')

    elif len(result) == 4:
        eat_result1 = result[0]
        go_result1 = result[1]
        eat_result2 = result[2]
        go_result2 = result[3]
        print(f'{u_id}님! {eat_result1["district"]}에서의 데이트를 계획하고 계신가요?')
        print(f'{u_id}님께 추천드릴 맛집은 {eat_result1["district"]}에 위치한 {eat_result1["name"]}입니다.')
        print(f'{u_id}님께 추천드릴 데이트 장소는 {go_result1["district"]}에 위치한 {go_result1["p_name"]}입니다.')
        print(f'혹시나! {eat_result2["district"]}에서의 데이트를 계획하고 계신다면?')
        print(f'맛집으로는 {eat_result2["district"]}에 위치한 {eat_result2["name"]}와 ')
        print(f'데이트 장소로는 {go_result2["district"]}에 위치한 {go_result2["p_name"]}을(를) 추천드려요.')
        
    print(f'영화가 끌리는 데이트라면 현재 상영중인 영화 {watch}은(는) 어떠신가요?')

Limitations

Limitations

    이번 프로젝트는 모델들의 결함을 서로 보충하여 hybrid model을 직접 구축하는 단계로 진행하였다. 실제로 Contents based filtering과 Neural Collaborating filtering의 결과를 조합하는 과정에서 한쪽 모델만 높게 예측한 아이템이 아닌 두 모델 모두 예측값이 좋은 아이템을 찾는 데에 비중을 두게 되었다. 그 과정에서 적절한 조합 방법을 찾지 못했고 단순히 두 값을 곱하는 방법을 사용했으며 결과적으로 최종 result의 prediction값이 낮아졌다는 점이 이 프로젝트의 한계점으로 남는다.

Conclusion

    이번 프로젝트에서는 서울 내의 맛집/카페, 데이트 명소, 영화를 모두 포함한 데이트 코스 추천 알고리즘을 기획하고 개발하였다. 단일 장소에 대한 추천을 넘어 각 장소들을 조합하여(필터링 등) 데이트 코스로 추천해주었다는 점에 의의가 있으며 위와 같은 결과를 도출하기 위해 어떤 추천 알고리즘을 사용해야 이 주제에서 가장 적합한 추천을 할 수 있을지에 대한 고민을 통해 다양한 추천 알고리즘의 특성 및 활용 방법을 익힐 수 있었다. 또한 최종 추천을 위해 사용되는 자연어 처리/형용사 추출, 형용사 embedding, vector clustering/clustering distance, data normalization, vector 유사도 측정에 대해서도 각각 어떤 방법론들이 있고 어떤 상황에서 사용해야 하는지 등을 찾아보면서 진행했다. 분석에 적합한 방법들에 대해 성능 평가를 동시에 진행하며 최종적인 알고리즘을 완성할 수 있었다.
    결과적으로 이번 프로젝트를 통해 추천 시스템의 A-Z를 직접 구현해봄으로써 추천 알고리즘이 어떻게 동작하는지 잘 이해할 수 있었다. 다만, 적용한 추천 알고리즘의 논문이나 내부 로직을 100% 이해하지 못했다는 아쉬움이 있으며, 더 세부적인 논문 이해를 통해 모델링을 정교화한다면 더 좋은 결과를 도출할 수도 있을 것이라 생각하였다.

Project Schedule

Contents March April May June
1. 데이터 수집 ✔️
2. 데이터 형식 통합 ✔️
3. 리뷰 데이터 자연어 처리 ✔️
4. 장소별 형용사 데이터 셋 생성 ✔️
5. 유저별 형용사 데이터 셋 생성 ✔️
6. Contents Based Filtering(User, Item based) ✔️
7. Neural Collaborative Filtering ✔️
8. 1차 최종 알고리즘 모델링 ✔️
9. 최종 알고리즘 모델링 ✔️
10. 테스트용 구글 폼 제작 ✔️
11. 표본을 대상으로 만족도 조사 시행 ✔️

References

Reports

Contributors

Roles

주차 이름 추진내용
2주차(3월 27일) 김동혁 - 1차 프로젝트 제안서(3.기대효과 및 활용방안, 4. 수행방법 일부) 작성
- 맛집/카페 : 수집 가능한 플랫폼 탐색
류연주 - 1차 프로젝트 제안서(2. 과제 목표, 4. 수행방법 일부) 작성, 최종 취합
- 데이트 명소: 수집 가능한 데이터 탐색
유정수 - 1차 프로젝트 제안서(1. 과제 개요, 4. 수행방법 일부) 작성
- 전시/영화 : 수집 가능한 데이터 탐색
3주차(4월 3일) 김동혁 - 맛집/카페 : 망고플레이트를 통해 기본 데이터 및 리뷰 수집
류연주 - 데이트 명소 : 대한민국 구석구석(장소 데이터), TripAdvisor(리뷰 데이터) 크롤링 작업 시작
유정수 - 전시/영화 : 왓챠를 통한 영화 데이터 및 리뷰 크롤링
4주차(4월 10일) 김동혁 - 맛집/카페 : 망고플레이트, 다이닝코드에서 데이터 크롤링
- clustering distance에 대한 research
류연주 - 데이트 명소 : 대한민국 구석구석(장소 데이터), TripAdvisor(리뷰 데이터) 크롤링 작업 완료
유정수 - 전시/영화 : 왓챠, 네이버영화에서 데이터 크롤링
5주차(4월 17일) 김동혁 - 맛집/카페 : data 부족으로 인한 추가 크롤링
- 맛집/카페 : okt 패키지를 이용한 한글 형태소 분석
류연주 - 데이트 명소 : Kakao Map 장소/리뷰 데이터 크롤링
유정수 -전시/영화 : 오픈갤러리에서 전시 데이터 크롤링, 네이버 카페에서 전시 리뷰 데이터 크롤링
6주차(4월 24일) 김동혁 - 맛집/카페 : 한글 리뷰에서 형용사 추출
- 한글 기반 Fast-Text로 임베딩 연구
류연주 - 리뷰 자연어 처리를 위한 불용어 사전 구축 (한글)
- Papago로 데이트 명소 리뷰 데이터 번역 후 tokenizing 테스트
유정수 - 전시/영화 : 한글 리뷰에서 형용사 추출
- 단순 형용사 추출 방법과 리뷰를 중요 문장으로 요약 후 형용사 추출 방법에 대해 연구
7주차(5월 1일) 김동혁 - word embedding에서의 CBOW와 SKIPGRAM에 대한 research
- 맛집/카페: 데이터 통합 형식으로 변형
류연주 - 데이트 명소: Kakao Map 데이터 크롤링 완료, 리뷰 및 장소 데이터를 통합 형식으로 변형
- 리뷰 자연어 처리를 Fast-Text 기법 + Papago로 변형한 리뷰데이터로 진행
유정수 - 전시/영화 : 크롤링 완료 후 데이터 통합 형식으로 변형
- 번역하지 않은 데이터를 Fast-Text 기법을 사용해 embedding
8주차(5월 8일) 김동혁 - 맛집/카페: 리뷰 영어로 번역
- GMM, Affinity Propagation, Spectral 등 clustering 적용 시도
류연주 - 리뷰 자연어 처리 Word2Vec, BERT, ELMO, GLoVe research
- 데이트 명소: Word2Vec 적용 및 Fast-text와 비교
- 데이트 명소: Kmeans, DBSCAN, GMM 클러스터링 기법 적용
유정수 - 전시/영화: 전시 리뷰 데이터 부족으로 추가 탐색
- 전시/영화: 한글 데이터에 대해 Word2Vec, Fast-text 적용 및 비교
-embedding한 vector 클러스터링 진행(K-means, K-medoids, DBSCAN)
9주차(5월 15일) 김동혁 - Collaborative Filtering에서 Matrix Factorization에 대한 research
류연주 - 데이트 명소: 카카오/트립어드바이저 모든 리뷰 Papago api 사용하여 영어로 번역
- 데이트 명소: User matrix, Item matrix 생성
유정수 - 전시/영화: Papago api를 사용하여 모든 리뷰 데이터 번역
- 전시/영화: User matrix, Item matrix 생성
10주차(5월 22일) 김동혁 - Neural Collaborative Filtering 논문에 제시된 코드 연구
류연주 - 데이트 명소: 카카오/트립어드바이저 모든 리뷰 api 사용하여 영어로 번역
- 데이트 명소: User matrix, Item matrix 생성
유정수 - NCF 논문 리뷰 및 적용 방안 제시
- 영화: User matrix, Item matrix 생성
11주차(5월 29일) 김동혁 - 맛집/카페 : NCF 모델 적용
- 추천시스템 성능 평가방법 research
류연주 - NCF모델 적용 방향 수정, Hybrid method research
- 데이트 명소: NCF 모델 적용 (Microsoft 라이브러리)
유정수 - Hybrid method 적용 방법 연구 및 라이브러리 탐색
- 영화: Cornac 라이브러리 내부 로직 연구 및 NCF 모델 적용
12주차(6월 5일) 김동혁 - NCF를 이용한 라이브러리 검색 및 각 장단점 파악
- User Matrix * Item Matrix cosine similarity 방식 테스트
류연주 - User Matrix * Item Matrix 단순 행렬곱 적용 방식 테스트
- Data Normalization 방식 research
유정수 - 벡터의 유사도 측정 방법 research
- User Matrix * Item Matrix 단순 행렬곱 적용 방식 테스트
13주차(6월 12일) 김동혁 - 프로젝트 Flow chart 생성
-  맛집/카페 : Matrix Data Normalization
류연주 - 데이트 명소: 형용사 word-cluster 라벨링, 조사 문항에 넣을 20개 대표 형용사 선정
-  데이트 명소 : Matrix Data Normalization
유정수 - 영화: cosine similarity 방식으로 변경 후 Matrix Data Normalization
14주차(6월 19일) 김동혁 - 테스터들에게 보낼 설문지 중, 1) 형용사에 대해 느끼는 호감도 정도 문항 및 3) 지역구 선택 작성
- 맛집/카페 : 최종 모델 완성
- Random Search를 통한 NCF  hyper parameter tuning
류연주 - 테스터들에게 보낼 설문지 중, 2-2) 데이트 명소 문항 작성
- 맛집/카페, 데이트 명소, 영화 데이터를 조합한 최종 알고리즘 코딩
- 지역구 필터링 코딩
유정수 - 영화: 현재 상영 영화 추천을 위한 데이터 추가
- 영화: 최종 모델 완성
15주차(6월 26일) 김동혁 - 제작된 알고리즘을 python 파일 및 모듈로 제작
- 영상 촬영
류연주 - 최종 만족도 조사 방식 제안
- 만족도 설문지 작성
- 최종 발표 데모 영상 시나리오 작성 및 제작
유정수 - 최종 발표자료 준비
- 유저별 알고리즘 실행 결과 및 만족도 조사 메일 발송, 취합

Releases

No releases published

Packages

No packages published