Skip to main content Link Menu Expand (external link) Document Search Copy Copied

TITLE : [토크ON세미나] 추천시스템 분석 입문하기 3강 - 컨텐츠 기반 모델 - Word2Vec(CBOW, Skip-gram)

YOUTUBE LINK : https://youtu.be/3jfHP0Rq1Gg PRESENTER : SKplanet Tacademy DURATION : 00:28:15 PUBLISHED : 2021-01-25

Table of contents

  1. TITLE : [토크ON세미나] 추천시스템 분석 입문하기 3강 - 컨텐츠 기반 모델 - Word2Vec(CBOW, Skip-gram)
  2. FULL SCRIPT
  3. Summary

FULL SCRIPT

TFIDF의 장점과 단점부터 다시 언급하면 장점 같은 경우 직관적인 해석이 가능하다고 했었고 단점 같은 경우 대규모의 말몽치를 가질 때 메모리상의 문제점을 가지고 이게 높은 차원을 가지기 때문에 매트릭스가 되게 스팔스한 형태를 가져서 문제가 생긴다고 이야기 했었습니다.

그래서 아까 봤던 예시에서도 데이터 영하 4만 5천 개 정도밖에 없었는데 램 16기가의 캐글 노트북에서 터지니까 2만 1개로 줄여서 사용할 수 밖에 없었고요.

그래서 이렇게 이런 레플레이션트 아이템을 벡터로 표현할 때 방금처럼 TFIDF가 아니라 워드투백이라는 기법이 있는데 워드투백 기법 같은 경우는 아까의 문제점을 해결하기 위한 방법 중 하나예요.

대규모 말몽치를 가질 때 메모리상의 문제점을 가지니까 그리고 이렇게 문제점을 가지는 게 모든 단어를 사용하니까 문제점을 가진다.

그래서 이러한 단어들을 조금 의미 기반으로 바꾸고 그리고 한 번에 학습을 하는 게 아니라 배치 기반의 딥러닝에 도움을 받아서 배치 기반의 학습을 하면 어떨까.

그래서 통계 기반의 단점이 아까 봤듯이 세 가지인 것 같아요.

대규모 말몽치 할 때 메모리상의 문제점이 있다.

한 번에 학습을 진행해야 되니까 배치 단위로 쪼갤 수가 없어서 큰 작업 처리하기 어려웠다.

그리고 GPU 같은 병렬 처리 기대하기도 힘들죠.

그리고 학습을 통해 개선하는 그런 게 힘들다.

이 정도가 있는 것 같아요.

그래서 이제부터 볼 신경만 기반의 워드투백은 다음에 세 가지 문제를 전부 다 해결하는 방법입니다.

추론 기반이 뭐냐.

추론이라고 하면 여기서 말하는 추론은 주변 단어라는 맥락을 통해서 물음표에 중심 단어가 들어가는지 어떤 단어가 들어가는지 추출하는 작업인데요.

예를 들어서 you say goodbye and I say hello라는 예시가 있을 때 여기 물음표가 이렇게 주어졌을 때 you랑 goodbye라는 단어만을 보고 안에 say가 들어가는 것을 맞출 수 있을지 반대로 say라는 단어만 보고 양 옆에 you와 goodbye라는 단어를 맞출 수 있을지를 알아내는 게 워드투백입니다.

그리고 이렇게 학습을 통해서 say가 나온다고 예측을 했을 때 잘못 예측한 경우에 대해서는 학습을 통해서 점점 모델을 개선할 수 있기 때문에 더 좋은 방법이라고 생각합니다.

그리고 워드투백에서 정의에 대해서 다시 이야기해 주자면 워드투백은 단어 간의 유사도를 반영해가지고 단어를 벡터로 바꿔주는 임베딩 방법론인데 그래서 유사도라고 하면 단어의 위치를 통해서 어떤 주변 단어와 같이 나오는지를 통해서 유사도를 반영하는 거예요.

예를 들어서 나는 강아지를 좋아한다, 나는 고양이를 좋아한다.

여기서 강아지와 고양이는 지금 분명히 단어는 다르지만 나는과 좋아한다라는 두 단어의 사이에 나온 거잖아요.

그래가지고 내 주변에 강아지와 고양이가 주변에 나는과 좋아한다라는 비슷한 단어들이 나오니까 그런 위치를 통해서 주변에 나오는 단어들의 유사함을 통해서 벡터로 임베딩하는 게 워드투백이라고 할 수 있죠.

