Home 프로그래머스 인공지능 데브코스 16주차 정리 및 후기
Post
Cancel

프로그래머스 인공지능 데브코스 16주차 정리 및 후기

이번 글에서는 프로그래머스 인공지능 데브코스의 16주차 강의에 대한 정리입니다.
이 강의에서는 추천 시스템에 대하여 다루게 됩니다.


1. Recommendation System 이란?

추천 엔진의 정의

  • 사용자: 서비스를 사용하는 사람
  • 아이템: 서비스에서 판매하는 물품 (다른 사용자가 물품이 될 수도 있음 - 링크드인 등)
  • 일반적으로 서비스가 성장하면, 사용자나 아이템의 수도 같이 성장하게 됨
    • 특히, 사용자의 성장도가 훨씬 커짐
    • 하지만 아이템의 수가 커지면서 아이템의 선택에 대한 이슈가 생김
    • 모든 사용자가 능동적으로 검색하지 않고, 사람들이 추천에 대한 니즈가 생김
  • Twitter의 알파 제인의 정의: 사용자가 관심 있어 할 만한 아이템을 제공해주는 자동화 된 시스템 (관심, 자동화)
  • Yahoo의 디팍 아그라왈의 정의: 비즈니스 장기적 목표를 개선하기 위해 사용자에게 알맞은 아이템을 자동으로 보여주는 시스템 (장기적 목표, 매출액, 자동화)

추천 엔진이 필요한 이유

  • 조금의 노력으로 사용자가 관심 있어 할 만한 아이템을 찾아주는 방법
    • 아이템의 수가 굉장히 큰 경우 더 의미가 있음
    • 사람의 노다가로 해결할 수 없어 자동화가 필요함
    • 개인화 (Personalization)로 연결 될 수 있음
    • 또한 가끔씩 전혀 관심 없을 듯한 아이템도 추천 가능 (Serendipity)
  • 회사 관점에서는 추천 엔진을 기반으로 다양한 기능을 추가할 수 있음
    • 마케팅 시, 추천 엔진 사용 (이메일 마케팅)
    • 관련 상품 추천으로 쉽게 확장 할 수 있음
  • 아이템의 수가 많아서 원하는 것을 찾기 어려운 경우 (검색의 수고를 덜어줌)
  • 추천을 통해 신상품 등의 마케팅이 가능해짐 (추천을 통해 신상품 노출이 가능)
  • 인기 아이템 뿐 아니라, 롱 테일의 다양한 아이템을 노출 할 수 있음 (개인화가 알고리즘화 될 수 있음)

추천은 결국 매칭 문제

  • 사용자에게는 맞는 아이템을 매칭해주기 (아이템은 서비스에 따라 달라지고, 다른 사용자가 될 수도 있음)
  • 어떤 아이템을 추천할 것인가?
    • 지금 뜨는 아이템 추천 (개인화 되어 있지 않은 추천)
    • 사용자가 마지막에 클릭했던 아이템 추천
    • 사용자가 구매했던 아이템을 구매한 다른 사용자가 구매한 아이템 추천 (협업 필터링)
  • 추천 UI도 굉장히 중요 (보통 추천 유닛이 존재하고, 이를 어떤 순서로 노출시킬지?)
  • Cold Start 문제: 사용자의 데이터가 없는 상태에서 새로운 추천을 어떻게 해야 할까?
    • 따라서 사용자와 아이템 등에 대한 부가 정보들이 필요해짐
  • 아이템 부가 정보: 먼저 분류 체계를 만들어야 함, 태그 형태로 부가 정보를 유지하는 것도 좋음
    • 계층 구조의 분류 체계 (대분류, 소분류, 태그 및 키워드 등)
  • 사용자 프로파일 정보: 개인정보 (성별, 연령), 아이템 정보 (관심 및 서브 카테고리, 태그, 클릭, 구매 아이템)
  • 무엇을 기준으로 추천 할 것인가? 클릭? 매출? 소비? 평점?

