자카드 계수(Jaccard index)

Document.H
h_document
Published in
10 min readSep 19, 2021

클러스터링 분석 시 거리 계산을 할 때 변수의 종류에 따라 사용할 수 있는 유사도 거리가 다양함을 배웠다. 그중 명목형 변수에서는 Jaccard disttance, Soremsem-Dice, Anderberg, Ochiai, Simple Matching, Rogers and Tanimoto, Hamming Distance 등을 사용된다. 이 중 희소 데이터(sparse data)가 많은 경우 사용하는 자카드 계수에 대해서 살펴보도록 한다.

들어가기 전… 상관관계란?

프로덕트를 분석하다 보면 ‘A와 B의 상관관계가 높은가요?’라는 질문을 종종 받게된다. ‘상관관계 : Correlation can measure the linear relationship.’ 정의를 그대로 해석해보면 상관관계는 선형 관계를 측정할 수 있는 지표를 의미합니다. 이 말은 Non-linear relationship의 상관관계를 구할 수 없다는 말이기도 합니다.

예를 들어 다음과 같은 데이터 셋이 있다고 했을 때 (x= [-3, -2, -1, 0, 1, 2, 3], y= [9, 4, 1, 0, 1, 4, 9]) 상관관계는 0으로 나옵니다. 하지만 이 데이터들은 y=x²라는 함수로 표현되며, 이는 x와 y는 서로 연관이 되어 있음을 의미합니다.

즉 ‘상관관계가 0이다’라고 하면 상관관계가 없다고 하기보다는, 선형 관계가 아니다 라고 하는 것이 좀 더 정확한 표현입니다.

유사도 (Similarity)

데이터를 클러스터링/분류하기 위해서는 기준이 있고, 그 기준 중에 하나가 Similarity (↔ Dissimilarity = distance)입니다. 유사도는 두 개의 데이터 성질이 얼마나 닮았는지를 나타냅니다. 유사도의 범위는 [0,1]. 비유사도는 유사도와 반대 개념으로 범위는 [0~무한]으로 측정됩니다.

유사도를 측정하는 방법론은 다양합니다. 그중 데이터 값이 어떻게 이루어져 있는지에 따라서 분류 방법을 나눌 수 있습니다.

Sparse data (희소 데이터, 데이터 값이 0이 많은 데이터)

분석을 하다 보면 sparse data를 접하게 되는 경우가 많습니다. 예를 들어 기능과 리텐션의 상관관계를 분석하는 경우, 유저들이 특정 기능을 사용하는 경우와 리텐션에 집계되는 케이스가 각각 많을 수도 적을 수도 있습니다. 추천 시스템에서도 sparse data가 존재할 수밖에 없습니다. 유저가 서비스를 보았거나, 샀어도 평점을 남기는 경우보다 남기지 않는 경우가 더 많이 존재하고 이때 sparse가 생성되게 됩니다.

희소 데이터의 유사도를 측정할 때는 주로 Jaccard coefficient나 Cosine similarity를 사용한다고 합니다.

Non-sparse(=dense) data (밀집 데이터, 데이터 값이 0이 거의 없는 경우)

희소 데이터의 반대 개념으로, 주로 사용하는 유사도 거리는 Euclidean Distance와 Correlation이 있습니다.

Jaccard Coefficient

한 줄로 설명하면 두 집합의 교집합을 합집합으로 나눈 값을 자카드 지수라고 합니다. 두 개의 명목형 변수가 존재할 때 생길 수 있는 케이스는 총 4가지가 있습니다. a =(0,0), b=(1,0), c=(1,1), d=(0,1). 자카드는 이때 a=(0,0)을 분모, 분자에서 고려하지 않고 상관계수를 구하게 됩니다. c/(b+c+d)가 자카드 계수가 됩니다.

자카드 계수의 장점

  1. 0이 많은 데이터에서는 해당 부분을 고려해줍니다. (장점 1)
  2. A와 B는 같은 사이즈일 필요가 없습니다. (자연어 분석인 기준에서 의미하는 것 같습니다.)

장점 1) 0이 많은 데이터 고려
Jaccard Coefficient for binary data

J = f11 / f11+f10+f01 (둘다 매칭 된 것 / f00 제외한 매칭)
f11 : 2, f00 : 3, f10 : 3, f01 : 2
J = 2 / (2+3+2) = 2/7

만약 위 예시를 자카드 계수가 아닌 Simple Matching Coefficient를 binary data 에서 사용하게 된다면 ..

SMC= (2 +3) / (2+3+3+2) = 5/10 로 자카드 계수와 다른 결과가 나오는 것을 확인할 수 있습니다. (SMC 자세한 설명)

자카드 계수의 단점

  1. 0과1이 교차되는 경우에 jaccard 는 상관관계를 구현하지 못한다. (단점 1 참고)
  2. 음의 상관관계를 알지 못한다. (산점도를 비롯한 그래프로 재확인 필요) (단점 2 참고)
  3. 얼마나 자주 발생하는지(term frequency)를 고려하지 않는다.
  4. 정규화(normalize) 작업이 필요할때가 있다

단점 1) 0과1이 교차되는 경우에 jaccard 는 상관관계를 구현하지 못한다

x와 y는 서로 교차로 발생하고 있습니다. 두 데이터는 교차로 발생하고 있기 때문에 상관관계가 없다고 보기 힘듭니다. 하지만 자카드 지수는 매칭되는 케이스가 없으므로 0으로 나타나게 됩니다.

