# 서점의 고객 데이터에 대한 가상 사례
# 탐색적인 분석과 고객세분화 응용 사례
# cs1 <- read.xlsx("https://t1.daumcdn.net/cfile/blog/99A85D3F5A9E002921?download")
# 데이터 파일은 <고객데이터분석 using R> 페이지에 있음
# 엑셀파일을 사용하는 대신 다운로드 후 CSV 파일을 사용
cs1 <- read.csv("https://t1.daumcdn.net/cfile/blog/99E68E4C5CE4B4051F?download")
head(cs1)
names(cs1)
names(cs1)
[1] "고객명" "성별" "연령"
[4] "지역" "구매일수" "최종구매후기간"
[7] "구매서적수" "서적구매액" "기타상품구매액"
[10] "총구매액" "관심쟝르" "구매쟝르수"
[13] "가입기간" "SMS수신여부"
names(cs1) <- c("cust_name", "sex", "age", "location", "days_purchase",
"recency", "num_books", "amt_books", "amt_non_book",
"amt_total", "interest_genre", "num_genre",
"membership_period", "sms_optin" )
# 최종구매후기간 recency와 구매한 서적의 수간의 관계 확인
plot(cs1$recency, cs1$num_books)
# 동일 좌표에 다수의 고객 존재 가능성이 있으므로 jitter 활용
plot(jitter(cs1$recency), jitter(cs1$num_books))
abline(lm(cs1$num_books~cs1$recency), col="blue")
# 보조선인 회귀선을 본다면 최근성이 낮을수록, 즉 구매한지 오래되었을 수록
# 구매한 서적의 수가 많음
# 엑셀에서 천단위 comma가 포함된 것을 gsub 함수로 제거
cs1$amt_books <- as.numeric(gsub(",","",as.character(cs1$amt_books)))
cs1$amt_non_book <- as.numeric(gsub(",","",as.character(cs1$amt_non_book)))
plot(jitter(cs1$num_books), jitter(cs1$amt_books))
abline(lm(cs1$amt_books~cs1$num_books), col="blue")
# 구매한 책의 수가 많을수록 구매금액이 큼
# 주로 비싼 책을 샀는지를 파악하기 위해 평균금액을 계산
cs1$unitprice_book <- cs1$amt_books/ cs1$num_books
plot(jitter(cs1$num_books), jitter(cs1$unitprice_book),
pch=19, col="lightblue", cex=0.7,
ylim=c(0, max(cs1$unitprice_book)*1.05),)
abline(lm(cs1$unitprice_book~cs1$num_books),
col="blue",lwd=2, lty=2)
abline(h=median(cs1$unitprice_book), col="darkgrey")
# 성별을 구분해서 특성 차이 비교
plot(jitter(cs1$num_books), jitter(cs1$unitprice_book),
pch=19, cex=0.7,
col=ifelse(cs1$sex=='여', "pink", "lightblue"),
ylim=c(0, max(cs1$unitprice_book)*1.05),
sub="pink: female blue: male")
abline(lm(cs1$unitprice_book~cs1$num_books),
col="blue",lwd=2, lty=2)
abline(h=median(cs1$unitprice_book), col="darkgrey")
plot(jitter(cs1$num_books), jitter(cs1$unitprice_book),
pch=19,
cex=4*cs1$amt_non_book/max(cs1$amt_non_book),
col=ifelse(cs1$sex=='여', "pink", "lightblue"),
ylim=c(0, max(cs1$unitprice_book)*1.05),
sub="size: 서적이외 상품 구매액")
abline(lm(cs1$unitprice_book~cs1$num_books),
col="blue",lwd=2, lty=2)
abline(h=median(cs1$unitprice_book), col="darkgrey")
# 서적과 서적이외 구매액 비교
plot(jitter(cs1$amt_books), jitter(cs1$amt_non_book),
pch=19, col="khaki", cex=1.5,
ylim=c(0, max(cs1$amt_non_book)*1.05))
abline(h=median(cs1$amt_non_book)*1.5, col="darkgrey")
abline(v=median(cs1$amt_books)*1.5, col="darkgrey")
# 서적 구매는 많으나 기타 상품 구매가 약한 집단을 선정해
# 집중적 cross-selling 노력 기울이는 것이 필요해 보임
text(median(cs1$amt_books)*1.5 * 2,
median(cs1$amt_non_book)*1.5 *0.7, "cross-sell target")
# 대상 집단 조건 - 시각적으로 설정했던 기준선 영역에 해당하는 고객리스트 추출
tgtgridseg <- cs1[cs1$amt_books > median(cs1$amt_books)*1.5 &
cs1$amt_non_book < median(cs1$amt_non_book)*1.5 ,]
nrow(tgtgridseg)
paste("size of target = ", as.character(100* nrow(tgtgridseg)/ nrow(cs1)), " % of customer base")
# 선정된 집단의 프로파일 시각적으로 확인
# 서적 구매수량과 성별 분포 확인 (여성은 pink)
barplot(tgtgridseg$num_books, names.arg=tgtgridseg$cust_name,
col=ifelse(tgtgridseg$sex=='여',"pink","lightblue"),
ylab="서적 구매수량")
# 전체고객의 평균/중위수 서적구매수량과 비교
abline(h=mean(cs1$num_books), lty=2)
abline(h=median(cs1$num_books), lty=2)
# 프로파일 확인 결과 중위수에 비해 서적구매수량이 많고, 평균에 비해서도
# 많은 편인 여성 고객들임
# 기타 상품 중 여성 선호 상품을 찾아 제안하는 방식으로 cross-sell
# 캠페인 진행 필요해 보임
# 군집분석을 활용한 고객세분화
# 수치형식의 중요 변수 = { "days_purchase",
"recency", "num_books", "amt_books", "amt_non_book",
"amt_total", "num_genre",
"membership_period" }
cs2 <- cs1[,names(cs1) %in% c("days_purchase",
"recency", "num_books", "amt_books", "unitprice_book",
"amt_non_book", "num_genre", "membership_period")]
kmm1 <- kmeans(cs2, 3)
table(kmm1$cluster)
# 고객집단을 표시할 색상을 임의로 지정
# 번호순의 색상 이름 벡터 생성
cols <- c("red","green","blue")
barplot(table(kmm1$cluster), names.arg=names(table(kmm1$cluster)),
col=cols,
main="군집별 고객수 분포")
# 각 고객의 소속 집단이 어디인가에 따라 색상 표시
plot(jitter(cs2$days_purchase), jitter(cs2$num_genre),
col=cols[kmm1$cluster], pch=19,
main="고객세분집단 프로파일: 구매빈도와 서적구매 쟝르 다양성 분포",
sub="Cl#1: red, Cl#2: green, Cl#3: blue")
# 서적 구매 쟝르의 수가 많다면 서적 구매 수량이 많을 가능성 높으므로
# 비율을 새로 계산 (=구매한 서적 수량 대비 쟝르의 수)
plot(jitter(cs2$days_purchase), jitter(cs2$num_genre/cs2$num_books),
col=cols[kmm1$cluster], pch=19,
main="고객세분집단 프로파일: 구매빈도와 서적구매 쟝르 다양성 분포",
sub="Cl#1: red, Cl#2: green, Cl#3: blue",
ylab="서적구매량대비 구매쟝르수 비율")
# Next :: 추가적인 세분집단 프로파일링?
# Next :: 분석결과를 바탕으로 어떤 정교한 CRM Action을?
'CRM' 카테고리의 다른 글
디지털 채널, 앱, 코로나 그리고 CRM 고객관계관리와 데이터 분석 2021 (0) | 2021.04.20 |
---|---|
[강의 소개] 실전 타겟 마케팅과 고객세분화 활용 (0) | 2020.09.18 |
[CRMAJU2018] kmeans 예제 - 은행마케팅 (0) | 2018.05.16 |
[CRMAJU2018] Class 과제 :: 은행마케팅 - 20대 고객 탐색적 데이터 분석 (0) | 2018.05.10 |
앙상블 :: ensemble 배깅 그리고 random forest 개념 (0) | 2015.07.10 |