추천 엔진 예제

  • 아마존 관련 상품 (Related Product) 추천 - 사용자: 멤버, 아이템: 상품
    • 과거 구매 이력, 인기 있는 상품들, 주기적으로 구매 할 수 있는 상품들 등이 추천되고 있음
  • 넷플릭스 영화 및 드라마 추천 - 사용자: 멤버, 아이템: 영화, 드라마
    • 격자 형태의 추천 유닛 (최근 뜨고 있는 것 기반, 과거 시청 이력 기반, 인기 Top 10 기반 추천)
  • 구글 자동 검색어 완성 - 사용자: 검색자, 아이템: 검색어
    • 타이핑을 전체 완성하지 않아도 됨, 알지 못했던 새로운 키워드로 접근 가능하다는 등의 효과
  • 링크드인 혹은 페이스북 친구 추천 - 사용자: 멤버, 아이템: 멤버
    • Industry, 지역, 학교 등과 관련 있는 사람들 추천
  • 스포티파이 혹은 판도라 노래, 플레이리스트 추천 - 사용자: 멤버, 아이템: 노래, 플레이리스트
  • 헬스케어 도메인의 위험 점수 계산 - 사용자: 의사, 간호사, 아이템: 환자
    • 어느 환자가 더 위험한지 예측하여 치료시 우선순위를 주기 위함
    • 환자 별로 발병 확률과 발병시 임팩트를 계산하여 곱하는 형태 (발병 확률을 모델링)
  • 유데미 강좌 추천 - 사용자: 멤버, 아이템: 강좌

앞서 살펴본 추천 엔진들의 공통점

  • 격자 형태의 UI 사용 (넷플릭스가 선구자)
  • 다양한 종류의 추천 유닛들이 존재함
    • 일부 유닛은 개인화 (사람에 따라 다른 아이템을 추천해줌)
    • 일부 유닛은 인기도 등의 비개인화 정보 기반 (모든 사람에게 동일한 아이템 추천)
    • 추천 유닛의 랭킹이 중요해짐
      • 이 부분도 모델링 하여 개인화 하는 추세
      • 클릭을 최적화 하고, 이 데이터 수집을 위한 실험을 수행 (데이터 수집을 위한 온라인 테스트)

추천 엔진의 종류

  • 컨텐츠 기반 (아이템 기반)
    • 개인화 된 추천은 아니고, 비슷한 아이템을 기반으로 추천이 이뤄짐
      • 책이라면, 타이틀, 저자, 책 요약, 장르 등의 정보를 사용
      • 많은 경우, NLP 테크닉을 사용하여 텍스트 정보를 벡터 정보로 변환 (단어 카운트, TF-IDF, 임베딩)
      • 구현이 상대적으로 간단 (보통 아이템의 수가 사용자의 수 보다 작음)
  • 협업 필터링 (Collaborative Filtering): 평점 기준
    • 기본적으로 다른 사용자들의 정보를 이용하여 내 취향을 예측하는 방식
      • 사용자 기반, 아이템 기반 두 종류가 존재
      • 결국은 행렬 계산으로 이뤄짐 (Sparse 행렬 형태)
      • 유사도 계산 (코사인 유사도 등)
    • 사용자 기반 (User): 나와 비슷한 평점 패턴을 보이는 사람을 찾아서 그 사람들의 평이 좋았던 것을 추천
      • 나와 비슷한 사용자를 어떻게 찾을지가 중요 (사용자 프로파일 정보 구축, 프로파일간 유사도 계산 - KNN)
    • 아이템 기반 (Item): 평점의 패턴이 비슷한 아이템들을 찾아서 그것을 추천하는 방식
      • 2001년에 아마존에서 논문으로 발표. 아이템들 간 유사도를 비교하는 것으로 시작
      • 사용자 기반 협업 필터링과 비교하여 더 안정적이며, 좋은 성능을 보임
      • 아이템의 수가 보통 작기 때문에 사용자에 비해 평점의 수가 평균적으로 많고, 계산량이 적음
      • 즉, 사용자 기반 추천에 비해, 데이터에 대한 고객들의 평점 등에 대한 데이터가 많아서 성능이 좋음
  • 사용자 행동 기반
    • 아이템 클릭, 구매, 소비 등의 정보를 기반으로 하는 추천
      • 사용자와 아이템에 대한 부가 정보가 반드시 필요함
      • 여기에 속하는 추천은 구현이 간단하긴 하지만, 아주 유용함
    • 모델링을 통해 사용자와 아이템 페어에 대한 클릭 확률 등의 점수 계산이 가능
      • 의사 결정 트리나 딥러닝 등이 사용 가능 (유데미에서 채택한 방법)
      • Batch 기반 추천, 실시간 추천인지 방식 등도 결정해야 함
  • 위 알고리즘들을 하이브리드 형태로 사용

