TITLE : [토크ON세미나] 추천시스템 분석 입문하기 4강 - 협업 필터링 (KNN, SGD, ALS) | T아카데미
YOUTUBE LINK : https://youtu.be/TFbTU9VG3is PRESENTER : SKplanet Tacademy DURATION : 00:42:29 PUBLISHED : 2021-01-25
Table of contents
FULL SCRIPT
협업필터링 모델은 무엇이냐?
협업필터링이란 사용자의 구매 패턴 그리고 평점을 가지고 다른 사람들의 구매 패턴이나 평점을 통해서 추천을 해주는 거예요 그래서 나에 대한 것을 추천해줄 때 내가 평점을 매긴 거랑 비슷한 사용자들을 찾는 거거든요 그래서 예를 조금 KNN과 같은 기법들은 협업필터링에서도 최근저기후 기반의 메모리 베이스 기반의 모델이라고 표현하고 잠재 요인을 통해서 협업필터링을 하는 경우 잠재 요인의 기반의 모델이라고 표현합니다 그리고 얘 같은 경우는 2006년도 부터 9년도까지 열린 넷플릭스 프라이즈 컴피티션에서 우승한 솔루션이기 때문에 그때 이후로 유명세를 타가지고 후에도 많은 사람들이 알고리즘 연구했고 최근에도 딥러닝과 그런 협업필터링 많이 적용해 가지고 연구하고 있는 분야이기도 합니다 그래서 협업필터링에서도 이후 기반의 모델인 KNN부터 살펴보도록 할게요 네이벌 베이스드 협업필터링인 메모리 기반의 알고리즘 협업필터링은 얘는 협업필터링 위해서 초기에 개발된 알고리즘인데 예를 들어서 두 가지 형태의 접근법이 있을 수 있어요 나와 비슷한 사용자를 찾아서 비슷한 사용자가 본 아이템을 추천해주겠다 그리고 내가 준 아이템과 유사한 아이템을 찾아서 유사한 상품을 추천해주겠다 얘 같은 경우 보면 이 세 번째 친구를 친구한테 지금 포도랑 오렌지를 추천해 주려는 걸 어떻게 만들었는지를 볼 텐데 얘 같은 경우 딸기와 사과를…
아 딸기와 수박을 먹었잖아요 이 친구는 딸기와 수박 그리고 오렌지를 먹었고 아 4개 다 먹었죠 포도 딸기 수박 오렌지 단순하게만 봐도 4개 중에 2개 상품이 겹치니까 50%가 유사하다는 걸 알 수가 있고 그래서 얘와 얘가 유사하니까 유사했던 이 첫 번째 친구가 먹은 포도랑 오렌지를 추천해 주면 어느 정도 되겠거니 하는 방법입니다 그리고 비슷하게 만일 이 친구와 이 친구가 수박에 대해서 둘 다 선호하는 게 비슷하고 만일 다른 수박에 대해서 선호하는 게 비슷하다면 그렇게 비슷하게 선호를 받은 아이템들에 대해서 포도를 추천해 주겠다는 것은 아이템 기반의 필터링이고요 그래서 얘랑 얘의 차이점은 유사한 사람을 찾냐 유사한 상품을 찾냐가 가장 큰 차이점이라고 생각하시면 됩니다 유사한 사람은 내가 준 내가 평점을 내린 아이템이 비슷한 걸 찾는 거고 유사한 상품 같은 경우는 다른 사람들이 평점을 줬을 때 포도랑 수박이 다른 사람들이 보통적으로 주는 평점이 비슷하다는 것을 의미합니다 그래서 그 중에서도 가장 기반이 되는 KNN 알고리즘 같은 경우는 보통은 가장 근접한 K계의 네이벌스를 계산하는 거예요 그래서 대표적으로 머신러닝 해보신 분들은 많이 알겠지만 이 p, pt라는 점이 새로 들어왔을 때 얘에 대한 클래스가 a, b, c 중에 뭐가 속하는지를 알고 싶고 얘를 알기 위해서는 내 주변에 k계의 점들만 이렇게 딱 봤을 때 a에 속하는 점은 2개, b에 속하는 점은 3개, c에 속하는 점은 2개니까 얘는 b와 가장 인접하겠거니 해가지고 b를 클래스로 프레딕션 한다는 알고리즘인데 한번 얘를 가지고 그런 데이터에서 어떻게 추천이 되는지 비슷한 사용자를 찾는지에 대해서 예제로 한번 살펴볼게요 일단 아까 초반에 봤던 aprii 알고리즘에서 봤던 추천 시스템 모델 같은 경우는 implicit feedback data라고 했었잖아요 얘 같은 경우 구매를 했는지 안 했는지에 대한 정보는 알고 있지만 이거를 내가 좋아하는지 싫어했는지에 대한 정확한 반응은 모르는 형태를 implicit이라고 했고 explicit 같은 경우는 유저가 자신의 선호두를 직접적으로 표현한 거예요 그래서 1점부터 10점까지의 평점을 매길 때 7점 같이 아이템 1과 3은 사용자 1이 난 이거 상품은 좋다, 사용자 3이 4와 5 같은 경우 1점으로 이런 건 싫다 그래서 추천을 하지 말아달라 하는 거를 통해서 학습을 하는 거죠 그리고 지금 현재 이렇게 세 가지 경우에 대해서 물음표가 된 거는 직접 구매를 안 한 건데 그럼 이제 구매를 안 했지만 유사도를 찾게 되면 얘가 진짜 좋아하는지 안 좋아하는지를 이웃 기반의 모델을 통해서 찾으려는 거를 저희가 지금 해보려고 합니다 그래서 목표는 이 세 가지 점이 어떤 평점을 가질지에 대한 거를 예측하는 거예요 그래서 유저 기반의 협업 필터링은 유저가 자신의 선호두를 직접 표현한 데이터고 그리고 유저 간의 유사도를 찾기 위해서 유저 간의 유사도를 먼저 계산하는 것부터 시작합니다 그래서 사용자 3을 기준으로 이 물음표 두 개를 추천하는 거를 예시로 들었을 때 1과 2, 4, 5 중에 어떤 사용자와 사용자 3 간의 유사한지를 한번 계산해 볼 거예요 그래서 사용자 3과 1에 대해서 Cos과 P선으로 유사도를 계산할 수가 있겠죠 이렇게 물음표 쳐진 값들이 있으니까 얘네들은 보통 무시를 하고 진행을 합니다 있는 정보들만 통해서 유사도를 계산한다고 생각하시면 돼요 그래서 실제 알고리즘은 이렇게 계산되는데 6, 7, 4, 5처럼 네 가지 좌표만을 가진 게 값이 실제로 물음표가 두 칸 있어서 아이템 2부터 5를 통해서만 유사도를 계산했다는 것을 의미합니다 그래서 이렇게 유사도 두 개 계산할 수가 있고 유사도 높은 값들 이렇게 계산이 되잖아요 그럼 이제 이거를 통해서 추천을 진행하는데 간단하게 사용자 3에 대해서 가장 나랑 유사한 유저 두 명만을 찾아주세요 하면 사용자 1과 2가 유사한 걸 알 수가 있잖아요 그래서 1과 2가 얘를 평점을 이 물음표에 대해서 4점 4점 내렸으니까 얘 같은 경우도 잘 안 보겠거니 그리고 얘는 높게 내렸으니까 얘 같은 경우 사용자 3도 잘 높게 평점을 주겠거니 이렇게 생각할 수가 있습니다 근데 이때 하나의 문제점이 있는 게 사용자마다 이렇게 한번 평균 값을 보면 아래 3부터 5는 평균 평점이 되게 짜고요 1부터 2는 3, 4, 5에 비해 되게 후한 걸 볼 수가 있어요 그래서 얘네가 실제로 이걸 높게 줬는데 진짜 이걸 높게 준 건지 애초에 이 사용자들이 평균 평점을 높게 주는 후한 유저이기 때문에 그런 편차가 생긴 건지 그런 의구심이 들 수가 있거든요 그래서 이런 의구심을 제거하시기 위해서 그런 거 바이오스 텀을 제거해주는 부분이 필요해요 그래서 그런 걸 어떻게 제거해주냐 첫 번째로 각각의 아이템 1에 대한 평점을 내린 거에 대해서 그러니까 그리고 이거 2 같은 경우 사용자 자신의 평점이 되고요 평균 평점과 그리고 이거 계산을 통해서 얻은 이 1.5 같은 경우는 사용자 1의 아이템 1에 대한 점수가 7이잖아요 그리고 평균적으로 5.5를 주고 이 두 값을 빼줌으로써 1.5라는 그런 바이오스 텀이 제거된 평균 평점을 얻을 수가 있어요 마찬가지로 1.2는 사용자 1에 대해서 4.2에 대해서 6점과 평균적으로 4.8을 주니까 두 값을 뺀 1.2가 이 실제 바이오스가 제거된 평점인 것을 볼 수 있고요 그 피어슨을 기준으로 하니까 유사도가 높은 거에는 더 가중치를 받게 되겠죠 그래서 이렇게 하면 3.35가 계산된 거 볼 수 있고 아까 이 부분에 대해서 평점에 바이오스를 제거했을 때는 6.49로 굉장히 높았는데 이게 3.35로 굉장히 낮아진 것을 볼 수가 있습니다
그래서 이렇게 바이오스 텀 제거해주는 게 중요하고요 방금은 유저 기반의 유사도를 통해서 비슷한 유저 두 명 잡고 추천을 해준 거잖아요 그래서 사용자 1,2가 유사하니까 이 사람들이 내준 7점과 6점 평균 평점으로 사용자 3을 채워줄 건데 바이오스 텀이 있으니까 그 부분을 제거해서 반영해줘야 된다를 본 거고 이번에는 유저 간의 유사도가 아니라 아이템 간의 유사도를 한번 계산할게요 아이템 간의 유사도는 어떻게 계산하냐?
동일합니다 방금 봤을 때는 이렇게 사용자 1과 사용자 2 간의 이런 식으로 유사도를 계산했었잖아요 사용자 1과 사용자 3의 유사도 벡터가 이렇게 사용자 벡터 1, 사용자 3의 벡터 하나 해가지고 유사도를 이렇게 해서 했는데 이번엔 반대로 아이템 1을 이렇게 벡터로 가지고 이런 식으로 벡터 간의 유사도를 계산할 거예요 그래서 이 컬럼과 이 컬럼, 이 컬럼과 이 컬럼의 유사도를 계산하면 사람들이 아이템에 대해서 평점을 내린 게 비슷한 상품을 찾겠다는 것이죠 그래서 이렇게 했을 때 1번 상품과 3번 상품이 굉장히 유사한 것을 볼 수가 있고요 6번 상품 같은 경우에는 4번 상품과 굉장히 비슷한 것을 볼 수가 있습니다 그럼 이제 똑같은 형식으로 채워주는 것도 할 수 있겠죠?
그래서 이 부분은 아까랑 동일해서 넘어갈게요 바이어스 텀 계산해 줘가지고 가중 평균 내려주시면 됩니다 그래서 네이벌 베이스드 메소드의 장점이라고 하면 굉장히 간단하고 직관적이에요 간단하고 직관적인 게 뭐냐?
일단 비슷한 사용자 먼저 찾고 그리고 비슷한 사용자를 몇 명이나 선택할지 그거를 K를 통해서 정해주고 그리고 그렇기 때문에 내가 비슷한 사용자에 통해서 추천을 해 준 거니까 되게 추천하는 이유가 정당해요 이 사람이 평점 내린 게 기존의 사용자와 비슷하다 그러니까 당연히 이 사람들을 통해서 추천해 주는 게 옳다라는 거죠 그리고 추천 리스트에 새로운 아이템과 유저가 추가되어도 상대적으로 모델이 크게 바뀌지가 않아요 근데 시간과 속도를 메모리가 조금 많이 들고 그리고 시소성 때문에 제한된 범위가 있습니다 조금 많이 모든 추천 관련해서는 동일하게 겪는 문제 중에 하나가 빈익빈 부익부 약간 이런 형사인데 사람들이 많이 보는 상품은 애초에 그냥 다 많이 보고 적게 보는 상품은 다 적게 봐가지고 애초에 이런 모델 같은 경우는 많이 보는 거 위주로밖에 조금 추천이 될 수밖에 없어요 그리고 그것 때문에 종가가 비슷한 이유 중에 아무도 해리포터에 대한 평가를 하지 않았으면 해리포터에 대한 평점을 예측 같은 걸 아예 할 수도 없고요 그래서 이런 부분을 해결하기 위해서 아까 봤던 컨텐츠 기반의 추천 시스템을 같이 적절하게 사용해 주는 게 조금 필요합니다 그래서 두 가지 모델이 조금 상호 보완적으로 이런 부분을 해결해 주는 것 같아요 이게 지금 봤던 게 E-WOOK 기반의 추천 시스템 모델이고 E-WOOK 기반의 협업 필터링 모델이고 지금부터 볼 거는 잠재 유인 기반의 협업 필터링 모델이에요 그래서 E-WOOK 기반의 협업 필터링과 잠재 유인 기반의 협업 필터링이 뭐냐에 대해서 차이점부터 언급하고 들어가면 E-WOOK 기반은 아이템의 그런 벡터와 유저 스페이스의 벡터 간의 이렇게 조합을 통해가지고 아이템 간의 유사도를 통해서 아이템 기반 추천을 한다든지 유저 스페이스 간의 유저 간의 벡터의 유사도를 개선해서 비슷한 유저를 통해 추천을 해준다든지 그런 식으로 진행했다면 잠재 유인 기반의 협업 필터링은 어떤 유저 스페이스에 대한 레이턴트 스페이스와 아이템 스페이스에 대한 그런 아이템 레이턴트 스페이스 두 가지를 만들고 둘의 그런 매트릭스 곱을 통해서 추천을 진행하는 거거든요 그래서 한번 정의부터 간단하게 설명 다시 드리자면 잠재 유인의 협업 필터링은 이런 레이틴 매트릭스를 채우기 위해서 두 가지 행렬을 도입해요 행렬 하나는 유저에 대해서 설명하는 유저 매트릭스 행렬 하나는 아이템에 대해서 설명하는 아이템 매트릭스 근데 이 외에 그런 유인들이 정확히 무엇을 의미하는지를 모르기 때문에 잠재 유인 기반의 협업 필터링이라고 하고 각각의 사용자의 레이턴트 스페이스와 레이턴트 매트릭스와 아이템의 레이턴트 매트릭스를 곱했을 때 이 평점 매트릭스를 복원할 수 있다라는 거죠 그래서 보면 이게 영화 같은 경우 이게 영화였던 것 같은데 영화에 대해서 어떤 그런 장르를 가지는지 그런 거를 의미하는 거거든요 그래서 내로라는 영화는 히스토리의 성분을 가지고 그리고 로맨스는 없고 했는데 그리고 마찬가지로 비슷한 영화 이거 세 개에 대해서도 영화 성분을 가지고 이 세 개 영화에 대해서는 로맨스 성분을 가지고 근데 이제 1, 2, 3 같은 경우는 히스토리 관련된 영화를 보니까 실제 성분이 히스토리 관련된 요인에 대해서만 1로 반응하는 것이고 영화 같은 경우 1, 2, 3 같은 이 앞에 세 개가 히스토리 관련된 잠재 유인만 갖고 있겠거니 하는 거죠 그래서 대충 이렇게 사용자와 아이템에 대해서 잠재 유인을 분석하는데 그런 잠재 유인은 지금은 히스토리와 로맨스로 설명하긴 했지만 사실은 정확하게는 알 수 없다라는 게 정확하게 알 수는 없기 때문에 잠재 유인이라고 표현합니다 그리고 이 잠재 유인을 계산하는 방법은 넷플릭스에서 사용했던 SVD도 있고 웨이트드 해가지고 가중치 주는 것도 있고 온리옵절브드 돼가지고 하는 방법도 있는데 저희는 간단하게 SVD는 넘어가고 SGD랑 뒤에 나오는 ALS 두 가지 방식에 대해서 설명을 드릴게요 SGD는 뭐냐, SGD 같은 경우는 고유가 분해를 통해서 행렬을 대각하는 방법이거든요 그래가지고 스토케스틱 그라데이틴트 딥스텐셉 다들 입러닝 하셨으면 알텐데 이전에 평점 매트릭스와 내가 만든 유저에 대한 레이턴트 매트릭스와 아이템에 대한 레이턴트 매트릭스의 곱 간의 차이를 최소화하려는 거예요 그래서 아까 봤듯이 유저 레이턴트와 아이템 레이턴트를 곱했을 때 평점 매트릭스 복원할 수 있는데 그게 실제 평점 내린 거랑 얼마나 차이가 나는지 그 차이를 줄이는 u와 v를 찾겠다는 거죠 그리고 딥러닝이다 보니까 u와 v의 웨이트가 계속 업데이트 되는 형식을 가지겠죠 그래서 그래디언트 데센트에서 편미분 된 값을 보면 u에 대해서 편미분 했을 때 어떤 v에 대한 함수가 나오고 v에 대해서 편미분 했을 때 어떤 u에 대한 함수가 나오는 것을 알 수가 있어요
그리고 이걸 통해서 지금 계속 업데이트가 진행이 되겠죠 참고로 딥러닝 하다보면 다들 그렇겠지만 웨이트 값 같은 경우 그런 레귤레이제이션 텀이 없으면 되게 폭발적으로 증가하는 경우가 있거든요 그래가지고 그런 거를 방지해주기 위해서 각각의 크기의 제곱인 레귤레이제이션 텀을 이렇게 더해줌으로써 어느 정도 웨이트가 폭발하는 것을 방지해주기 위한 장치가 필요합니다 그리고 이제 한번 실제 예시를 통해서 어떻게 진행이 되는지를 한번 살펴볼게요 그래서 지금 데이터는 사용자 4명에 대해서 유저 3개에 대한 아이템에 대한 영화에 대한 평점을 준 매트릭스가 있고요 평점은 1부터 5까지 제공된 형태고 이러한 형태의 데이터를 아시다시피 익스플리시 피드백 된 형태의 데이터라고 생각하시면 됩니다 그래서 저희의 목표는 이 물음표를 채우는 건데 이 물음표를 어떻게 채울 거냐?
유저 레이턴트와 아이템 레이턴트의 곱을 통해서 채울 거다 이거죠 그래서 아까 봤듯이 유저 레이턴트와 아이템 레이턴트는 일단 이거는 사용자 4명에 대해서 그리고 아이템 3명에 대해서 차원을 가진 거고요 이 차원에서 이 컬럼의 크기 이 로우의 크기는 이거는 사용자가 정해주는 값이고 보통은 ALS 논문 같은 거 보면 20을 많이 사용한다고 해요 그래서 저도 보통 20을 많이 사용합니다 그래서 초기에 유저 레이턴트의 값과 아이템 레이턴트의 값은 랜덤하게 이니셜라이저된 값이고 둘을 다 프로덕트하면 얘는 4 곱하기 2고 얘는 2 곱하기 3이니까 둘을 곱했을 때 4 곱하기 3의 행렬이 나오잖아요 이렇게 나온 내 복원된 레이턴트 매트릭스를 실제 값과 비교해 보면서 그래디언트 데스텐트를 진행하는 거죠 그리고 이 참고로 물음표 된 거는 우리가 실제 라벨이 없으니까 얘에 대해서는 스킵을 진행해주고 실제 있는 3부터 4까지 물음표 2개를 제외한 10가지 레이팅에 대해서만 학습을 진행한다고 생각하시면 됩니다 한 번 보면 3하고 0.0663하고 차이가 많이 나잖아요 그래서 에러 값도 되게 크게 나와요 그렇기 때문에 에러 값이 크니까 이 로스 값도 지금 받는 부분이 되게 크게 이렇게 얻어오는 거죠 그래서 로스 에러 값에 대해서 그리고 벡터, 유저의 아이템의 이거는 지금 유저에 대해서 그래디언트 하는 거잖아요 그래서 보면은 v에 대해서 벡터를 받고 지금 0번째 사용자에 대해서 첫 번째 아이템에 대한 그런 레이팅에 대한 오차를 계산하기 주기 때문에 레이턴트 스페이스도 동일하게 0번째 사용자에 대해서 첫 번째 아이템에 대한 벡터 스페이스가 이렇게 건드려진다고 생각하시면 돼요 그래서 이 값이 그대로 이렇게 오는 거고 그래서 앞에 텀은 그래디언트 데스텐트 값 그 뒤에 텀은 레귤러이제이션 되는 값이라고 생각하시면 됩니다 그래서 에러에다가 이제 아이템 스페이스에 값 곱해주고 레귤러이제이션 진행하고 똑같이 로스를 이번에는 아이템 스페이스에 대한 값으로 계산을 주기 때문에 v로 미분하니까 이제 사라지고 u만 남게 되겠죠 여기서 그래서 u에 대해서 이제 아이템 스페이스 0번째 사용자에 대한 값 이 값이 이렇게 남게 되고 뒷부분은 이제 레귤러이제이션을 해줘야 되니까 자기 자신의 웨이트 값이 온다고 생각하시면 됩니다 그리고 0.01 같은 경우는 그 제가 설정해주는 람닷값 그 레귤러이제이션을 얼마만큼 설정해주지에 대한 파라미터로 보시면 됩니다 그리고 이렇게 진행하고 이제 이번에는 3에 대해서 진행했으니까 그 다음 텀에 대해서도 이제 진행하기 전에 일단 웨이트 업데이트 이렇게 해줄 수 있고요 업데이트 같은 경우는 아까 계산했던 duser 같은 경우 이렇게 해가지고 러닝 레이트만큼 이렇게 크기 반영해서 업데이트 해주는 거는 당연하니까 쉽게 아실 테고 쉽게 아실 테고 new user latent에 대한 업데이트 된 값을 계산하려면 기존의 웨이트에다가 러닝 레이트와 그렇게 계산한 델타 그 백 프로파게이션 값을 곱해서 이거 빼주면 됩니다 마찬가지로 item latent에 업데이트 된 웨이트도 동일하게 계산해주고요 근데 이걸 이제 3에 대해서 계산했으니까 물음표를 제외한 모든 평점에 대해서도 반복해서 진행해줄 필요가 있어요 그래서 지금은 3에 대해서 했으니까 다음엔 2에 대해서 진행해주고 그럼 어떻게 되겠어요?
2는 지금 사용자 0번째에 대해서 두 번째 상품이잖아요 그래서 latent space도 0번째 사용자에 대해서 두 번째 아이템이 이렇게 반응하게 되고요 마찬가지로 다음번 첫 번째 사용자에 대해서 0번째 상품에 대해서는 여기서 사용자 1, 0번째 아이템 이렇게 계속해서 진행하다 보면 latent space 값이 계속해서 바뀌고 얘를 이렇게 한 바퀴 돈 게 에폭크 1인데 얘를 에폭크 10번 돌다 보면 어느샌가 좋은 토탈 코스트가 계속 떨어지다 보면 어느 정도 값이 비슷하게 수정되는 구간이 오거든요 그래서 1하고 1.13, 2하고 2.38, 4하고 3.91, 5하고 4.2 이렇게 되게 비슷하게 온 걸 볼 수가 있죠 그래서 이 결과를 나온 걸 보고 이 물음표를 지금 저희가 채운 거고 어느 정도 다른 게 비슷하니까 유의미하게 결과 나왔다고 생각할 수가 있잖아요 그래서 이 결과를 보고 사용자 0번 같은 경우 이 첫 번째 사용자 같은 경우 평점이 높은 이 상품은 2.7로 기존에 평점 내린 것보다 중간층에는 속하니까 추천을 해주자 이 물음표 같은 경우 평점 마이너스 1으로 추천해줘도 어차피 안 보겠네? 그러면 추천을 안 해주자 이런 식으로 분석을 진행할 수도 있고요 보통 이런 식으로 많이 하고 이 유저 스페이스와 아이템 스페이스가 어떤 잠재 유행 기반의 특징이 추출이 된 거잖아요 그래서 얘를 잘 분석해서 여기서 유사도를 계산해서 추천을 해줄 수도 있습니다 저 같은 경우는 여기서도 많이 TSN이나 이런 거 해가지고 유저 간에 어떤 특성을 가지고 있는지 아이템 간에 어떤 특성을 가지고 있는지 그런 거 분석을 많이 진행하는 거 같아요 그래서 이런 SGD 같은 경우는 되게 유연해서 로스 펑션도 되게 다양한 거 사용할 수 있고 딥러닝 장점들은 모두 다 가지고 있다고 생각하시면 되고요 수렴 속도가 매우 느리다고 했지만 딥러닝 좋은 거 쓰시면 매우 빠를 겁니다 그리고 파랄라이즈드로 반복해서 같이 분산 처리할 수 있으면 더 빠를 거고요 그 다음에 보는 많이 사용하는 협업 필터링 방식이 AS라는 방법입니다 얘 같은 경우는 기존의 SGD가 유저와 아이템을 동시에 최적화하는 방법이라면 ALS는 하나의 레이턴트는 고정해놓고 하는 건데 얘의 장점이 하나를 고정하기 때문에 다른 하나는 무조건 컴백스하게 형태고 최적화가 컴백스한 형태고 무조건 행렬히 수렴하는 걸 알 수가 있거든요 그래서 무슨 말인지 다시 한 번 설명드리자면 여기 SGD 같은 경우 그래디언트 데스젠트 할 때 얘와 얘 값을 동시에 구한 다음에 웨이트를 업데이트를 하잖아요 근데 SGD는 순서가 좀 달라요 예를 들어서 이 벡터 스페이스 이게 솔루션인데 유저를 먼저 고정해놓고 업데이트를 하고 부위를 먼저 고정해놓고 업데이트를 진행하거든요 그래서 실행해서 보면 아이템 행렬 같은 경우는 그냥 고정해놓고 사용자 행렬을 최적화한다든지 그 다음에 사용자 행렬을 그냥 고정해놓고 아이템 행렬을 최적화한다든지 하게 되는데 일단 처음부터 다시 한 번 설명드릴게요 SGD가 두 개의 행렬, 레이턴트 두 개를 동시에 최적화하는 거라면 ALS는 하나는 고정시켜놓고 유저를 고정시키고 아이템을 최적화시키고 그 다음에 아이템을 최적화시키고 아이템을 고정시켜놓고 유저를 최적화 유저를 고정시켜놓고 아이템을 최적화 이런 식으로 반복해서 진행하는 건데 이렇게 하면 문제가 컴백스 형태로 바뀌게 되거든요 그래서 유저를 고정했을 때는 아이템 레이턴트 스페이스에 정답을 찾을 수가 있어요 수렴된 행렬을 찾을 수 있는 게 되게 장점이어서 얘도 많이 사용하는 알고리즘 중에 하나니까 잘 알아두면 좋을 것입니다 그래서 기존의 문제를 다시 한 번 생각해보면 어떤 Y라는 값에 대해서 Y라는 레이팅에 대해서 X-β라는 선형외기처럼 계산을 생각할 수도 있는데 거기에 대해서 베타를 해를 구하는 거 보통 리니어 리그레이션 배웠을 때 한 번씩은 봤을 거거든요 리니어 리그레이션에서 Y-Xβ의 L2 노므를 계산하는데 그때 베타의 해가 무엇인지 계산한 거 보통 한 번 리니어 리그레이션 파트 다시 보시면 해당식이 있을 거예요 근데 여기서도 지금 동일하게 진행할 수가 있는데 똑같이 R과 그리고 유저에 대한 값 그리고 아이템에 대한 값이 주어졌을 때 뒤에는 레귤라이제이션 텀만 있을 때 동일하게 이 베타에 대한 해를 하나만 고정시키면 이 Vt 곱하기 V, Ut 곱하기 U 이런 식으로 어떤 솔루션을 저희가 알 수가 있다는 거죠 이거 솔루션 나오는 부분은 조금 순식적으로 설명을 드려야 돼서 넘어가고요 ALS 같은 경우 이거 물음표 같은 경우는 전부 0으로 처리한 다음에 학습을 진행합니다 그래서 학습 과정은 조금 비슷하고 뒤에 고정시키는 부분만 달라요 그래서 user.latent, item.latent, space 처음에 이니셜라이저 한 다음에 아까 말했듯이 하나를 고정해놓고 하나를 최적화하는 과정을 거치거든요 그래서 최적화하는 해는 선형외계에서 해 구하는 것처럼 답이 정해져 있고 그래서 저희는 그냥 정해진 답을 그냥 사용하면 됩니다 V 같은 경우 아까 계산했기 때문에 V 그냥 대입해놓고 lambda 같은 경우도 저희가 정해주는 레귤라이제이션 값이잖아요 그래서 R1 같은 경우도 이미 알고 있는 이 값이고 그래서 값을 다 알고 있어요 저희는 그래서 그냥 다 대입만 해주시면 돼가지고 이것도 대입, 이거는 아이템 고정하고 사용자에 대해서 최적화한 부분 그리고 사용자에 대해서 고정해놓고 아이템을 최적화하는 부분 이렇게 반복해서 진행하는 거기 때문에 되게 쉽고요 코드도 implicit package라는 걸 사용해서 바로 적용할 수가 있는데 실스 코드는 먼저 협업 필터링 기반의 추천 시스템 sharp-sgd부터 먼저 살펴보도록 하겠습니다 그래서 베이스라인 코드는 이 블로그에 있는 분의 코드를 사용했고요 조금 필요한 부분만 수정해서 작성했습니다 그래서 코드를 좀 스텝 바이 스텝으로 여기는 좀 천천히 설명을 드릴게요 일단 기본적으로 매트릭스 팩토라이제이션이라는 클래스를 만들어 줄 건데
저희가 이제 사용하게 될 hyper-parameter들도 있었고 그리고 input 값으로 받는 값들도 있었잖아요 제가 기본적으로 받을 input은 rating 매트릭스에요 이렇게 rating 매트릭스인데 사용자에 대해서 어떤 아이템 몇 개를 가지고 평점을 0부터 5에서 무엇을 매겼는지 이 input 값을 입력 값으로 받는데 여기서 r은 rating 매트릭스이고 num-users와 num-items는 사용자 몇 명과 아이템은 총 몇 개가 있는지를 의미합니다 그리고 아까 유저의 latent space는 제가 정해주는 어떤 hyper-parameter인 줄 알고 설명했었잖아요 그래서 k 값 latent space의 크기는 제가 설정해주면 됩니다 그리고 running rate와 regularization을 얼마만큼 줄지 그리고 fork, 반복해서 학습은 몇 번을 할지에 대한 세 가지에 대해서 hyper-parameter를 정해주시면 됩니다 참고로 init이 뭐냐고 하면 init 같은 경우 클래스를 이렇게 호출할 때 자동으로 실행되는 함수에요 그래서 만약 내가 매트릭스 팩토라이제이션이라는 코드를 이런 식으로 호출한다고 생각하시면 팩토라이저라는 객체를 만들 때 자동으로 init이라는 부분은 바로 실행이 돼가지고 아까 봤던 hyper-parameter들을 이 부분에서 r과 num-users, num-items 이런 부분에 자동으로 모델스로가 객체를 실행하는 순간 바로 저장을 진행하게 되는 거죠 그래가지고 이 입력 값을 매트릭스 팩토라이제이션에 넣어서 실행을 하게 되는데요 일단 아까 봤던 hyper-parameter 같은 경우는 저희가 정해주시면 되고요 여기서는 좀 데이터 크기가 작아서 k3을 사용했지만 데이터 많은 경우에는 보통 k는 20 정도의 인자 값을 줘가지고 많이 사용하는 것 같아요 그리고 regularization parameter 같은 경우도 보통 상황 맞게 설정해주시면 되고요 그리고 벌보수는 이거 학습 과정에 대해서 프린트 찍을지 안 찍을지 학습 과정을 보여주지 말지에 대한 hyper-parameter를 의미한다고 생각하시면 됩니다 그 다음에 팩토라이제이션에서 fit이라는 함수를 호출하게 되면 학습이 시작이 되는데요 이 fit에 대한 함수 한번 보시면 아까 봤듯이 첫 번째로 p와 q라는 latent space를 만들 거예요 여기서 p는 유저에 대한 latent space고 q는 아이템에 대한 latent space인 거죠 그래서 값을 보면 random normalization 함수를 통해서 정규범포화를 가지고 있는 정규범포화를 띄도록 initialize를 취해줄 건데 size는 numUsers k의 차원을 가지도록 qItemUserLatentItemSpace 같은 경우는 numItems와 k의 크기를 가지도록 만들어준다 생각하시면 됩니다 그리고 마찬가지로 bias term에 대해서도 이렇게 설정해줄 수 있고요 그리고 저희가 이제 학습을 이제 전체에 에폭그 지금 방금 100번 설정한 값에 대해서 100번만큼 반복하게 되잖아요 근데 이제 아까 말했듯이 평점이 있는 부분에 대해서만 계산을 해야 돼요 그래서 그 부분을 이제 출력해주는 부분이 nonzero라는 함수인데 nonzero라는 함수가 의미하는 게 무엇이냐면 0이 아닌 부분의 x, y값만 출력을 해준다는 의미예요 그래가지고 저희 rMatrix 이렇게 보면 어떤 값은 1, 2처럼 0이 아닌 값과 0인 값이 이렇게 섞여져 있는데 이거 같은 경우 실행을 하게 되면 0이 아닌 1, 0, 0 좌표와 그리고 0이 아닌 1, 0, 3 좌표 이런 식으로 0이 아닌 부분에 대해서만 x와 y를 반환해주는 게 self.r에 nonzero라는 함수입니다 그리고 저희가 이렇게 해서 x와 y를 출력을 했잖아요 그럼 이제 이거에 대해서 gradient descent를 계산하고 그리고 얘를 통해서 weight를 업데이트 시켜주고 그 다음에 cost를 저장을 하게 되면 전체 학습과정은 끝이 나게 되는 거죠 그래서 한번 gradient descent 부분부터 다시 살펴볼게요 gradient descent 함수 살펴보면 일단은 에러를 계산해주기 위해서 prediction 해주는 부분이 필요해요 여기서 말하는 prediction이 뭐냐면 저희가 만든 user latent space와 item latent space를 곱해줌으로써 어떤 행렬 매트릭스를 만들어주는 부분이고요 그리고 추가적으로 아까 이론 ppt에서는 설명 안 했지만 여기에 보통 평점에 대한 바이어스 텀도 이렇게 더해줄 수가 있습니다 그 KNN에서 진행했던 것처럼 이렇게 해서 latent, latent space, latent 그런 매트릭스를 만들어주면 prediction 값이 있고 prediction과 latent 값의 차이를 계산하면 error term을 계산할 수가 있잖아요 그래서 이 error term을 가지고 바로 업데이트를 이렇게 진행해주게 되는 거죠 바이어스 텀에 대한 업데이트도 진행해주고 그리고 latent space의 weight에 대한 그런 값도 업데이트를 진행해주고 이렇게 업데이트를 반복해서 진행해주게 되면 이 부분인데 이렇게 포뮬리드에서 반복해서 진행해주게 되면 user latent space와 item latent space가 어느 정도 좋은 값을 수렴하게 될 테고 그 수렴한 값을 가지고 추천을 진행해주시면 됩니다 그리고 이번에는 ALS에 대해서 한번 실스코드 똑같이 살펴보도록 할게요 근데 ALS도 실스코드는 똑같고 딱 한 부분 달라지는 것만 보시면 되는데 바로 이 텀이거든요 이 부분에 포문이 한번 어떻게 걸린지 보시게 되면 에폭 한 번에 대해서 여기는 이제 user latent space에 대해서 업데이트를 진행해주고 여기는 item space에 대해서 업데이트를 진행해주는 부분인데 아까 SGD 같은 경우는 여기가 아마 이렇게 달랐어요 보면 이렇게 한 번에 그냥 같이 진행을 진행해줬는데 이게 근본적인 ALS와 SGD의 차이점이라고 생각하시면 돼요 하나를 일단 업데이트 계속해서 수렴을 만들고 그 다음에 다음 매트릭스의 행렬을 수렴을 진행해주겠다 하지만 SGD는 둘을 동시에 진행해주는 게 큰 차이점입니다 그리고 이 함수 내용 보면 어떤 정해진 솔루션이 아까 있다고 했었잖아요 그 함수 그대로 구현을 해서 적용을 하면 돼서 이 부분은 한번 수식을 보고 코드 어떻게 작성됐는지 이게 수식하고 어떻게 차이가 되는지를 한번 이해해주시면 좋을 것 같아요 그리고 참고로 이게 ALS 이렇게 날코드로 이렇게 numpy 코드로 짜봤는데 사실 보통은 이렇게 사용을 안 하죠 많이 일단 word2vec이 이제 여러 가지 문장이 있을 때 얘를 인베딩을 모델 스스로가 해주는 거거든요 그래서 input 같은 경우는 이제 하나의 문장에 대해서 중심 단어와 주변 단어를 통해서 이 부분을 보시면 될 것 같은데 모델 스스로가 이제 칸을 양옆으로 한 칸씩 이 부분은 window size 하나를 입력했을 때 양옆에 you are good bye, say 이렇게 세 칸씩 보통 입력이 들어가게 되는 거예요 그래서 만일 뒤에 다른 더 긴 문장이나 짧은 문장들이 들어와도 세 칸씩 이렇게 들어가면서 모델 스스로가 양옆에 무엇이 나오는지에 대해서만 학습을 진행하기 때문에 이렇게 학습이 진행되고 인베딩이 이제 이렇게 학습되면서 weight input이 인베딩된 단어에 대해서 인베딩된 결과값이 되는 거죠 그래서 인베딩을 해서 모델에 넣는 게 아니라 그냥 문장 자체를 input으로 입력을 넣어주면 모델 스스로가 학습을 진행해주게 되면서 weight 값을 뱉어내게 되고 이 뱉어내진 weight가 인베딩된 가중치 값으로 생각하시면 됩니다 협업 필터링 부분 장점과 단점부터 이야기 드리고 그 다음에 간단하게 추천 매트링 무엇이 있는지 설명드리고 실습 부분 넘어가도록 할게요 그래서 협업 필터링의 장점과 단점부터 설명드리자면 장점 같은 경우는 도메인 지식이 필요하지 않습니다 되게 큰 장점이죠 이게 사실 콘텐츠 기반의 모델 같은 경우 자연원 처리하려면 문서에 따라서 어떤 내용들이 중요하고 이미지 같은 경우 어떤 이미지의 특정 부분들이 중요한지 그런 걸 많이 고려를 해서 학습을 진행해야 되는데 협업 필터링 같은 경우 아까 만든 클래스들이 있잖아요 SGD도 그렇고 ALS도 그렇고 그냥 돌리시면 결과가 나옵니다 그래서 도메인 지식이 필요하지 않고 결과가 되게 좋거든요 그래서 사용자의 새로운 흥미라든지 어떤 비슷한 사용자나 비슷한 상품들 그런 거 찾기도 좋고 이런 문맥 정보라든지 다른 추가적인 정보가 없이 내가 뭘 구매했냐 안 구매했냐 라든지 인플레이션 데이터를 그냥 써도 되고 평점을 0부터 5까지 몇을 매겼는지 익스플리시 데이터를 그냥 사용하면 되기 때문에 추가적인 정보가 필요 없죠 그래서 시작 단계의 모델로 굉장히 좋아요 그래서 베이스라인 보통 이거 협업 필터링으로 적용해보고 추가적으로 콘텐츠랑 같이 결합했을 때 결과가 어떻게 나왔는지 아니면 다른 딥러닝이라든지 통계 기반의 모델들 적용했을 때 결과가 어떻게 나왔는지 그런 거 이제 해볼 수가 있는 거죠 하지만 확연히 보듯이 단점 같은 경우는 새로운 아이템이나 새로운 고객이 들어오면 한 번 더 학습을 진행해줘야 되기 때문에 좀 다루기가 힘듭니다 그리고 사이드 피처들 그러니까 고객의 개인정보 아이템의 추가 정보 뭐 이런 아까 메타 데이터에서도 좋은 정보들이 있었는데 걔네들을 같이 학습에 참여하기가 어렵죠 그리고 ALS 같은 경우는 SGD보다 조금 수렴 속도가 빠르다는 장점이 있고 그리고 로스스케일만 사용한다는 그런 단점이 있습니다