단점 2) 음의 상관관계를 알지 못한다.

y는 x에 대해서 음의 상관관계를 가지고 있습니다( y=-x). 하지만 자카드에서는 케이스의 합집합과 교집합으로만 수치를 표현하기 때문에 음의 상관관계를 표현할 수 없습니다.

(0,0)을 제외해주는 것은 왜 중요할까요?

‘행동이 발생하지 않았다면, 결과가 발생하지 않는다’의 조건이 반영하기 때문입니다. 우리는 행동에 따른 결과를 알고 싶은데 0을 제외하지 않게 된다면, ‘A: 행동이 발생하지 않았고 결과도 발생하지 않았다. 그렇기 때문에 A는 관계가 있다’는 모순적인 내용이 분석 결과에 포함됩니다. ‘행동’을 하지 않았지만 결과에 영향을 주게 되는 것이지요.

자카드 계수와 함께 sparse data의 상관관계를 분석할 때 사용하는 계수는 cosine 유사도입니다.

Cosine Similarity

cosine = A와 B의 내적 / (A의 절대값 * B의 절대값)

두 데이터(벡터) 간의 코사인 각도를 이용하여 구할 수 있는 두 데이터의 유사도를 의미합니다. 두 벡터의 방향이 완전히 동일한 경우에는 1의 값을 가지며, 180°로 반대의 방향을 가지면 -1의 값을 갖게 됩니다. 90°의 각을 이루면 분자에 위치한 A와 B 내적의 값이 0으로 상관관계가 0이 됩니다.결국 코사인 유사도는 -1 이상 1 이하의 값을 가지며 값이 1에 가까울수록 유사도가 높다고 판단할 수 있습니다.

장점

  1. 벡터의 규모(크기)가 중요하지 않다. → 모수가 적을때 장점을 가진다
  2. 다양한 차원이 존재할때 유사도 구분이 뚜렷할 수 있다. → 여러가지 지표들을 비교할 때 유사도를 비교적 뚜렷하게 구분할 수 있다.
  3. 자카드와 마찬가지로 (0,0) match는 고려하지 않는다

단점

  1. 상호 상관관계의 feature(키, 몸무게 등)를 갖는 원소들간의 유사도를 계산할때에 좋지 못하다. Euclidean vs. Cosine Distance
  2. 위치(vector) 의 기준을 무엇으로 잡는지에 따라 유사도(각도)가 달라질 수 있다.
  3. Binary data 에서는 사용할 수 없다.

Jaccard 와 Cosine 차이점

자연어 분석 기준으로 설명이 되어 있습니다.

  1. 자카드 유사성은 각 문장/문서마다 고유한 단어 집합만 사용하는 반면 코사인 유사성은 벡터의 전체 길이를 필요로 한다.문장 1의 ‘친구’라는 단어를 여러 번 반복하면 코사인 유사성이 바뀌지만 자카드 유사성은 변하지 않는다는 것을 의미합니다.
    1. AI is our friend and it has been friendly
    2. AI and humans have always been friendly

2. 자카드 유사성은 중복이 중요하지 않은 경우, 코사인 유사성은 유사성을 분석하면서 중복이 중요한 경우 좋다. 두 가지 제품 설명의 경우, 단어를 반복해도 유사성이 줄어들지 않으므로 Jaccard 유사성을 사용하는 것이 더 좋습니다.

마무리하며…

데이터들을 쪼개 보면서 상관관계가 어떻게 변하는지 알아봤지만, 중요한 것은 실제 데이터들이 어떤 관계가 있는지 찾는 것이지, 높은 상관계수를 찾기 위해 데이터를 분류하고 쪼개는 행동을 하는 것은 정확성을 낮추는 일이다. 따라서 각 케이스에 맞는 분석을 선택해서 진행해야 한다.

  • 기능을 사용하는 유저가 많다면 →피어슨 상관분석
  • 기능을 사용하는 유저가 많지 않고
    사용 유무로 분석하고 싶다면 → 자카드
    빈도를 고려하고 싶다면 →코싸인

bigquery의 array 함수를 사용해서 자카드 계수를 구하는 방법을 만들었다. python에서는 sklearn.metrics 라이브러리(jaccard_score)를 사용할 수 있다.

-- 1주차 n회 사용 여부에 따른 2주차 리텐션 자카드 계수 구하기 (bigquery)
with
jaccard_base as ( select arr.n, concat(arr.n, '번 이상 사용'),
-- x : 1주차 사용 횟수, y : 2주차 방문 여부
count(distinct case when use_w1_cnt >=arr.n and search_w2=1 then user_id else null end) as w11,
count(distinct case when use_w1_cnt>=arr.n and search_w2!=1 then user_id else null end) as w10,
count(distinct case when use_w1_cnt<arr.n and search_w2=1 then user_id else null end ) as w01,
count(distinct case when use_w1_cnt<arr.n and search_w2!=1 then user_id else null end) as w00
from (
--n회 사용횟수를 array함수로 구현
select n from (select generate_array(1,20, 1) arr ),unnest(arr) as n) as arr,
`테이블`
group by 1 ,2
)
select *, w11/(w11+w10+w01) as jac
from jaccard_base
order by 1

--

--

Document.H
h_document

좋은 질문을 던지고 싶은 데이터분석가