유사도 측정 방법

  • 두 개의 비교 대상을 N차원 좌표로 표현. 사용자와 사용자 혹은 아이템과 아이템
  • 보통 코사인 유사도나 피어슨 상관계수 유사도를 사용하게 됨
    1. 두 벡터의 방향성이 비슷할수록 1에 가까운 값이 계산되는 코사인 유사도 (동일할 경우 1이 됨)
    2. 두 벡터가 반대 방향을 향하는 경우에는 -1이 계산
    3. 피어슨 유사도는 코사인 유사도의 개선 버전으로 각 벡터를 중앙 (중심)으로 재조정

협업 필터링에 대한 문제

  • Cold start 문제
    • 사용자: 아직 평점을 준 아이템이 없는 경우
    • 아이템: 아직 평점을 준 사용자가 없는 경우
    • 보통 컨텐츠 기반 혹은 사용자 행동 기반 추천과 병행하여 이 문제를 해결해나감
  • 리뷰 정보의 부족 (Sparsity) - 리뷰를 했다는 자체도 사실은 관심으로 볼 수 있음
  • 업데이트 시점 - 사용자나 아이템이 추가 될때마다 다시 계산해야 함
  • 확장성 이슈 - 사용자와 아이템의 수가 늘어나면서 행렬 계산에 시간이 오래 걸림 (Spark 같은 것이 필요해지는 이유)
  • 협업 필터링의 많은 문제들이 추천의 일반적인 문제이기도 함

협업 필터링 구현 방법

  • 메모리 기반
    • 앞서 설명한 방식 (사용자 기반, 아이템 기반)
    • 사용자간 혹은 아이템간 유사도를 미리 계산
    • 추천 요청이 오면, 유사한 사용자 혹은 아이템을 K개 뽑아서 이를 바탕으로 아이템 추천
    • 구현과 이해가 상대적으로 쉽지만, 스케일하지 않음 (평점 데이터의 부족)
  • 모델 기반
    • 넷플릭스 프라이즈 컨테스트 때 고안된 추천 방식 (아이템 행렬에서 비어 있는 평점을 SGD를 사용해서 채움)
    • 이는 보통 SVD (Singular Vector Decompostion)을 사용해서 구현 (딥러닝의 오토인코더를 사용하기도 함)
    • 평점을 포함한 다른 사용자 행동을 예측하는 방식으로 진화하고 있음
      • 주로 암시적 정보 (클릭, 구매, 소비)를 기반으로 행동을 예측하게 됨
      • 아이템 노출 - 아이템 클릭 - 아이템 구매 - 아이템 소비 (인프라 단에서 해당 데이터들 수집이 필요함)
      • 사용자 행동 기반 간단한 추천 유닛 구성
        • 사용자가 관심을 보인 특정 카테고리의 새로운 아이템, 인기 아이템 등
      • 사용자 행동을 예측하는 추천 (클릭 혹은 구매)
        • 지도 학습 문제로 접근 가능. 무엇을 학습하고, 예측하는 모델인지 먼저 생각해야 함
          • 어떤 기준으로 추천을 할까? = 머신러닝의 레이블 정보
          • 명시적 힌트: 리뷰 점수 (Rating), 좋아요 (Like)
          • 암시적 힌트: 클릭, 구매, 소비 등

2. Recommendation System 구현 1

넷플릭스 프라이즈 개요

  • 2006년부터 3년간 운영된 넷플릭스의 기념비적인 추천 엔진 경진대회
  • 넷플릭스 추천 시스템 품질을 10% 개선하는 팀에서 $1M 수여 약속 (RMSE가 평가 기준으로 사용)
  • 프라이버시 이슈도 제기 되었긴 했지만, 넷플릭스 브랜드 인지도도 올라감
  • 이를 기폭제로 캐글과 같은 머신러닝 경진대회 플랫폼이 등장
  • 이 대회를 통해서 협업 필터링이 한 단계 발전하게 되었음
    • SVD를 활용한 SVD++는 이후 굉장히 많은 분야에서 활용됨
    • 앙상블 방식의 모델들이 가장 좋은 성능을 보이게 됨 (하지만 실행시간이 너무 길어서, 실제로는 사용 불가)
      • 앙상블과 랜덤포레스트: 다수의 분류기를 사용해서 예측하는 방식
      • 성능이 좋긴 하지만, 훈련과 예측 시간이 오래 걸린다는 단점이 있음
    • 다양한 알고리즘들이 논문으로 학회에서 발표됨 (SVD++ 포함)

