2016년 2월 7일 일요일

전자 상거래 상품 이름 분석 II

상품 이름의 단어 조각을 트랜잭션 단위의 부분 집합(조합)으로 간주하고 연관성을 찾는 과정을 알아 본다.

본문은 자주 활용되는 연관 규칙(Association Rules)에 대한 작업 과정을 다룬다.
도구는 Python으로 전처리를 하고 분석은 R을 사용했다.

먼저 트랜잭션 데이터 소스 형태이다.

가. 장바구니 형태 (basket)
상품 이름
사각 똑딱 4P
손톱 매직 파일
헤어 집게 2P
오각 스펀지 12P
손톱 버퍼 2 세트

나. 테이블 형태 (single)
트랜잭션 단어
1 사각
1 똑딱
1
1 4P
2 손톱

두 가지 소스 중에 하나로 트랜잭션을 만든다.

가. 장바구니 형태
tr = read.transactions(“<file_name>”, format = "basket", sep=" ", rm.duplicates=TRUE)
** rm.duplicates : 트랜잭션 단위 아이탬(단어) 중복에 대한 제거 여부
     결과(return) : (중복 아이탬 수, 중복 트랜잭션 수)

나. 테이블 형태
tr = read.transactions(“<file_name>”, format = "single", sep=",", cols=c(1,2),r m.duplicates=TRUE)
** 헤더가 있는 경우 cols에 헤더 이름을 사용한다.

트랜잭션이 준비가 되었으니,

아프리오리(apriori) 알고리즘을 통해서 연관 규칙을 찾는다.

library(arules)
rules=apriori(tr, parameter=list(supp=0.01, conf=0.5))
inspect(rules)

lhs Var.2 rhs support confidence lift
1 {와이어} -> {스테인리스} 0.01001821 0.8800000 13.60901
2 {여성} -> {거실화} 0.01047359 1.0000000 54.90000
3 {거실화} -> {여성} 0.01047359 0.5750000 54.90000
4 {소스} -> {} 0.01275046 0.8000000 13.94286
5 {식탁} -> {매트} 0.01593807 1.0000000 44.81633
* lhs (Left Hand Side) - 좌변
* rhs (Right Hand Side) - 우변
* support - 지지도 = 좌우변 같이 출현한 개수 / 전제 개수
* confidence - 신뢰도 = 좌우변 같이 출한한 개수 / 좌변이 출현한 개수 = Pr(B|A)
* lift - 향상도 : 신뢰도 / 우변 지지도 = Pr(B|A) / Pr(B)

** 향상도
1을 기준으로 작으면 음의 관계 크면 양의 관계를 뜻한다.
좌우변의 지지도가 작으면서 신뢰도가 높다는 것은 좌우변의 관계가 깊다는 것을 말한다.

참고

분포 보기
library(arulesViz)
plot(rules, shading="order", control=list(main = "Words of EC Product", col=rainbow(5)))


그래프 보기
plot(rules, method="graph", control=list(type="itemsets"))

아프리오리 ( a priori )
“앞에 오는 것으로 부터”를 뜻하는 라틴어이다.
바톰 업(bottom up) 방식으로 문제에 접근 한다.
부분 집합(subset)의 빈도가 적다면 부분 집합을 포함하는 집합의 빈도도 작다는 아이디어를 활용한다.

아프리오리 in 협업적 여과 방법
http://data-rider.blogspot.kr/2016/01/blog-post_30.html

플롯(plot)에서 한글 on 맥(Mac)
par(family="AppleGothic")

코드 샘플
# 공백으로 분리된 단어를 트랜잭션 포맷으로 변경
corpus = []
tid = 0
for words in df['cleansed']:
    tid += 1
    for word in words.split():
        corpus.append((tid,word))
df = pd.DataFrame(corpus,columns=['tid','word'])

# 단어의 건수 추출
corpus = {}
for words in df['cleansed']:
    for word in words.split():
        if word not in corpus:
            corpus.setdefault(word,0)
        corpus[word] += 1
df = pd.DataFrame(list(corpus.items()),columns=['word','freq'])

# 단어의 분류 태그 달기
cmap = {
'칼라': ['블루','레드','핑크','블랙','베이지','그린','브라운','화이트','그레이'],
'사이즈': ['대','중','소'],
'재질': ['스테인리스','유리'],
'성별': ['남성','여성'],
'형태': ['원형','사각'],
'형질': ['스테인리스','유리']
}

수치 = '^(\d+\D+)+'

def flaging(word):
    for i in cmap:
        if word in cmap[i]:
            return i
    if re.match(수치,word):
        return '수치'
    return '-'

df['flag'] = df['word'].apply(flaging)

0 개의 댓글:

댓글 쓰기