이런 경우 강아지와 고양이는 유사할 것이다.

그래서 원아택더의 형태의 스파스한 매트릭스가 가지는 단점을 해결하고자 그런 매트릭스를 저차원 공간의 벡터로 맵핑하는데 이 부분에 대해서는 뒤에서 다시 언급할게요.

그리고 아까 말했듯이 비슷한 위치에 등장하는 단어들은 비슷한 의미를 가진다.

아까 말했던 고양이와 강아지의 예시처럼.

그래가지고 이를 통해서 유사도를 계산할 수가 있고 아까 봤던 TF-IDF처럼 단어나 구매 상품을 그런 거 벡터라이저 시켜가지고 그런 벡터 간의 유사도를 계산함으로써 워드투백을 진행할 수 있습니다.

그래서 워드투백은 알고리즘이 두 개가 있어요.

첫 번째로는 씹오라는 방법과 두 번째로는 스킵그래미라는 방법인데 일단 결론부터 말씀드리자면 스킵그래미 15보다 성능이 일단은 좋고 거의 다 스킵그래미를 많이 사용합니다.

실제 논문에서도 결과 차이가 많이 커가지고 스킵그래미를 많이 사용합니다.

그래서 15호 방법이 뭐냐부터 설명을 드리자면 15호는 빨간색인 것처럼 주변에 있는 단어들을 가지고 중간에 있는 단어를 예측하는 거예요.

예를 들어서 you와 goodbye를 통해서 물음표를 예측하는 게 15호고 스킵그래미는 say를 통해서 you와 goodbye가 양옆에 나온다는 걸 예측하는 거예요.

근데 이거를 이제 표현을 어떻게 하냐면 여기서 말하는 you와 goodbye처럼 어떤 물음표 주변에 있는 단어를 주변 단어라고 표현하고 이 주변 단어를 어느 정도 길이까지 볼지를 윈도우의 크기라고 정의합니다.

윈도우의 크기가 1인 경우에 대해서는 you와 goodbye만 보고 윈도우의 크기가 2인 경우에 대해서는 이 물음표를 기준으로 you, goodbye, and 양옆으로 두 칸씩 보는 거라고 생각하시면 돼요.

왼쪽에는 빈칸이 없으니까 하나만 보고.

그리고 물음표처럼 중심이 되는 단어들을 중심 단어라고 합니다.

그래서 이를 통해서 15호 알고리즘이 어떻게 진행되는지 한번 살펴볼게요.

여러분들 딥러닝을 조금 대부분 다들 공부를 하셨는지 모르겠는데 혹시 아예 모르시는 분들이 있으신가요?

딥러닝 같은 경우에 인풋이 들어오면 어떤 은닉층과 그런 레이어가 쌓이고 거기서 웨이트를 통해서 아웃풋을 출력한 다음에 그 아웃풋의 소프트 맥스를 치해가지고 정란 레이블과 비교해가지고 어떤 백 프로파게이션을 통해가지고 웨이트를 업데이트하는 거잖아요?

근데 지금 water2back도 정확하게 똑같다고 생각하시면 돼요.

입력값이 지금 들어올 건데 입력값이 원화 팩터의 형태로 들어올 거예요.

예시는 you say goodbye and I say hello에서 you와 goodbye를 입력받는 형태입니다.

그래서 you와 goodbye를 지금 원화 팩터 형태로 입력을 받으면 you만 있는 경우 그리고 goodbye만 있는 경우 두 칸에 대해서만 1을 가지고 나머지는 다 0을 가진 걸 볼 수 있죠?

그래서 얘가 들어왔을 때 입력층의 웨이트랑 곱해져서 어떤 값 하나와 두 개가 생겨서 이 둘을 결합한 은닉층이 하나가 생길 거고 이 은닉층을 가지고 이제 출력층을 만든 다음에 백 프로파게이션을 진행하게 될 텐데 좀 더 자세하게 이야기 드리자면 입력값으로는 you와 goodbye를 받고 정단 레이블은 say를 가지는 형태입니다.

그래서 주변 단어는 아까 봤듯이 you와 goodbye, 중심 단어는 say 그리고 윈도우 크기는 1인 겁니다.

그리고 이제 코드 부분에서 살펴보면 일단 원화 팩터 형태로 어레이 값을 두 개를 가지겠죠?

input을 두 개?