추천 엔진의 발전 역사

  • 2001년 아마존이 아이템 기반 협업 필터링 논문 발표
  • 2006년 ~ 2009년 넷플릭스 프라이즈
    • SVD를 이용한 사용자의 아이템 평점 예측 알고리즘 탄생
    • 앙상블 알고리즘의 보편화
    • 딥러닝의 일종이라고 할 수 있는 RBM (Restricted Boltzman Machine)이 단일 모델로 최고 성능을 보임
    • 딥러닝이 추천의 분야에서 사용 가능성을 보이게 됨
  • 2010년 딥러닝이 컨텐츠 기반 음악 추천에 사용되기 시작
  • 2016년 딥러닝을 기반으로 한 추천이 활기를 띠기 시작
    • 오토인코더 기반으로 복잡한 행렬 계산을 단순화 하는 방식이 하나
    • 아이템 관련 사용자 정보를 시간 순으로 인코드 하는 RNN을 사용하는 방식이 다른 방식
    • 아마존에서 DSSNTE 라는 알고리즘을 오픈소스화 했다가 나중에 SageMaker 라는 제품으로 통합

유데미 추천 살펴보기

  • 문제 정의: 학생들에게 관심 있을만한 강의를 먼저 보여주는 것
  • 추천 UI - 격자 기반 UI, 다양한 추천 유닛들이 존재 (유닛 선택과 랭킹이 필요함)
  • 온라인 강의 메타 데이터 - 분류 체계, 태그, 클릭 키워드 분석 등
  • 다양한 행동 기반 추천 - 클릭, 구매, 소비 등

인기도 기반 추천 유닛 개발

  • 인기도 기반 추천은 Cold start 이슈가 존재하지 않음
  • 그렇다면, 인기도의 기준은? 평점? 매출? 최대 판매?
  • 사용자 정보에 따라 확장 가능 (서울 지역 인기 아이템 추천 등)
  • 단, 개인화는 되어 있지 않음 (어느 정도는 가능함)
  • 아이템의 분류 체계 정보 존재 여부에 따라 쉽게 확장 가능 (특정 카테고리에서의 인기 아이템 추천)
  • 인기도를 다른 기준으로 바꿔서 다양한 추천 유닛 생성 가능 (Top course, Newest course 등)
  • Cold start 이슈가 없는 추천 유닛 (현재 사용자들이 구매한 아이템, 사용자들이 보고 있는 아이템 등)

유사도 측정 (코사인 및 피어슨 유사도)

  • 벡터들 사이에 유사도를 판단
  • 코사인 유사도: N차원 공간에 있는 두 개의 벡터 간의 각도 (원점에서)를 보고서 유사도를 판단하는 기준
  • 평점처럼 방향 뿐 아니라, 벡터 크기의 정규화도 중요하면, 피어슨 유사도를 사용하게 됨 (코사인 유사도의 개선판)
    • 먼저 벡터 A와 B의 값들을 보정
    • 각 벡터 내 셀들의 평균값들을 구한 뒤, 평균값을 각 셀에서 빼줌
    • 예를 들면, A = {3, 4, 5} 라면, 평균값은 4이고, 보정 후에는 {-1, 0, 1}이 됨
    • 그 이후 계산은 코사인 유사도와 동일함. 이를 중앙 코사인 유사도 혹은 보정된 코사인 유사도라고 부름
    • 이를 통해 모든 벡터가 원점을 중심으로 이동하고, 벡터 간 비교가 더 쉬워짐 (정규화 효과)

