>RE::VISION CRM

CRM

[CRMAJU2018] R데이터분석 - 탐색적 고객세분화 :: 서점 데이터 활용

YONG_X 2018. 5. 22. 12:55

# 서점의 고객 데이터에 대한 가상 사례

# 탐색적인 분석과 고객세분화 응용 사례

 

# cs1 <- read.xlsx("https://t1.daumcdn.net/cfile/blog/99A85D3F5A9E002921?download")

# 데이터 파일은 <고객데이터분석 using R> 페이지에 있음

 

 

cust_seg_smpl_280122.csv
0.00MB

 

 

cust_seg_smpl_280122 (1).csv
0.00MB

 

 

# 엑셀파일을 사용하는 대신 다운로드 후 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을?

 

 

 

 
cust_seg_smpl_280122.csv
0.0MB