그래서 you가 있는 곳에 1, goodbye가 있는 곳에 1 그리고 초기의 웨이트는 아시다시피 랜덤한 이니셜라이즈 된 값을 가지게 되고 사이즈의 3 같은 경우에 차원수는 제가 정해주게 되는 값입니다.

그래서 이 차원을 제가 정해주기 때문에 그런 기존에 TF-IDF 같은 통계 추론 기반에서의 문제점인 스팔스가 해결된다고 생각하시면 돼요.

그리고 이렇게 곱해진 값 w-input과 입력값이 곱해진 hidden layer 1과 hidden layer 2 입력값과 w-input이 곱해진 hidden layer 2를 평균된 게 이 은닉층이라고 생각하시면 되고 나중에 다시 언급하겠지만 이 w-input 값이 단어의 embedding 값이 된다고 생각하시면 됩니다.

그리고 세 번째로 지금 은닉층에 대한 결과까지를 계산했잖아요?

그럼 이제 w-output과 은닉층을 곱해주는 부분에 대해서 계산을 해야 되는데 일단 진행 순서는 그 다음엔 은닉층과 w-output을 곱해가지고 스코어를 계산하게 됩니다.

그리고 이 계산한 스코어에 소프트 맥스를 취해서 각 단어가 나올 확률을 계산해가지고 얘를 정답 레이블과 비교하게 되는데요.

w-output 같은 경우도 초반에 이니셜라이저된 값을 사용하고 스코어 같은 경우는 은닉층과 w-output을 곱한 값이 스코어가 되겠죠?

그리고 이 스코어에 대해서 소프트 맥스를 취한 게 prediction 값이 되고 여기서 왜 소프트 맥스를 취하냐?

딥러닝 모르시는 분들을 위해서 간단하게 이야기 드리자면 기존에 이렇게 스코어 함수 출력 값을 보면 값이 0부터 1이 아니라 마이너스부터 0.몇몇몇까지 지금 굉장히 값이 분포가 다양해요.

그래서 얘를 조금 확률로 변환시켜주기 위해서 그런 exponential 함수를 도입해가지고 분모해서 summation, exponential, summation 그리고 문자에는 exponential 이렇게 취해서 이렇게 되면 전체에 나온 값들을 다 더했을 때 1이 나오게 되거든요.

그래서 이런 형태로 확률의 성질을 반영해주기 위해서 소프트 맥스 함수를 사용한다고 생각하시면 됩니다.

그래서 정리 다시 드리자면 입력 값 원하 벡터 형태로 두 가지 받았고 w-input을 이니셜라이저 해가지고 두 개를 곱해서 히든 레이어 만드는데 히든 레이어 같은 경우는 이니셜라이즈와 input을 곱한 거에 평균을 낸다.

그리고 w-output도 이니셜라이즈 처음에 하고 얘를 인넥층과 곱해서 출력층의 점수를 만든 다음에 얘를 확률로 바꾸기 위해서 소프트 맥스를 취해주고 그리고 얘를 이제 정답 레이블과 비교하게 되는데 보통 멀티 레이블인 경우에선 크로스 엔트로피 로스 많이 사용하니까 해당 로스 사용해서 계산해주면 됩니다.

그리고 마지막으로 이제 로스를 계산한 값을 가지고 백 프로파게이션을 하게 되죠.

이 부분에 대해서는 이제 그런 소프트 맥스에 대한 백 프로파게이션 그런 거 될 때 공식 같은 게 있어가지고 공식 바로 적용했는데 소프트 맥스의 그런 역전파 값은 prediction의 answer값, bang 값이거든요.

그래서 이거 그냥 pi에 대해서 prediction 값에 대해서 label값 뺀 거 그대로 사용하시면 되고요.

그래서 실제 저도 그대로 사용해서 answer값에서 아까 예측한 pred값을 그냥 뺐습니다.

그리고 이제 이 델타, 저희 w-output에 대한 그런 백 프로파게이션 역전파 값을 계산해야겠죠.

그거는 이제 np.outer를 통해서 계산을 할 수가 있는데 아까 봤던 히든 레이어 은닉 증거, 그리고 그런 소프트 맥스에서 발생했던 그런 델타 역전파 값을 outer를 취하면 weight에 대한 output을 계산할 수가 있고요.

그리고 이제 weight에 대한 output 계산했으니까 input에 대한 output도 계산을 해야겠죠.

그 부분에 대해서는 이제 np.dot을 통해서 da 값을 계산할 수가 있습니다.