TF-IDF 소개와 실습

  • 텍스트를 행렬 (벡터)로 표현하는 방법
  • 텍스트 문서를 행렬로 표현하는 방법은 여러 가지가 존재함
    • 기본적으로 일단 단어를 행렬의 차원으로 표현해야 함
    • Bag of Words 방식은 문서들에 나타나는 단어 수가 N개이면, N차원으로 문서를 표현
      • 딥러닝의 워드임베딩 사용시, 차원 수도 축소되고, 공간 상에서 비슷한 단어끼리 가깝게 위치
  • One Hot Encoding + Bag of Words (카운트) - 단어의 수를 카운트해서 표현함
    • 가장 먼저는 Stopwords를 제거함 (the, is, in, we, can, see 등)
    • 그 뒤 단어의 수를 계산함 (sky, blue, sun, bright, shining 5개)
    • 단어 별로 차원을 배정 (sky = 1, blue = 2, sun = 3, bright = 4, shining = 5)
  • One Hot Encoding + Bag of Words (TF-IDF) - 단어의 값을 TF-IDF 알고리즘으로 계산된 값으로 표현

  • CountVectorizer 소개
    • 앞서 Bag of Words 카운팅 방식을 구현한 모듈
    • 벡터로 표현이 되면, 문서들 간의 유사도 측정이 가능함
  • TF-IDF 소개
    • 앞서 카운트 방식은 자주 나오는 단어가 높은 가중치를 가지게 됨
    • 하지만 TF-IDF는 한 문서에서 중요한 단어를 카운트가 아닌 문서군 전체를 보고 판단함
    • 어떤 단어가 한 문서에서 자주 나오면 중요하지만, 이 단어가 다른 문서들에서 자주 나오지 않으면 더 중요할 것
    • TF-IDF = TF(t, d) * IDF(t)
      • TF(t, d): 단어 t가 문서 d에서 몇 번 나왔는가?
      • DF(t): 단어 t가 전체 문서군에서 몇 번 나왔는가?
      • IDF(t): 앞서 DF(t)의 역비율
        • 단어 t가 전체 문서들 중에서 몇 개의 문서에서 나왔는지? 이 비율을 역으로 계산한 것이 IDF
        • In(N/DF): N은 총 문서 수를 나타내고, DF는 단어가 나온 문서를 뜻함
1
2
3
4
5
6
7
8
9
10
11
12
### CountVectorizer 코드화
from sklearn.feature_extraction.text import CountVectorizer

text = [
    'The sky is blue',                            # sky, blue
    'The sun is bright',                          # sun, bright
    'The sun in the sky is bright',               # sun, sky, bright
    'We can see the shining run, the bright sun'  # shining, sun, bright
]

countvectorizer = CountVectorizer(analyzer='word', stop_words='english')
count_wm = countvectorizer.fit_transform(text)
 skybluesunbrightshining
doc111000
doc200110
doc310110
doc400211
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
### TFidfVectorizer 코드화
from sklearn.feature_extraction.text import TfidfVectorizer

text = [
    'The sky is blue',                            
    'The sun is bright',                          
    'The sun in the sky is bright',               
    'We can see the shining run, the bright sun'  
]

tfidfvectorizer = TfidfVectorizer(analyzer='word', stop_words='english', norm='l2')
tfidf_wm = tfidfvectorizer.fit_transform(text)

### Cosine 유사도 계산
from sklearn.metrics.pairwise import cosine_similarity

cosine_similarities = cosine_similarity(tfidf_wm)
 skybluesunbrightshining
doc11, 1*log(4/2) = 0.61911, 1*log(4/1) = 0.7852000
doc2001, 1*log(4/3) = 0.70711, 1*log(4/3) = 0.70710
doc31, 1*log(4/2) = 0.657801, 1*log(4/3) = 0.53251, 1*log(4/3) = 0.53250
doc4002, 2*log(4/3) = 0.73251, 1*log(4/3) = 0.36621, 1*log(4/1) = 0.5738

TF-IDF 문제점

  • 정확히 동일한 단어가 나와야 유사도 계산이 이뤄짐 (동의어 처리가 안됨)
  • 단어의 수가 늘어나고, 아이템의 수가 늘어나면 계산이 오래 걸림
  • 결국 워드 임베딩을 사용하는 것이 더 좋음 (아니면, LSA 같은 차원 축소 방식을 사용해야 함)

3. Recommendation System 구현 2

4. 딥러닝 기반 Recommendation System 구현 1

5. 딥러닝 기반 Recommendation System 구현 2

This post is licensed under CC BY 4.0 by the author.

LG Aimers 2기 지도학습 - 분류, 회귀 (이화여대 강제원 교수님)

LG Aimers 2기 지도학습 - 딥러닝 (KAIST 주재걸 교수님)