추천 시스템 - 아이템의 유사도

nicotina04·2023년 1월 22일
0

추천 시스템

목록 보기
2/2

우리는 앞서 추천 시스템의 정의와 추천 시스템에 사용되는 알고리즘의 대략적인 분류를 알아봤다.

대충 유사한 아이템을 찾아 추천한다는 것은 알겠다... 근데 그 유사한 정도인 유사도는 정확히 어떻게 계산할 수 있단 말인가?

이 포스트에서는 아이템끼리의 유사도를 어떻게 측정할 수 있는지 알아보고자 한다.

콘텐트 기반 필터링에서 아이템의 성분 분석

일단 콘텐트 기반 필터링을 짚고 넘어가자. 콘텐트 기반 필터링은 자기가 구매한 아이템과 유사한 아이템을 찾아 추천해준다.

그런데 그 아이템의 특징이 뭔데 특징이 유사한 아이템을 어떻게 찾느냐는 말인가? 교육받은 인간이야 눈으로 보고 "이건 에어컨이구나~"하고 넘어가지만, 우리 컴퓨터는 알 수 있을 리가 만무하다.

물론 쇼핑몰에서 볼 수 있는 물건들은 위 사진과 같이 대충 뭐 하는 물건인지 정보가 제공되고 있어서 그나마 낫다.

하지만 문서 아이템은 어떨까? 나는 경제 뉴스 중에서도 미국 주식과 관련된 뉴스를 추천받고 싶은데 우리 추천 시스템이 어떤 뉴스가 미국 주식 뉴스인지 알 수 있는 방법이 무엇일까?

우리는 이 문제를 해결하기 위해 단어들의 집합인 문서를 보다 컴퓨터가 쉽게 이해할 수 있는 벡터로 바꾸어야 한다. 현재는 이런 데이터를 벡터로 바꿔주는 여러 기법이 있는데 이 포스트에서는 그중 하나인 TF-IDF를 언급하고자 한다.

TF-IDF

TF-IDF는 어떤 말뭉치에서, 그러니까 전체 단어들의 집합에서 특정 단어가 문서에서 얼마나 중요한지 나타내는 수치이다. 이름에서 유추할 수 있듯 TF와 IDF가 각각 합쳐진 것인데 하나씩 알아보자.

TF(Term Frequency)

이름에서 유추할 수 있듯 해당 문서에서 특정 단어가 나타나는 빈도이다. 그러면 이것만 보고 이렇게 생각할 수 있다. "어 그러면 TF가 높으면 중요한 거 아니에요?" 어 아니다. 예를 들어 "안녕하세요." 같은 경우는 별 의미가 없음에도 많이 등장할 수 있다.

이런 문제를 해결하기 위해 IDF가 나온다.

IDF(Inverse Document Frequency)

직역하면 문서 빈도의 역수다. 특정 단어가 나타난 문서의 빈도의 역수를 취한 값이다. 만약 "안녕하세요."와 같이 의미는 없는데 많은 문서에 나타난다면 DF는 커질 것이고 역수를 취한 IDF는 작아질 것이다.

TF-IDF는 다음과 같은 식으로 나타나게 된다.

TFIDF=TF×IDFTF-IDF = TF \times IDF

그래서 TF-IDF이다. 만약 "원자성"이라는 단어가 문서 A에서 많이 나타났지만, 전체적으로 "원자성"을 포함한 문서가 적을 경우 TF-IDF가 커지므로 큰 의미를 갖는다고 볼 수 있다.

그러면 계산은 어떻게 할 수 있을까? 좀 더 자세히 표현하면 다음과 같다.

단어 tit_{i}가 문서 djd_{j}에 나타난 횟수는 TF(ti,dj)TF(t_{i}, d_{j})이다.

전체 문서의 갯수를 NN, 단어 tit_{i}가 존재하는 문서의 갯수를 nin_{i}라고 할 때, IDF는 IDF(ti,N)=logNniIDF(t_{i}, N) = \log \frac{N}{n_{i}}이다.

왜 로그가 붙느냐면 전 세계에서 온라인으로 저장된 문서가 얼마나 있을지를 생각해보자. 엄청나게 많을 것이다. 즉 N이 너무 커서 영향을 많이 미치는 것을 막기 위해 로그를 붙여 그 값을 감소시키는 것이다.

물론 전체 아이템의 수가 많지 않을 것으로 예상되면 로그를 붙이지 않아도 좋다.

물론 정규화를 원하면 다음을 통해 0과 1 사이의 값으로 변환할 수 있다.

TFIDF(ti,dj)(TFIDF)2\frac{TF-IDF(t_{i}, d_{j})}{ \sqrt {\sum(TF-IDF)^{2}} }

이렇게 우리는 아이템을 성공적으로 벡터로 바꿀 수 있었다. TF-IDF 말고도 Word2Vec, FastText 등 다양한 기법이 존재하니 시간이 있을 때 찾아보는 것을 권한다.

유사도 계산

앞서 콘텐트 기반 필터링에서 유사도 계산을 위해서 아이템을 벡터화하는 과정을 거쳤다. 협업 필터링은 사용자가 줬던 평점들이 곧 벡터가 되므로 벡터화를 크게 신경 쓸 필요가 없다.

이제 벡터끼리의 유사도를 구해보도록 하자. 벡터 간 유사도를 구하는 방법은 코사인 유사도, 피어슨 상관계수 등 여러 가지가 있다.

코사인 유사도(Cosine Similarity)