그리고 dw, 방금 부분 잘못 설명했는데 히든 레이어에 대한 역전파 값을 계산한 거고요.

여기서 da에서, 그리고 여기서 이제 weight input에 대한 역전파 값을 아까와 같이 np.outer라는 함수를 통해서 계산을 하게 된 겁니다.

그 다음에 이제 역전파 통해서 weight 업데이트 하는 거는 기존하고 동일하게 weight의 input에다가 running rate를 뺀 다음에 그리고 아까 계산했던 델타 weight를 곱해가지고 계산을 할 수가 있고 이렇게 weight가 지금 업데이트 되잖아요.

이걸 이제 에폭 한 번 돈 건데 weight를 이제 한 번이 아니라 열 번, 백 번 이렇게 반복해서 돌다 보면 어느새 조금 괜찮은 weight 값이 가지게 되고 이 weight가 바로 그런 단어들의 embedding 값을 의미한다고 생각하시면 됩니다.

그래서 여기까지는 output 계산하는 거 동일하고요.

지금 수행한 게 사실 이 부분이잖아요.

say를 통해서 you와 goodbye에 대한 거를 맞추는 부분이잖아요.

그래서 얘만 수행하는 게 아니라 이제 샵3부터 샵8까지 다른 맥락에 대해서도 동일하게 수행해 줄 수가 있어요.

그러면 이제 하나의 문장에 대해서만 총 8가지의 task를 수행하게 되는 거예요.

그래가지고 이렇게 한 번 수행하고 다른 문장들 있으면 다른 문장이나 문서들에 대해서도 똑같이 word2vec 진행해주고 그렇게 하면 15호 과정이 끝나고요.

15호하고 그 스킵그램도 다음에 나오는 스킵그램도 알고리즘 상으로는 굉장히 똑같아요.

근데 차이점이 하나가 있다면 아까는 input 값을 이렇게 두 개를 받고 output은 하나가 출력이 된 구조였잖아요.

근데 얘는 반대로 input은 하나를 받고 output은 두 가지로 출력이 되는 구조인 거죠.

그래서 내부적인 알고리즘은 동일한데 중심 단어와 주변 단어는 동일하지만 output 값만 달라진다고 생각하시면 돼요.

그래서 알고리즘 아까 설명해가지고 이 부분은 간단하게 포인트만 집어서 설명하고 넘어갈게요.

그래서 일단 입력 값은 원합 벡터 형태의 입력 값을 받습니다.

그래서 여기서는 입력이 하나죠.

say 하나만 들어오기 때문에 say를 통해서 say를 입력 값으로 원합 벡터 형태로 하나 가지고 you와 goodbye라는 output 두 가지를 맞추는 테스트라고 생각하시면 됩니다.

그리고 주변 단어는 you와 goodbye, 중심 단어는 say 하나, 윈도우 크기는 1이 되는 거죠.

그리고 이제 입력을 받았으니까 입력 값을 weight input하고 곱해줌으로써 은닉층의 값을, 은닉층의 weight 값을 만들어줄 수 있고요.

그리고 이 만든 은닉층의 값을 weight output과 곱해줌으로써 그런 스코어를 만들어줄 수가 있는데 얘가 확률이 아니니까 softmax를 취해서 확률로 변환을 해줘야 된다.

그리고 멀티레이블이니까 cross entropy loss를 계산해줘야 되고 참고로 이거는 지금 backpropagation이 두 부분에서 loss가 발생하잖아요.

그래서 이 부분을 summation을 해가지고 backpropagation을 진행을 해주더라고요.

그래서 weight 같은 경우는 np.outer를 통해서 delta weight를 계산할 수가 있고요.

마찬가지로 input에 대해서도 np.outer를 통해서 계산할 수가 있고 그리고 da 같은 경우는 np.dot을 통해서 계산할 수가 있고

얘를 이제 update 같은 경우는 새로운 weight 같은 경우는 기존의 weight에 running rate를 곱한 값을 delta에다가 곱한 다음에 빼줌으로써 수정을 할 수가 있다는 것입니다.

그리고 마찬가지로 weight output에 대해서도 동일하게 진행해줄 수 있고요.

그리고 얘도 동일하게 지금은 2번의 문맥에 대해서만 진행했으니까 3번부터 8번까지 문맥에 대해서도 동일하게 진행해주시면 됩니다.

