연관성 분석 (장바구니 분석) 이라는 건 서로 다른 두 인자 사이의 관계를 분석하는 것입니다. 마트에서 장을 볼 때 여러가지 물건을 살 텐데, 예를 들면 생수와 우유가 큰 관계가 있는지, 또는 콜라와 치킨은 큰 관계가 있는지, 둘 중에 어떤 것들의 조합이 더 관계가 높은지와 같은 것을 알아보는 데에 쓰입니다.
이걸 장바구니 분석이라고도 하는 이유가 여기에 있습니다. 사람들이 장을 보는데 어떤 물건들을 주로 같이 사는지를 알아보고, 그 물건들을 가까운데 배치하는 등의 작업을 통해 매출을 올리려는 거거든요.
대략의 순서는 1. 데이터를 정의하고 2. 데이터를 바탕으로 관계 지표를 정의한 후 3. 지표 비교를 통해 우선순위를 매기는 겁니다. 사실상 의사결정을 위해 3단계가 가장 중요하긴 하지만, 일단 1단계와 2단계를 거쳐서 지표를 만들고 나서 진행할게요. 구체적으로 어떻게 하는 건지 알아보겠습니다.
데이터 정의하기
먼저 마트의 포스를 봤더니 아래와 같은 거래 내역이 있다고 하겠습니다. 이 포스 데이터를 기반으로 어떤 상품들 사이에 상관관계가 있는지 알아보겠습니다. 그러려면 아래의 데이터를 이용해서 추가적으로 데이터를 정의하는 것이 필요합니다.
ID | 상품 구매내역 |
1 | 사과주스, 콜라 |
2 | 우유, 사과주스, 세제, 생수 |
3 | 사과주스, 우유 |
4 | 사과주스, 세제, 콜라 |
5 | 세제, 콜라, 생수 |
6 | 콜라, 사과주스, 우유 |
7 | 생수, 콜라 |
8 | 생수, 사과주스 |
상품별 구매횟수
가장 먼저 상품별 구매횟수를 알아야 합니다. 예를 들면 사과주스는 총 몇회 구매가 되었고, 생수는 총 몇회 구매되었다는 식으로 아래와 같이 데이터를 생성합니다.
상품 | 구매횟수 |
사과주스 | 6 |
우유 | 3 |
세제 | 3 |
생수 | 4 |
콜라 | 5 |
전체 8건의 거래 중에서 사과주스는 6회가 구매되었다는 뜻입니다. 다음 단계로 넘어갈게요.
상품 간 동시구매횟수
이번에는 두개의 상품을 동시에 구매한 횟수를 데이터로 생성하겠습니다. 예를 들면 사과주스와 우유를 동시에 구매한 거래는 몇회나 될까? 라는 식입니다. 아래의 표와 같이 생성합니다.
상품1 | 상품2 | 동시구매횟수 |
사과주스 | 우유 | 3 |
사과주스 | 세제 | 2 |
사과주스 | 생수 | 2 |
사과주스 | 콜라 | 3 |
우유 | 세제 | 1 |
우유 | 생수 | 1 |
우유 | 콜라 | 1 |
세제 | 생수 | 2 |
세제 | 콜라 | 2 |
생수 | 콜라 | 2 |
위 표를 해석해 보면 사과주스와 우유를 동시에 구매한 횟수는 3건이라는 뜻입니다. 여기까지 기본적인 데이터를 정의하는 과정이었고, 이 다음에 이제 이 데이터들을 이용해서 여러가지 지표들을 만들어내는 작업을 할 겁니다.
연관성 지표 정의하기
연관성 지표에는 크게 지지도, 신뢰도, 향상도 세개가 있습니다. 각각 다음과 같은 뜻을 가집니다.
- 지지도 : 두개의 상품을 같이 구매할 확률
- 신뢰도 : 상품1을 구매했을 때 상품2를 구매할 확률 (조건부 확률)
- 향상도 : 상품2를 구매할 확률 대비 상품1을 구매했을 때 상품2를 구매할 확률이 얼마나 더 큰가
지지도까지는 금방 알겠는데 신뢰도와 향상도는 아무래도 예시로 알아보는 게 나을 거 같아요. 아래에서 하나하나씩 알아보겠습니다.
지지도 계산하기
지지도는 두개의 상품을 같이 구매할 확률이라고 했습니다. 다르게 말하면 상품1과 상품2를 같이 구매할 확률이구요, 기호로 쓰자면 아래와 같이 쓸 수 있습니다.
P(상품1 ∩ 상품2)
이 지표는 구하기가 쉽습니다. 위의 데이터 정의에서 상품 간 동시구매횟수 테이블을 거의 그대로 사용하면 되기 때문입니다. 전체 구매횟수 (거래횟수) 가 8건이므로, 동시구매횟수를 거래횟수로 나눠주면 됩니다. 아래와 같습니다.
상품1 | 상품2 | 지지도 |
사과주스 | 우유 | 0.375 (= 3/8) |
사과주스 | 세제 | 0.25 |
사과주스 | 생수 | 0.25 |
사과주스 | 콜라 | 0.375 |
우유 | 세제 | 0.125 |
우유 | 생수 | 0.125 |
우유 | 콜라 | 0.125 |
세제 | 생수 | 0.25 |
세제 | 콜라 | 0.25 |
생수 | 콜라 | 0.25 |
신뢰도 계산하기
신뢰도는 상품1을 구매했을 때 상품2를 구매할 확률이라고 했습니다. 좀 더 풀어서 말하면 다음과 같습니다.
- 만약에 어떤 사람이 상품1을 산다면 상품2를 살 확률은 어떻게 되지?
- 다르게 말하면 : 상품1을 구매한 사람이 상품2를 살 확률은?
왜 신뢰도라고 하냐면, 이 지표의 정의 상 숫자가 높으면 높을수록 상품1을 사면 상품2도 무조건 산다는 뜻이기 때문입니다. 예를 들어 만약에 생수와 콜라의 신뢰도가 1이라고 하면, 생수를 산 사람은 무조건 콜라도 산다는 뜻입니다. 하지만 반대는 완전히 같지 않을 수 있습니다. 일단 아래의 정의를 보겠습니다.
P(상품1|상품2) = P(상품1 ∩ 상품2) / P(상품1) = 지지도 / P(상품1)
위의 정의와 같이 생수를 산 사람이 무조건 콜라를 산다고 해서, 콜라를 산 사람이 무조건 생수도 산다고 장담할 수는 없습니다. 상식적으로 봐도 그렇긴 하죠.
일단 계산 자체는 지지도를 상품1을 살 확률로 나누면 됩니다. 그리고 상품1을 살 확률은 이 글 가장 위의 상품별 구매횟수 / 전체 구매횟수를 하면 나오겠죠? 이와 같이 계산한 결과는 아래와 같습니다.
상품1 | 상품2 | 신뢰도 |
사과주스 | 우유 | 0.5 |
사과주스 | 세제 | 0.333333333 |
사과주스 | 생수 | 0.333333333 |
사과주스 | 콜라 | 0.5 |
우유 | 사과주스 | 1 |
우유 | 세제 | 0.333333333 |
우유 | 생수 | 0.333333333 |
우유 | 콜라 | 0.333333333 |
세제 | 사과주스 | 0.666666667 |
세제 | 우유 | 0.333333333 |
세제 | 생수 | 0.666666667 |
세제 | 콜라 | 0.666666667 |
생수 | 사과주스 | 0.5 |
생수 | 우유 | 0.25 |
생수 | 세제 | 0.5 |
생수 | 콜라 | 0.5 |
콜라 | 사과주스 | 0.6 |
콜라 | 우유 | 0.2 |
콜라 | 세제 | 0.4 |
콜라 | 생수 | 0.4 |
지지도보다 표가 훨씬 길어졌습니다. 생수를 산 사람이 우유를 살 확률과, 우유를 산 사람이 생수를 살 확률은 다르기 때문에 모든 경우의 수에 대해 다 계산을 해줘야 해서 그렇습니다. 이 분석의 제약 조건이 여기에서 드러나는데요, 지금 상품이 5종류인 경우에도 경우의 수가 이렇게 많은데, 이거보다 더 늘어나면 어마어마하게 많아지겠죠. 이 제약 조건을 다른 방식으로 처리하는 게 필요할 것으로 보입니다.
향상도 계산하기
향상도는 상품1을 고려하지 않고 그냥 상품2를 구매할 확률보다 상품1을 샀을 때 상품2를 살 확률이 얼마나 더 큰가 하는 것입니다. 심리적으로 상품1을 골랐을 때 상품2를 사자는 마음이 더 간절하게 떠오른다는 거죠. 예를 들면 그냥 치즈를 살 확률보다 와인을 골랐을 때 치즈를 살 확률이 더 큰가? 라는 질문에 대한 답을 해주는 거라고 보면 됩니다. 당연히 향상도가 높을수록 연관성이 높은 상품이겠죠? 정의는 다음과 같습니다.
P(상품1|상품2)/P(상품2) = 신뢰도/P(상품2)
위 식을 와인과 치즈의 예시로 대입해 보자면 이렇습니다. P(와인|치즈)/P(치즈). 한번 이대로 계산해 볼께요. 아래와 같습니다.
상품1 | 상품2 | 향상도 |
사과주스 | 우유 | 1.333333333 |
사과주스 | 세제 | 0.888888889 |
사과주스 | 생수 | 0.666666667 |
사과주스 | 콜라 | 0.8 |
우유 | 사과주스 | 1.333333333 |
우유 | 세제 | 0.888888889 |
우유 | 생수 | 0.666666667 |
우유 | 콜라 | 0.533333333 |
세제 | 사과주스 | 0.888888889 |
세제 | 우유 | 0.888888889 |
세제 | 생수 | 1.333333333 |
세제 | 콜라 | 1.066666667 |
생수 | 사과주스 | 0.666666667 |
생수 | 우유 | 0.666666667 |
생수 | 세제 | 1.333333333 |
생수 | 콜라 | 0.8 |
콜라 | 사과주스 | 0.8 |
콜라 | 우유 | 0.533333333 |
콜라 | 세제 | 1.066666667 |
콜라 | 생수 | 0.8 |
아래에 이야기하겠지만, 정의 상 향상도는 1 이상 되어야 좋은 겁니다. 그냥 치즈를 살 확률이 더 높다면 굳이 와인 옆에 치즈를 놓을 필요는 없잖아요? 이제부터 저 계산 결과를 비교하는 방법을 알아보겠습니다.
우선순위 정하기
일단 계산은 쭉 해서 나왔고, 그러면 이제 저 계산 결과를 가지고 소위 나래비를 세우든지 뭘 하든지 해서 원하는 걸 뽑아내야 합니다. 그러자고 하는 거니까요. 여기에서 대체로 룰은 아래와 같습니다.
- 지지도는 어떠한 최소 기준을 만족해야 한다. 최소 기준은 상황에 따라 정한다.
- 신뢰도와 향상도는 높을수록 좋다.
- 향상도는 1 보다는 커야 한다.
지지도와 신뢰도, 향상도를 모두 사용하는 룰입니다. 일단 이 예시에서 지지도는 0.125 ~ 0.375의 값을 가지므로, 0.25 이상이면 기준을 만족한다고 보고 진행해 볼게요. 전체적인 계산 결과는 아래와 같습니다.
상품1 | 상품2 | 지지도 | 신뢰도 | 향상도 |
사과주스 | 우유 | 0.375 | 0.5 | 1.333333333 |
사과주스 | 세제 | 0.25 | 0.333333333 | 0.888888889 |
사과주스 | 생수 | 0.25 | 0.333333333 | 0.666666667 |
사과주스 | 콜라 | 0.375 | 0.5 | 0.8 |
우유 | 사과주스 | 0.375 | 1 | 1.333333333 |
우유 | 세제 | 0.125 | 0.333333333 | 0.888888889 |
우유 | 생수 | 0.125 | 0.333333333 | 0.666666667 |
우유 | 콜라 | 0.125 | 0.333333333 | 0.533333333 |
세제 | 사과주스 | 0.25 | 0.666666667 | 0.888888889 |
세제 | 우유 | 0.125 | 0.333333333 | 0.888888889 |
세제 | 생수 | 0.25 | 0.666666667 | 1.333333333 |
세제 | 콜라 | 0.25 | 0.666666667 | 1.066666667 |
생수 | 사과주스 | 0.25 | 0.5 | 0.666666667 |
생수 | 우유 | 0.125 | 0.25 | 0.666666667 |
생수 | 세제 | 0.25 | 0.5 | 1.333333333 |
생수 | 콜라 | 0.25 | 0.5 | 0.8 |
콜라 | 사과주스 | 0.375 | 0.6 | 0.8 |
콜라 | 우유 | 0.125 | 0.2 | 0.533333333 |
콜라 | 세제 | 0.25 | 0.4 | 1.066666667 |
콜라 | 생수 | 0.25 | 0.4 | 0.8 |
1단계 : 지지도와 향상도 기준 만족하는 것만 고르기
먼저 지지도와 향상도 기준을 만족하는 걸 골라냅니다. 그러면 아래와 같습니다.
상품1 | 상품2 | 지지도 | 신뢰도 | 향상도 |
사과주스 | 우유 | 0.375 | 0.5 | 1.333333333 |
사과주스 | 세제 | 0.25 | 0.333333333 | 0.888888889 |
사과주스 | 생수 | 0.25 | 0.333333333 | 0.666666667 |
사과주스 | 콜라 | 0.375 | 0.5 | 0.8 |
우유 | 사과주스 | 0.375 | 1 | 1.333333333 |
우유 | 세제 | 0.125 | 0.333333333 | 0.888888889 |
우유 | 생수 | 0.125 | 0.333333333 | 0.666666667 |
우유 | 콜라 | 0.125 | 0.333333333 | 0.533333333 |
세제 | 사과주스 | 0.25 | 0.666666667 | 0.888888889 |
세제 | 우유 | 0.125 | 0.333333333 | 0.888888889 |
세제 | 생수 | 0.25 | 0.666666667 | 1.333333333 |
세제 | 콜라 | 0.25 | 0.666666667 | 1.066666667 |
생수 | 사과주스 | 0.25 | 0.5 | 0.666666667 |
생수 | 우유 | 0.125 | 0.25 | 0.666666667 |
생수 | 세제 | 0.25 | 0.5 | 1.333333333 |
생수 | 콜라 | 0.25 | 0.5 | 0.8 |
콜라 | 사과주스 | 0.375 | 0.6 | 0.8 |
콜라 | 우유 | 0.125 | 0.2 | 0.533333333 |
콜라 | 세제 | 0.25 | 0.4 | 1.066666667 |
콜라 | 생수 | 0.25 | 0.4 | 0.8 |
생각보다 몇 개 없네요. 이것만 일단 추려서, 다음 단계를 진행해 보겠습니다.
2단계 : 필터링된 데이터만으로 우선순위 정하기
일단 위 표에서 골라진 데이터만으로 표를 그려보면 아래와 같습니다.
상품1 | 상품2 | 지지도 | 신뢰도 | 향상도 |
사과주스 | 우유 | 0.375 | 0.5 | 1.333333333 |
우유 | 사과주스 | 0.375 | 1 | 1.333333333 |
세제 | 생수 | 0.25 | 0.666666667 | 1.333333333 |
생수 | 세제 | 0.25 | 0.5 | 1.333333333 |
콜라 | 세제 | 0.25 | 0.4 | 1.066666667 |
세제 | 콜라 | 0.25 | 0.666666667 | 1.066666667 |
상품1과 상품2가 있다고 했을 때, 정의 상 지지도와 향상도는 상품1 - 상품2, 상품2 - 상품1 로 순서를 바꿔도 값이 동일하게 나옵니다. 향상도도 어차피 식을 다시 풀어 써보면 P(X|Y)/P(Y) = P(X∩Y)/P(X)P(Y) 이므로, 순서가 없는 값입니다.
순서에 따라 값이 바뀌는 건 신뢰도 뿐이므로, 일단 상품1, 상품2 페어 중에서 신뢰도가 낮은 값은 제거해도 될 거 같습니다. 예를 들어서 사과주스 - 우유, 우유 - 사과주스를 보시면 신뢰도만 0.5와 1로 다르고 나머지는 값이 같습니다. 그러면 당연히 신뢰도가 높은 걸 선택하는 게 좋으니까요. 그러면 이제 표는 3줄로 줄어듭니다.
상품1 | 상품2 | 지지도 | 신뢰도 | 향상도 |
우유 | 사과주스 | 0.375 | 1 | 1.333333333 |
세제 | 생수 | 0.25 | 0.666666667 | 1.333333333 |
세제 | 콜라 | 0.25 | 0.666666667 | 1.066666667 |
일단 세개가 남았으니 원래 목적이 마트에 어떤 걸 붙여서 진열해 둘까? 라는 데 있다는 걸 고려해 보면 그냥 세개 다 해도 상관없을 것 같구요. 근데 리스트가 너무 길어서 꼭 상위 몇개를 뽑아야겠다 라고 하면, 지지도와 신뢰도, 향상도를 곱해서 가장 높은 것부터 뽑는다든지 하는 식으로 진행하면 되겠죠? 이 세개 리스트 중에서는 우유 - 사과주스를 근처에 진열해 두는 게 가장 좋을 거 같습니다. 물론 실제 결제 데이터가 아니므로 이상하게 느껴지는 건 당연합니다. 이 예시에서는 그렇다는 뜻입니다.
글을 마치며 : 분석의 제약 조건
이 글에서는 연관성 분석, 또는 장바구니 분석의 개념만을 소개하였습니다. 현실 세계에서는 마트에 물건이 5개만 있지도 않을 뿐더러, 2개씩 페어하는 것보다는 여러개를 한 군데 진열해 놔야 할 수도 있고, 물건을 얼마나 디테일하게 쪼개느냐 (반팔 라운드티와 반팔 V넥 티는 같은 종류로 묶어야 하는가 아니면 다른 종류의 상품으로 봐야 하는가) 에 따라서 리스트가 천차만별이 될 수 있습니다. 일단 이 글에서는 이러한 방법이 있다 정도를 소개한 것으로 이해해 주시면 좋을 것 같습니다.
댓글