나혼자 재미도 없고.. ㅠㅠ
서버옮겨서 제대로 키워보고싶구만. 😓
어디까지나 알고리즘 이해를 중심으로 설명하려하기에, 알려진 논문이나 자료들과는 조금 다를지도 모른다. 애시당초 그런 논문들 처럼 설명할거였으면 그냥 링크나 올리고 말았을 것이다. ㅎㅎ
앞서 Apriori의 처리속도 문제를 해결할 수 있게끔, 자료구조를 기똥차게(?) 응용하여 만들어낸 트릭(?)이랄까?ㅋ (처음에 이거 이해하고 얼마나 놀라웠던지..ㅋㅋ)
(얼핏 구성만 보면, 강남에서 프랑스인이 길을 묻는 것 같은 유체이탈을 경험하게 되지만, 세부적으로 하나하나 뜯어보면 사실 무쟈게 단순하다. ^^)
입력데이터 예시)
다음과 같은 상품정보가 있다고 생각해보자. (구성에서는 Item ID라며 I1~I5라는 코드로 되어있으나, 이해를 위해 실제 '인XX크 상품명'으로 예를 만들겠음)
- 데오드란트, 니베아, 스틱, 세이퍼진
- 니베아, 스프레이, 세이퍼진
- 데오드란트, 니베아, 스틱, 세이퍼진
- 데오드란트, 니베아, 스프레이, 세이퍼진
- 데오드란트, 니베아, 스프레이, 스틱, 세이퍼진
- 스프레이, 니베아, 스틱
No. | Item ID | support count |
1 | 니베아 | 6 |
2 | 세이퍼진 | 5 |
3 | 데오드란트 | 4 |
4 | 스프레이 | 4 |
5 | 스틱 | 4 |
각 노드의 괄호 안 숫자는 support count이며 횡으로 연결된 동일 노드들간 support count의 값을 합산하면 Header table의 support count값과 동일해진다.
그 전에 Apriori에서도 언급했다시피, 전체 데이터를 표본으로 삼는 것은 좋지않기 때문에 노이즈를 제거한다. 즉, Minimum support를 선언하지만, 패스하겠다.
솔직히 제거하던말던 별 차이는 없구만.. ㅎㅎ
※ Python package
https://pypi.org/project/pyfpgrowth/
그러니까, '핸드폰'을 구매한 사람은 '핸드폰 케이스'를 함께 구매할 확률이 높다, 뭐 이런거?
(전공자의 경우, 수학적 설명이나 기호가 빠져 이상하게 생각할 수 있을텐데, 비전공자를 위한 간단한 알고리즘 설명이라 생각바람.)
구매번호 | 구매물품 |
1 | 키보드, 노트북, 외장하드 |
2 | 노트북, 파우치 |
3 | 노트북, 거치대 |
4 | 키보드, 노트북, 파우치 |
5 | 키보드, 거치대 |
6 | 노트북, 거치대 |
7 | 디카 |
8 | 키보드, 노트북, 거치대, 외장하드 |
9 | 키보드, 노트북, 거치대 |
10 | 노트북, 파우치 |
구매번호 | 노트북 | 키보드 | 거치대 | 파우치 | 외장하드 | 디카 |
1 | O | O | X | X | O | X |
2 | O | X | X | O | X | X |
3 | O | X | O | X | X | X |
4 | O | O | X | O | X | X |
5 | X | O | O | X | X | X |
6 | O | X | O | X | X | X |
7 | O | X | X | O | X | X |
8 | O | O | O | X | O | X |
9 | O | O | O | X | X | X |
10 | X | X | X | X | X | O |
(support) | 8 | 5 | 5 | 3 | 2 | 1 |
노트북 | 거치대 | 파우치 | 외장하드 | |
키보드 | 상품노출: 5 동시노출: 4 지지도: 4/10=0.4 신뢰도: 4/5=0.8 | 상품노출: 5 동시노출: 3 지지도: 3/10=0.3 신뢰도: 3/5=0.6 | 상품노출: 5 동시노출: 1 지지도: 1/10=0.1 신뢰도: 1/5=0.2 | 상품노출: 5 동시노출: 2 지지도: 2/10=0.2 신뢰도: 2/5=0.4 |
노트북, 거치대 | 거치대, 파우치 | 파우치, 외장하드 | 외장하드, 노트북 | 노트북, 파우치 | 거치대, 외장하드 | |
키보드 |
상품노출: 5
동시노출: 2
지지도: 2/10=0.2
신뢰도: 2/5=0.4
|
상품노출: 5
동시노출: 0
지지도: 0
신뢰도: 0
|
상품노출: 5
동시노출: 0
지지도: 0
신뢰도: 0
|
상품노출: 5
동시노출: 2
지지도: 2/10=0.2
신뢰도: 2/5=0.4
|
상품노출: 5
동시노출: 1
지지도: 1/10=0.1
신뢰도: 1/5=0.2
|
상품노출: 5
동시노출: 1
지지도: 1/10=0.1
신뢰도: 1/5=0.2
|
(기껏 썼는데 좋은 예제가 만들어지지 않는다. ㅠㅠ 쓴게아까워서 지우지는 않겠;;)
노트북, 키보드 | 키보드, 거치대 | 거치대, 파우치 | 파우치, 노트북 | 노트북, 거치대 | 키보드, 파우치 | |
외장하드 |
상품노출: 2
동시노출: 2
지지도: 2/10=0.2
신뢰도: 2/2=1
☞ 100%
|
상품노출: 2
동시노출: 1
지지도: 1/10=0.1
신뢰도: 1/2=0.5
☞ 50%
|
상품노출: 2
동시노출: 0
지지도: 0
신뢰도: 0
☞ 0%
|
상품노출: 2
동시노출: 0
지지도: 0
신뢰도: 0
☞ 0%
|
상품노출: 2
동시노출: 1
지지도: 1/10=0.1
신뢰도: 1/2=0.5
☞ 50%
|
상품노출: 2
동시노출: 0
지지도: 0
신뢰도: 0
☞ 0%
|
(저에게만 그런 느낌일 수 있으니 너무 기대는 마시고요;)
물론 ElasticSearch 5.0.0 GA 버전 이후 기본 scoring알고리즘이 TF-IDF에서 BM25로 변경되었으나, TF-IDF는 반드시 알아둬야할 개념임에는 분명하다.
그리고 "Term"이라는 것은 조각, 토큰과 유사한 의미로, 문헌분석의 경우에서는 단어 정도로 생각하면 좋을것이다.
2은 2배를 의미하지만, ½은 반(Half)을 의미한다. 역수를 취한다는 의미는 결국 정 반대로 가중치를 책정한다는 의미이다.
I | love | dogs | hate | and | knitting | is | my | hobby | passion | |
D-1 | 1 | 1 | 1 | |||||||
D-2 | 1 | 1 | 1 | 1 | 1 | |||||
D-3 | 1 | 1 | 1 | 2 | 1 | 1 |
I | love | dogs | hate | and | knitting | is | my | hobby | passion | |
D-1 | 1.5 | 3 | 1.5 | |||||||
D-2 | 1.5 | 1.5 | 3 | 1.5 | 1.5 | |||||
D-3 | 1.5 | 1.5 | 3 | 6 | 3 | 3 |
사실 log는 없어도 되는 놈이다. 특히 위와 같이 단순한 표본분석에서는 log는 필요치 않을 수도 있다.
하지만 데이터가 커지면? 좀더 다양한 데이터를 대상으로 한다면? 그때 상황이 달라진다.
I | love | dogs | hate | and | knitting | is | my | hobby | passion | |
D-1 | 0.18 | 0.48 | 0.18 | |||||||
D-2 | 0.18 | 0.18 | 0.48 | 0.18 | 0.18 | |||||
D-3 | 0.18 | 0.18 | 0.48 | 0.95 | 0.48 | 0.48 |
결국 특정 구간 값을 가지게 된다. 이것이 바로 cosine normalization(코사인 평준화)의 가장 간단한 예이다.
코사인평준화에 대한 내용은 "cosine similarity", 그러니까 "문헌 유사도" 중 "코사인유사도"에서 다시 언급되게 된다.
여기까지 이해했다면 TF-IDF는 사실 다 이해한 것이나 마찬가지다. ^^