근데 아까 언급했듯이 skit-gram이 앞에 봤던 15호보다는 성능이 되게 좋아요.

근데 그 이유가 뭐냐면 일단 skit-gram이 풀려는 테스트가 15호보다 훨씬 어렵거든요.

15호 같은 경우는 say를 맞추려고 you와 goodbye를 통해서 say를 맞추는 그런 두 가지 단어를 통해서 하나를 맞추는 건데 얘 같은 경우는 say를 통해서 두 가지 양옆의 단어를 맞추잖아요.

그래서 딥러닝이 좀 더 어려운 테스트를 수행하면서 더 이제 학습을 똑똑하게 진행한다?

좀 더 어려운 테스트를 수행하는 거죠.

그렇기 때문에 보통은 skit-gram을 많이 사용해서 코드를 작성해주시면 됩니다.

그리고 다른 문맥에 대해서 진행하면 되고 이거를 effort급 반복해서 학습 진행해주셔야 되고요.

그리고 패키지 같은 경우는 이제 jenshin 패키지 사용해서 진행하면 되는데 잠시만요.

코드 간단하게 한번 실제 코드 작성한 거 통해서 간단하게 한번 살펴보도록 하겠습니다.

그래서 컨텐츠 기반의 추천 시스템에서 Word2vec을 이용한 추천 시스템 샷1 부분 여기로 와주시면 되고요.

이거는 조금 뒷부분에 아마 모델 돌아가는 게 속도가 느려가지고 그 부분은 조금 제가 스킵하면서 넘어갈 수 있는 거는 조금 양해 부탁드립니다.

Word2vec 같은 경우 일단은 jenshin 패키지를 이용해서 진행을 할 수가 있는데요.

이 부분이 Word2vec의 알고리즘을 호출해주는 부분이라고 생각하시면 됩니다.

패스 같은 경우는 각자 경로에 맞춰주시면 되고 저희 같은 경우는 캐그를 사용하시는 분은 그대로 치시면 됩니다.

데이터 같은 경우는 movie data 그대로 사용할 건데요.

movie data 같은 경우 조금 타임스탬프 시간이 순서가 조금 복잡한 경우가 있어가지고 아 이게 순서가 조금 섞여서 시간순으로 정렬해주는 함수인 salt.values를 통해서 순서를 정렬해주도록 하겠습니다.

여기로 보시면 작은 값부터 큰 값까지 순서대로 정렬된 거를 볼 수가 있고요.

아까 봤던 메타 데이터의 정보도 불러와서 타이틀이나 이름이나 이름을 정렬되면 불러와서 타이틀이나 오버뷰 같은 것들을 활용하기 위해서 불러와줍니다.

이번에는 오버뷰 말고 오리지널 부분 조금 활용해 볼 건데 그래가지고 한번 일단 메타 데이터의 id하고 여기 movie의 id하고 컬럼명이 일치하지가 않더라고요.

그래서 컬럼명이 일치해주기 위해서 일단 얘도 movie의 id로 이렇게 컬럼명 변경해주셔가지고 둘을 여기서 조인을 해주는 과정을 표현합니다.

참고로 이게 id 값 같은 경우 보통 int 형태로 많이 제공이 되잖아요.

숫자여가지고 근데 이제 데이터마다 어떤 데이터는 스트링 형태로 돼 있는 경우도 있고 어떤 형태는 인트형으로 돼 있는 경우도 있더라고요.

그래서 둘을 지금 동일하게 스트링 형태로 맞춰주기 위해서 s 타입으로 스트링으로 변경해준 다음에 둘을 조인을 하도록 하겠습니다.

함수는 pd점 벌지를 통해서 하면 돼요.

pd점 벌지를 통해서 함수 조인하면 맨 끝에 오리지널 타이틀 부분 이렇게 잘 맵핑된 걸 볼 수가 있죠.

그 다음에 이제 오리지널 타이틀에 메타 데이터 같은 게 결집지가 되게 많더라고요.

제가 봤을 때는 한 영화 만 개 중에 9천 개 넘게는 있었던 것 같았는데 그래서 실제 결과는 잘 안 나오는데 사용법만 어떻게 되는지 보여주기 위해서 예시로만 보여드릴게요.

그래서 일단 오리지널 타이틀에 결집지 있는 부분은 전부 제거해주고요.

아까 봤듯이 난 룰이라는 함수를 통해서 사용할 수 있습니다.