코사인 유사도는 유사도를 계산하는 방법 중 잘 알려져 있으며 아이템 벡터 AA와 아이템 벡터 BB의 내적이 곧 코사인 유사도가 된다.

cosθ=ABAB=iAiBiiAi2iBi2\cos \theta = \frac{A \cdot B}{||A|| \, ||B||} = \frac{\sum\nolimits_{i} A_{i}B_{i}}{ \sqrt{\sum\nolimits_{i} A_{i}^{2}} \sqrt{\sum\nolimits_{i} B_{i}^{2}} }

여기서 각 θ\theta가 작으면 코사인값이 커져 두 벡터가 비슷함을 나타내고 θ\theta가 크면 코사인값이 작아져 두 벡터가 비슷하지 않음을 나타낸다.

피어슨 상관 계수(Pearson Correlation Coefficient)

피어슨 상관 계수는 협업 필터링에서 사용할 수 있는 방법으로 두 변수의 상관관계를 수치로 표현하는 방법의 하나다.

피어슨 상관 계수로 나올 수 있는 값은 [1,1][-1, 1]의 범위를 가지는데 -1은 음의 상관 관계, 0은 상관관계가 없음, 1은 양의 상관 관계를 나타낸다.

유사함을 측정할 때는 값이 클수록 유사한 것으로 판단한다.

협업 필터링에서는 다음과 같은 식으로 계산할 수 있다.

사용자 기반 협업 필터링에서의 피어슨 상관 계수

sa,b=iI(ra,ira)(rb,irb)iI(ra,ira)2iI(rb,irb)2s_{a, b} = \frac{\sum\nolimits_{i \in I} (r_{a, i} - \overline{r_{a}})(r_{b, i} - \overline{r_b})}{\sqrt{\sum\nolimits_{i \in I}(r_{a, i} - \overline{r_{a}})^2}\sqrt{\sum\nolimits_{i \in I}(r_{b,i} - \overline{r_{b}})^2}}

여기서 II는 전체 아이템 집합, aabb는 유사도를 계산할 사용자, rx,ir_{x, i}는 x가 아이템 i에 준 평점, x\overline{x}는 사용자 x가 줬던 평점의 평균이다.

아이템 기반 협업 필터링에서의 피어슨 상관 계수

si,j=uU(ru,iri)(ru,jrj)uU(ru,iri)2uU(ru,jrj)2s_{i, j} = \frac{\sum\nolimits_{u \in U} (r_{u, i} - \overline{r_{i}})(r_{u, j} - \overline{r_j})}{\sqrt{\sum\nolimits_{u \in U}(r_{u, i} - \overline{r_{i}})^2}\sqrt{\sum\nolimits_{u \in U}(r_{u,j} - \overline{r_{j}})^2}}

여기서 iijj는 유사도를 계산할 아이템, UUi,ji, j에 모두 평점을 준 전체 사용자 집합, rx\overline{r_{x}}는 사용자 xx가 준 평점의 평균을 의미한다.

코사인 유사도의 문제점과 보정된 코사인 유사도

앞서 언급한 코사인 유사도는 유사도를 계산하는 좋은 방법이지만 평점 정보로 동작하는 협업 필터링에서는 문제가 있다.

두 사용자 a,ba, b가 아이템 ii를 가장 선호한다고 해보자. 그런데 각각 준 평점이 같지 않으면, 즉 ra,irb,ir_{a, i} \neq r_{b, i}이면 코사인 유사도가 다르게 나타날 수 있다.

쉽게 말하면 평점을 후하게 주는 사람과 짜게 주는 사람은 사실 취향이 비슷할 수 있음에도 불구하고 코사인 유사도는 그렇지 않을 수도 있다는 것이다.

이를 해결하기 위해 각 평점을 정규화하는 방법인 보정된 코사인 유사도(Adjusted Cosine Similarity)가 고안됐다.

아이템 기반 협업 필터링에서 보정된 코사인 유사도는 다음과 같이 계산된다.

si,j=uU(ru,iru)(ru,jru)uU(ru,iru)2uU(ru,jru)2s_{i, j} = \frac{ \sum\nolimits_{u \in U}(r_{u, i} - \overline{r_u})(r_{u, j} - \overline{r_u}) }{ \sqrt{\sum\nolimits_{u \in U}(r_{u, i} - \overline{r_u})^2 } \sqrt{ \sum\nolimits_{u \in U}(r_{u,j} - \overline{r_{u}})^2 } }

이렇게 사용자의 평점 평균을 빼주면 그 사용자의 평균 평점보다 유난히 좋거나 나쁜 평점을 준 아이템을 파악할 수 있으므로 기존의 코사인 유사도보다 더 좋은 결과를 얻을 수 있다.

스피어만 상관 계수

스피어만 상관 계수는 피어슨 상관 계수와 마찬가지로 범위 [1,1][-1, 1]의 값을 가지며 평점들을 평점이 큰 순서부터 높은 순위로 바꿔 계산한다.

sa,b=16iIdi2n(n21)s_{a, b} = 1- \frac{6\sum\nolimits_{i \in I} d_{i}^{2}}{n(n^2 -1)}

nn은 전체 아이템 개수, did_{i}aabb가 아이템 ii에 준 평점을 순위로 변환한 다음 그 둘의 차를 나타낸 값이다.

스피어만 상관 계수는 평점의 분포가 극단적일 때 유용하지만 중복 평점이 많은 경우에는 유사도 계산이 어렵다고 한다.

지금까지 추천 시스템에서 유사도를 어떻게 계산하는지 알아보았다.

0개의 댓글