그리고 오리지널 타이틀에 그런 거 유저마다 어떤 영화를 봤는지를 계산하기 위해서 오리지널 타이틀의 유니크 부분만 따로 추출합니다.

그럼 이제 유저 1이 이 영화 타이틀을 보고 이 영화 타이틀을 봤는지에 대한 걸 알 수가 있잖아요.

예를 들어서 유저 1 같은 경우 순서대로 J. N. Splint Bob Strike 100을 본 다음에 바이브멘트 디마 이런 영화를 봤고 유저 3 같은 경우 300을 본 다음에 더 킬링 그 다음에 숄드버스 파인딩 네버랜드 이런 걸 본 걸 알 수 있어요.

여기서 재미있는 점은 사실 이러면 이런 걸 통해서 제가 하려는 게 뭐냐 이 영화 제목 하나하나를 그냥 단어로 보고 이 영화 간의 유사도를 어떤 영화를 순서대로 봤는지를 통해서 유사도를 계산하려고 해요.

그래서 만일 해리포터 시리즈가 있는데 해리포터 마법사의 돌 그 다음에 비밀의 방 맞나?

비밀의 방 그리고 아즈카반의 제수 이렇게 이어지는데 만일 비밀의 방 양옆에 해리포터 시리즈를 많이 본다면 해리포터 간의 유사도가 많이 높게 나오겠죠 워드투백 입장에서 왜냐하면 워드투백 알고리즘이 내 주변에 어떤 영화들이 나오는지 어떤 단어들이 나오는지를 통해 유사도를 계산한다고 했으니까 주변의 영화들이 뭐가 나오는지를 통해서 유사도를 계산할 거예요.

그래서 방금 봤던 이 영화들의 순서목록을 센텐스로 저장해서 기록을 하도록 하겠습니다.

그래서 센텐스를 출력하면 이런 형식으로 가지는데요.

참고로 이게 사용자 1에 대해서 어떤 영화를 봤는지 다음은 사용자 2에 대해서 어떤 영화를 봤는지 그 항목들이 타이틀 형태로 리스트로 저장이 된 거고 여기에서 코드에서 보면은 append라는 것부터 천천히 이야기 드리면 append 함수는 리스트에 입력값들을 저장해주기 위해서 사용하는 함수예요.

그래서 user sentence라는 항목을 sentence라는 리스트에 append를 하면 항목에 하나하나씩 담기게 되고요.

그리고 이게 지금 형태가 스트링이잖아요.

그래서 map-string이라는 걸 하면은 전체 리스트 안에 담긴 모든 원소들이 스트링으로 변형이 되는 것을 맵을 통해서 합니다.

그래서 맵이 뭐냐, 리스트 내 모든 원소에 대해서 스트링이라는 이 함수를 적응해주기 위함이에요.

왜 이거 해주냐면 아까 봤듯이 아까 봤던 300 같은 경우는 int 형태가 있고 얘는 스트링 형태가 있어서 형태 스트링으로 통일 안 시켜주면 중간에 에러 발생해서 해줬습니다.

그리고 genshin 같은 경우 이제 embedding network 이렇게 함수 작성할 수 있는데요.

예를 들어서 genshin 모델에서 word2vec이라는 함수를 import를 해준 다음에 아까 만들어준 sentence를 이렇게 입력을 받고요, 데이터 형태로.

그리고 size는 weight의 크기를 얼마나 정할지 window는 양옆의 주변 단어를 몇 개까지 볼지 workers는 cpu 자원을 몇 명이서 학습에 참여할지 iteration은 fork를 200바퀴 몇 바퀴 돌지 sg는 그런거 sg0인 경우에는 cbool 방식을 사용하고 sg1인 경우는 그런 skitgram을 사용한다고 생각하시면 됩니다.

이게 도는게 시간이 조금 걸려서 동거에 대한 결과 값을 미리 보여드릴게요.

이렇게 돌면 돌아가고 여기서 wv라는게 가중지급 벡터 가지고 제가 입력한 스파이더맨 영화에 대해서 유사도 계산할 수가 있는데 스파이더맨하고 유사한게 snowcake, snowwhite 이렇게 나왔는데 제가 봤을 때 얘 같은 경우는 제대로 학습이 된 것 같지는 않더라고요.

그래서 아까 tf, idf 같은 경우 여기서 그냥 간단하게 toy story 이런 것만 해도 잘 됐었는데 이런 거 보면 안 되는 경우도 있잖아요?

그래서 조금 상황에 맞게 추천시킨 모델도 여러 개 비교해보면서 적용하는 게 좋다 생각 들고 메타 데이터가 잘 구축이 안 된 경우에 대해서는 컨텐츠 기반 모델 같은 경우 잘 안 되더라고요.

그래서 그런 점에서 조금 아쉬운 부분이 있었습니다.

이런 컨텐츠 기반의 장점 같은 경우를 좀 설명드리자면 허버 필터링은 아이템 피처를 사용하기 때문에 추천해준 이유에 대해서 되게 잘 표현하기가 좋아요.

설명하기가 좋아요.

그래서 글 같은 경우 유사도 통해서 계산이 됐다.

아 이 글이 진짜 유사객화네 이런 조금 의미 파악이 되고 그리고 아까 무슨 콜드 스타트나 관련된 그런 언급들 많이 해주셨잖아요.

추천해줄 때 가장 문제가 콜드 스타트라는 건데 처음 들어온 사용자도 있을 수 있고 처음 작성된 영화, 처음 작성된 글, 처음 본 영화 이런 것들이 있을 수 있잖아요.

그러니까 얘같이 아예 최초에 등장하는 애들은 학습이 안 됐으니까 그런 거 추천해주기가 어려운데 근데 컨텐츠 기반의 모델은 아이템 들어올 때마다 임베딩 값 계산하고 바로 유사도 때리면 돼가지고 되게 추천해주기 편해요.

그런 콜드 스타트 문제에 대해서도.

하지만 단점은 아이템 피처를 좀 정확하게 추출을 해야 하기 때문에 제대로 추출을 못하면 정확도가 많이 낮습니다.

그래서 도메인 지식을 도메인 논리지에 대해서 분석이 많이 필요해요.

예를 자연어 처리할 때 어떻게 자연어 처리해야 되는지 이미지가 있으면 이미지 처리할 때 어떻게 해야 될지 그리고 아까 봤듯이 메타 데이터가 잘 된 곳이 사실 그렇게 많지가 않아요.

그래서 메타 데이터 활용하기도 어렵고 그래서 많은 어려움이 있지만 어려움이 있습니다.

그래서 보통은 이 컨텐츠 기반의 모델하고 바로 다음 장에 나오는 협업 필터링 모델을 같이 적절하게 쌓아서 활용을 많이 해주고요.

Summary

TFIDF의 장점은 직관적인 해석이 가능하다는 것이고, 단점으로는 대규모 말몽치를 가질 때 메모리상의 문제점과 높은 차원을 가지기 때문에 매트릭스가 스팔스한 형태를 가져서 문제가 생긴다.

이를 해결하기 위해 워드투백과 추론 기반의 방법이 있다.

워드투백은 대규모 말몽치를 가질 때 메모리상의 문제점을 해결하고, 추론 기반은 맥락을 통해 물음표에 중심 단어를 추출하는 작업을 한다.

Word2Vec은 단어를 벡터로 바꿔주는 임베딩 방법론으로써 단어 간의 유사도를 반영하고, 각 단어가 주변에 나오는 단어들로 정의해 벡터로 맵핑하는 것이다.

이를 통해 비슷한 위치에 등장하는 단어들은 비슷한 의미를 가진다고 생각할 수 있고, 단어나 구매 상품을 이 벡터로 맵핑하여 벡터 간의 유사도를 계산하는 것이다.

이를 이용하는 방법은 두 가지가 있으며, 일단 스킵그래미가 성능이 더 좋다고 한다.

15호 방법은 주변 단어를 기준으로 중간 단어를 예측하는 방법이며, 스킵그래미는 기준 단어 주변의 윈도우 크기만큼 단어를 보고 예측합니다.

이를 딥러닝으로 응용하면 입력값이 원화 팩터 형태로 들어오면 두 칸에 대해 1을 가진 값과 0을 가진 값을 출력합니다.

그건 단어 사이의 관계를 고려하기 위해서 이렇게 합니다.

입력값으로 you와 goodbye, 출력값으로 say를 받아 입력층의 웨이트와 곱해 은닉층을 만든 뒤 이를 출력층과 곱해 소프트 맥스를 취해 스코어를 계산하고 비교하는 딥러닝 모델을 설명하고 있다.

입력값과 출력값 사이의 관계를 고려하기 위해 소프트 맥스를 취하고 있으며, 웨이트와 레이블은 랜덤한 이니셜라이즈 값을 가지고 차원은 사용자가 정하는 값이다.

Deep learning is a way of using algorithms to learn from data.

It involves taking inputs, such as scores from a score function, and using an exponential function to convert them into probabilities.

This is done through a softmax function, which takes the scores and divides them by their sum to give a probability distribution.

The cross-entropy loss is then used to compare the predicted values to the labels, and backpropagation is used to update the weights.

The delta from the softmax is used with np.outer to calculate the weight output.

가중치 계산을 위해 np.dot과 np.outer 함수를 사용하고, 러닝 레이트를 뺀 값과 델타 가중치를 곱해 업데이트하는 것으로 여러 문장과 문서들에 대해 word2vec을 수행하며 각 문장에 대해 8가지의 task를 수행한다.

스킵그램과 비슷하지만, 이때는 input 값이 하나이고 output 값이 두 개가 되는 구조이다.

알고리즘은 입력 값을 원합 벡터 형태로 하나 받고, 주변 단어는 you와 goodbye, 중심 단어는 say 하나, 윈도우 크기는 1이 되는 걸로 설정한다.

이후 입력 값과 weight input을 곱해 은닉층의 값을 만들고, 이를 weight output과 곱해 스코어를 만들고 softmax로 확률로 변환하고 cross entropy loss를 계산해 backpropagation을 진행한다.

np.outer를 통해 weight, input, delta weight를 계산하고, running rate를 곱해 새로운 weight를 만들어 멀티레이블을 업데이트한다.

skit-gram은 15호보다 테스트가 더 어려워 성능이 좋다.

딥러닝은 좀 더 어려운 테스트를 수행하는 것으로, skit-gram을 많이 사용해서 코드를 작성하고 다른 문맥에 대해서 진행하며 effort급 반복해서 학습 진행하는 것이 필요합니다.

jenshin 패키지를 사용해서 Word2vec의 알고리즘을 호출해주고, movie data를 사용해서 시간순으로 정렬해주는 salt.values 함수를 통해 순서를 정렬하고, 메타 데이터의 id와 movie의 id를 컬럼명이 일치하도록 변경하고 이를 조인하는 과정을 거칩니다.

그럼 이 두 영화는 같은 시리즈라는 걸 알 수 있겠죠.

숫자여가지고 다양한 데이터 형태가 있으며, 스트링 형태로 변경하고 조인하는 것을 통해 맨 끝에 오리지널 타이틀 부분을 잘 맵핑할 수 있다.

메타 데이터 같은 것을 결집지로 만들기 위해 오리지널 타이틀에 유니크 부분만 추출하고, 함수를 통해 그 다음 유저마다 어떤 영화를 봤는지를 계산할 수 있다.

이를 통해 영화 타이틀을 단어로 보고 영화 간의 유사도를 계산할 수 있다.

비밀의 방과 해리포터 시리즈는 유사도가 높다.

워드투백 알고리즘을 통해 주변 영화들의 유사도를 계산하고, 사용자별로 본 영화들의 리스트를 저장하는 센텐스를 생성한다.

이를 스트링 형태로 변환하기 위해 map-string을 사용한다.

또한 genshin 모델에서는 word2vec 함수를 import하고 입력한 sentence를 데이터 형태로 받아 weight, window, workers, iteration, sg 등의 값을 설정한다.

시간이 걸리는 동거 결과를 미리 보여주기 위해, 스파이더맨 영화에 대한 유사도 계산을 가중지급 벡터를 통해 가능하지만, 메타 데이터가 잘 구축되지 않은 경우 컨텐츠 기반 모델이 적절하지 않을 수 있습니다.

이러한 컨텐츠 기반 모델의 장점은 허버 필터링을 통해 추천해준 이유가 잘 표현되고, 유사객화를 통해 의미 파악이 가능합니다.

그러나 추천해줄 때 처음 들어온 사용자나 처음 작성된 영화 등을 추천하기 어려운 문제가 있고, 아이템 피처를 정확하게 추출해야하는 단점이 있습니다.

따라서 도메인 지식과 논리를 분석하는 것이 필요합니다.

자연어 처리와 이미지 처리를 할 때는 메타 데이터를 활용하는 것이 어려운 일이다.

그렇기 때문에 이를 극복하기 위해 컨텐츠 기반의 모델과 협업 필터링 모델을 적절하게 쌓아서 활용하는 것이 많다.