[ADP 실기] 시험 후기 – 3. 시험 문제

 
 

 

 
 
 
고객세분화 (45점)

 
 
가. 세분화 변수의 생성 및 선정
     –   요약 변수 및 파생 변수의 생성
         예) 카테고리별 점유율, 주 인터넷 사용 시간대, 인터넷 사용 일수, 검색 패턴, 쇼핑단계별 이용 패턴,
              주 쇼핑 시간대, 주 관심 상품 카테고리, 구매 상품 가격대
     –   EDA, 상관분석, Decision Tree 등을 통하여 적절한 세분화 변수 선정
 
나. 군집 분석 및 최적 세분화 집단 생성
     –   적절한 군집 분석 기법 제시 및 분석 수행
     –   세분화 집단의 최적 개수 결정 및 기준 설명
 
다. 각 세분화 집단의 특성 분석, 정의 및 마케팅 인사이트
     –   각 세분화 집단에 대한 특성 분석 및 시각화
     –   특성 분석 결과를 기반으로 각 세분화 집단에 대한 마케팅 관점에서의 정의
     –   세분화 분석 결과를 토대로 타당한 마케팅 인사이트 제시
 
 
 
 
예측 (45점)

 
 
가. 세분화 집단별 예측 모형 (구매, 이탈, 등급 변동, 우수 고객 예측 등) 개발을 위한 종속 변수 정의 및 독립 변수 선정
     –   해당 예측을 위한 타당한 종속 변수의 정의
     –   해당 예측을 위한 독립 변수의 생성 및 선정
          요약 변수 및 파생 변수의 생성, EDA/상관분석/Decision Tree 등을 통한 적절한 변수 선정
 
나. 세분화 집단별 예측 모형 개발
     –   종속 및 독립 변수의 성격에 따른 적절한 모델링 기법 제시
     –   샘플링, 파티션 등 모델링 데이터 준비 및 모형 생성
     –   적절한 평가 기준에 의한 모델 평가 및 최종 모델의 선택
 
다. 예측 모형 분석 및 마케팅 인사이트 제시
     –   세분화 집단별 예측 모형의 특성 분석 및 시각화
     –   세분화 집단간 예측 모형의 비교 분석
     –   예측 모형 분석 결과를 토대로 적절한 마케팅 인사이트 제시
 
 
 
텍스트 마이닝 (10점)

 
 
가. 포털 사이트 검색 기록을 활용한 토픽 분석
     –   한 고객이 일정 기간 동한 포털 사이트에서 입력한 전체 검색 리스트를 하나의 문서(Document)로 간주
     –   위의 문서에 기반을 두어 고객의 관심 주제를 파악하기 위한 토픽 분석을 수행
 
나. 토픽 분석 결과의 해석 및 마케팅에서의 활용 방안 제시
     –   도출된 토픽 리스트의 의미를 마케팅 관점에서 해석
     –   분석 결과를 고객 세분화 및 예측 등에서 활용할 수 있는 구체적인 방안 제시

 
 
 
 
 
 
파일

 

 

 

[ADP 실기] 시험 후기 – 2. 시험용 데이터

 

 
 
 
마케팅 전략 수립
 
패널 1,000명의 1년간 온라인 이용 행태 데이터
 
1.  이용자의 인구통계학
    –   이용자 ID (Numeric)
    –   성별 (Character) : 남, 여
    –   직업 (Character)
    –   지역 (Character)
    –   나이 (Numeric)
 
2.  인터넷 접속 기록
    –   이용자 ID (Numeric)
    –   접속시각 (yyyymmddhh)
    –   접속횟수 (Numeric)
    –   체류시간 (Numeric)
    –   사이트 (Character)
    –   사이트 대분류 (Character) 
    –   사이트 중분류 (Character) 
    –   사이트 소분류 (Character) 
 
3.  오픈마켓 접속 기록
    –   이용자 ID (Numeric)
    –   접속시각 (yyyymmddhhMMss)
    –   체류시간 (Numeric)
    –   마켓이름 (Character)
    –   쇼핑 단계 (Character) : 가격비교, 검색, 상품 목록, 상품 상세, 장바구니, 구매, 구매 취소
    –   상품 페이지 ID (Numeric) : NA 존재
    –   검색어 (Character) : 마켓에서 사용자가 입력한 검색어
 
4.  오픈마켓에서 열람한 상품 정보
    –   상품 페이지 ID (Numeric)
    –   마켓 이름 (Character)
    –   상품 페이지 제목 (Character)
    –   상품 대분류 (Character)
    –   상품 중분류 (Character)
    –   상품 소분류 (Character)
    –   정가 (Numeric) : NA 존재
    –   판매가 (Numeric) : NA 존재
    –   판매자 명 (Character0
    * 상품의 분류는 마켓에 따라 다를 수 있음
    * 정가와 판매가가 NA이면 판매 중단된 상품임 (이 부분을 안 적어 왔네요, 제가 기억하고 있는 내용 입니다.)
 
5.  포털 사이트 검색 기록
    –   이용자 ID (Numeric)
    –   접속 시각 (yyyymmddhh)
    –   검색어 (Character0
 
 
위 5개의 데이터는 UTF-8로 인코딩된 csv 파일로 제공이 됩니다.
각 파일은 헤더가 존재하며 rownames은 저장되지 않았습니다.
 
 
 
평가 기준
 
–   적절한 분석 기법 사용
–   제공 데이터의 다각적 활용
–   다양한 분석 기법 활용 및 평가
–   결측치 및 이상치 처리
–   분석 언어 활용의 능숙도 및 코드의 효율성
–   분석 결과의 논리적 해석 및 활용 방안 제시
 
 
 
관련 글
 
 
 
 
 
파일

 

 

 
 

[ADP 실기] 시험 후기 – 1. 시험장 환경

 
 
 
 
2014년 6월 28일 토요일에
종로에 있는 한국데이터베이스진흥원에서 진행한
제1회 데이터 분석 전문가 (Advanced Data Analytics Processional, ADP) 실기 시험에 참석을 하였습니다.
 

1호선 종각역 3번

주소

서울시 종로구 종로 51 종로타워 19층 한국데이터베이스진흥원 (우)110-789

 
시험장에 조금 일찍 도착을 했는데, 시험장은 제1시험장과 제2시험장으로 구분되어 있었습니다.
저는 제1시험장에서 시험을 치루었는데 저를 포함하여 8명의 응시생들이 참석을 하였습니다.
 
시험 담당자의 말에 의하면 제2시험장은 제1시험장보다 적은 수의 응시생이 참석을 하였다고 합니다. 
15명 정도 되냐고 물어보니 말을 아끼던데 그 정도 인원이 시험을 치룬 것 같습니다.
 
 
시험장은 책상을 두개씩 세줄로 구성이 되어 있었는데
한 수험생마다 두개의 책상을 사용하도록 되어 있었고
필기구와 음료, 초코바(?)가 준비되어 있었고 제가 가지고 있던 캔커피의 반입은 허용이 되었습니다.
 
시험은 오픈북으로 4시간 동안 진행이 되었는데
약 30분전에 입실이 허용이 되어 컴퓨터의 상황을 점검해 볼 수 있었습니다.
 
제가 기억하여 온 것을 잠깐 적어 보면 아래와 같습니다.
–   Windows 7, 2 core * 3.? GHz CPU, 8 GB 메모리, 외부 네트워크 차단
–   R Studio
    제가 시험전에 필요한 패키지를 설치해 되느냐고 물어 보니 이미 모든 패키지를 다 설치해 놓았다고 하더군요.
–   EditPlus
–   MS Office
–   설치되어 있는 화면 캡쳐 프로그램은 없고 Windows에 내장되어 있는 것을 사용하라고 하더군요.
 
PC 사양은 높은 편인데 너무 느리다는 느낌을 받았습니다.
그리고 화면도 자주 깜박 거려 
외부에서 시험자의 화면을 모니터링 하고 있는 것 같은 느낌을 받았는데 확인을 할 수 없었습니다.
 
 
시험은 정시에 시작이 되었습니다.
인쇄된 시험 문제지와
컴퓨터에 저장된 5개의 csv 파일(UTF-8로 인코딩)이 제공 되었습니다.
 
시험은 3문항(고객 세분화, 예측, 텍스트 마이닝)이 출제가 되었는데
요약변수/파생변수/데이터변환 과정을 거쳐 모델링을 하고
작성한 모델을 평가하고 인사이트를 도출하는 과정을 기술하는 문제 였습니다.
 
시험 결과물로는
HWP 또는 DOC로 작성한 분석 보고서와 R History을 제출 하여야 합니다.
 
 
시험이 오픈북이라
시험 문제를 4장의 종이에 적어 왔는데
다음 기회에 정리를 하여 공개 하겠습니다.
 
 
 
파일

 

 

 

 

[ADP 실기] Cheat Sheet for R

 
 
예전에 ADP 필기를 위해서 
약 1200 페이지의 책을 꼭 기억해야 할 6 페이지의 Cheat Sheet로 정리한 적이 있습니다.
 
이번에 ADP 실기를 위해서
꼭 기억해야 할 R 명령어를 2 페이지로 정리를 하여 보았습니다.
(Shiny, D3.js 등 제외)
 
 
 
 
 
파일

 

 

 

[ADP 실기] qqplot2 – qplot, 주요 argument

 
  • ggplot2에서 시각화 단계

Ggplot2.png

  • qplot 주요 arguments
  • x, y : x, y 좌표의 값
  • data : 데이터
  • geom : 챠트의 형태
  • auto : 자동으로 선택
  • point : 산점도, 점 그래프
  • smooth : 회귀선 표시
  • line : 선 그래프 (방향 : 왼쪽 -> 오른쪽)
  • path : 선 그래프 (무방향)
  • boxplot : 박스 챠트
  • jitter :
  • histogram : 히스토그램
  • density : 밀도 그래프
  • bar : 막대 그래프, 도수분포표
  • facets : 챠트 분할
  • main : 제목
  • xlab, ylab : X축, Y축 이름
  • xlim, ylim : X축, Y축 값의 범위
  • binwidth : 구간의 넓이
  • colour, color : 색상 분류 기준 (선/점 색)
  • shape : 점의 모양
  • alpah : 투명도, 작을수록 투명함
  • fill : 채우는 색
  • 예약어
  • ..count.. : 관측 개수
  • ..ncount.. : (0, 1)인 관측 개수
  • ..density.. : 밀도
  • ..ndensity.. : (0, 1)인 밀도
  • qplot 기타 arguments
  • weight : 가중치 적용
  • method
  • loess : smooth용 회귀분석
  • gam : 데이터로 자유도 계산한 lm
  • lm : 회귀분석
  • formula : 수식
  • se = FALSE : smooth에서 편차 제거
  • span : smooth와 같이 사용, 0~1
  • log : 로그 적용 (x, y, xy)
  • asp : y/x 비율
  • margins : 마진
  • stat : 통계
  • position :
 

파일

 

[ADP 실기] 텍스트 마이닝

 
텍스트 마이닝은 문서와 단어를 가공하여 아래와 같은 분석 등을 할 수 있습닏.
–   단어의 빈도 분석 -> 워드 클라우드
–   문서/단어의 군집 분석
–   문서별 감성 분석
–   단어의 연관 분석

 
 
 
library(tm)
getReaders()                            #— Reader의 종류 확인
getTransformations()                    #— tm_map용 함수 목록
 
###—————————————————————————–
### Corpus 생성
#— 영화 코멘트 파일 읽기
finp <- file("data/ADV_4_5_movieComment_1000.txt", encoding = "UTF-8")
lines <- readLines(finp)
close(finp)
rm(finp)
(lines <- head(lines, 100))
(doc <- Corpus(VectorSource(lines)))
 
(lines <- c("You're awe some and I love you", 
            "I hate and hate and hate. So angry. Die!",
            "Impressed and amazed: you are peer less in your achievement of unparalleled mediocrity.", 
            "I love you"))
(doc <- Corpus(VectorSource(lines)))
 
#— Vector에 저장된 Text 읽기
lines <- c("This   is a text", "This another one.", "My name is Eric", 
         "Fuzzy Analysis Clustering", "Computes a fuzzy clustering of the data into k clusters.")
(doc <- Corpus(VectorSource(lines)))
 
#— Text 파일 읽기
#— C:/Program Files/R/R-3.0.3/library/tm/texts/txt/ 폴더 지정
(folder <- system.file("texts", "txt", package = "tm"))
(doc <- Corpus(DirSource(folder), readerControl = list(language = "lat")))
rm(folder)
 
#— XML 파일 읽기
#— C:/Program Files/R/R-3.0.3/library/tm/texts/crude/ 폴더 지정
(folder <- system.file("texts", "crude", package = "tm"))
(doc <- Corpus(DirSource(folder), readerControl = list(reader = readReut21578XML)))
rm(folder)
 
###—————————————————————————–
### Corpus 조회
summary(doc)
doc[[1]]                                #— 첫번째 문서 조회
inspect(doc[1])                         #— 첫번째 문서 조회
 
#writeCorpus(doc)                        #— Corpus 저장
#writeCorpus(doc[1], filenames="01.txt") #— 첫번째 Corpus 저장
 
###—————————————————————————–
### Corpus 변환
(doc <- tm_map(doc, as.PlainTextDocument))[[1]]                #— XML 문서를 Text로 변환
(doc <- tm_map(doc, stripWhitespace))[[1]]                     #— 두개 이상의 공백을 하나의 공백으로 치환
(doc <- tm_map(doc, tolower))[[1]]                             #— 소문자로 변환
(doc <- tm_map(doc, removePunctuation))[[1]]                   #— 구두점 삭제
(doc <- tm_map(doc, removeWords, stopwords("english")))[[1]]   #— Stopword (조사, 띄어쓰기, 시제 등)를 제거하고 표준화
(doc <- tm_map(doc, stripWhitespace))[[1]]                     #— 두개 이상의 공백을 하나의 공백으로 치환
(doc <- tm_map(doc, stemDocument))[[1]]                        #— 어근만 추출
#(doc <- tm_map(doc, removeNumbers))[[1]]                       #— 숫자 삭제
#removeURL <- function(x) gsub("http[[:alnum:]]*", "", x)
#(doc <- tm_map(doc, removeURL))[[1]]                           #— URL 삭제
#rm(removeURL)
#(doc <- tm_map(doc, gsub, pattern = "diamond", replacement = "aaa"))[[1]]   #— 문자열 치환
 
 
#(doc <- tm_map(doc, grep, pattern = "diamond"))[[1]]           #— diamond가 포함된 라인 번호 반환
#(doc <- tm_map(doc, stemCompletion, dictionary = doc))[[1]]    #— 어근으로 원래 단어 유추
#    (a <- c("mining", "miners", "mining"))
#    (b <- stemDocument(a))
#    (d <- stemCompletion(b, dictionary=a))
 
###—————————————————————————–
### DocumentTermMatrix / TermDocumentMatrix
(m <- DocumentTermMatrix(doc))          #— DocumentTermMatrix 생성
#— Non-/sparse entries : 단어가 있는 entry / 단어가 없는 entry
#— Sparsity : 문서별 단어 중 한번도 사용하지 않은 비율
(m <- removeSparseTerms(m, 0.70))       #— Sparsity가 70% 이상인 경우 삭제
 
dic <- c("prices", "crude", "oil")      #— 여기 기술된 단어를 포함하는 모델 생성
(m <- DocumentTermMatrix(doc, list(dictionary = dic)))
 
(m <- TermDocumentMatrix(doc))          #— TermDocumentMatrix 생성
(m <- t(m))                             #— DocumentTermMatrix로 변환
(data <- as.matrix(m))                  #— DocumentTermMatrix를 matrix로 변환
 
m$nrow                                  #— 문서 (document) 개수 / 단어 (term) 개수
m$ncol                                  #— 단어 (term) 개수 / 문서 (document) 개수
m$dimnames                              #— 문서 (document)와 단어 (term) 목록
m$dimnames$Docs
m$dimnames$Terms
m$i                                     #— 문서 (document) 인덱스 / 단어 (term) 인덱스
m$j                                     #— 단어 (term) 인덱스 / 문서 (document) 인덱스
m$v                                     #— m$i[0] 문서에서 m$j[0] 단어의 발생 빈도
                                        #— m$j[0] 문서에서 m$i[0] 단어의 발생 빈도
 
inspect(m)                              #— 단어의 분포를 확인
inspect(m[1:2, 3:5])                    #— 처음 2개 문서의 3번째에서 5번째 단어의 분포를 확인
 
findFreqTerms(m, 10)                    #— 10회 이상 사용된 단어 표시
findFreqTerms(m, 10, 15)                #— 10회 이상, 15회 이하 사용된 단어 표시
findAssocs(m, "oil", 0.65)              #— "oil" 단어와 연관성(같이 사용될 확률)이 65% 이상이 단어를 표시
 
rm(dic)
 
###—————————————————————————–
### 단어의 빈도 분석
(frequency <- colSums(data))            #— 단어별 발생 건수 계산
(frequency <- subset(frequency, frequency >= 20))   #— 10건 이상 발생한 단어 추출
 
#library(gdata)
(frequency <- as.data.frame(available.packages()))  #— 패키지 목록 추출
(frequency <- gdata::trim(unlist(strsplit(as.character(frequency$Depends), ','))))   #— 패키지 의존 정보 추출
(frequency <- gsub('[ \(].*|\n', '', frequency))  #— 다양한 문자 부호 제거
(frequency <- table(frequency))         #— 단어의 빈도수 테이블
 
library(ggplot2)
barplot(frequency, las = 2)
 
library(wordcloud)                      #— 워드 클라우드
wordcloud(names(frequency), as.numeric(frequency), colors = c("green", "red"))
wordcloud(names(frequency), log(as.numeric(frequency)), colors = c("green", "red"))
 
(colors <- gray((frequency + 10) / (max(frequency) + 10)))
wordcloud(words = names(frequency), freq = frequency, min.freq = 2, random.order = F, colors = colors)
rm(frequency, colors)
 
###—————————————————————————–
### 문서의 군집 분석
(fit <- hclust(dist(scale(data)), method = "ward"))
plot(fit)
rect.hclust(fit, k = 3)                 #— 5개의 그룹으로 구분
(groups <- cutree(fit, k = 3))          #— 문서별로 그룹 지정
rm(fit, groups)
 
k <- 3
(kmeansResult <- kmeans(m, k))          #— k-평균 군집 모형
for (i in 1:k) {
  cat(paste("cluster", i, ": ", sep = ""))
  s <- sort(kmeansResult$centers[i,], decreasing = T)
  cat(names(s), "n")
}
 
library(fpc)
(pamResult <- pamk(m, metric = "manhatttan"))
(k <- pamResult$nc)
 
(pamResult <- pamResult$pamobject)
for (i in 1:k) {
  cat(paste("cluster", i, ": "))
  cat(colnames(pamResult$medoids)[which(pamResult$medoids[i, ] == 1)], "n")
}
 
###—————————————————————————–
### 감성 분석
###—————————————————————————–
#— 문장을 입력받아 문장과 점수를 반환
#— 점수 = 긍정 점수 – 부정 점수
#—     긍정 점수 : 긍정 단어 (pos.words)가 포함된 개수
#—     부정 점수 : 부정 단어 (neg.words)가 포함된 개수
(pos.word <- scan("data/ADV_4_5_positiveWords.txt", what = "character", comment.char = ";"))   #— 긍정 단어
(pos.words <- c(pos.word, "upgade"))
(neg.word <- scan("data/ADV_4_5_negativeWords.txt", what = "character", comment.char = ";"))   #— 부정 단어
(neg.words <- c(neg.word, "wait", "waiting"))
 
scores <- function(sentences, pos.words, neg.words, .progress='none') { #— 점수와 문장을 반환
  require(plyr)
  require(stringr) 
  scores = laply(
    sentences, 
    function(sentence, pos.words, neg.words) {
      sentence = gsub('[[:punct:]]', '', sentence)   #— 구두점 삭제
      sentence = gsub('[[:cntrl:]]', '', sentence)   #— 특수기호 삭제
      sentence = gsub('\d+', '', sentence)             #— 숫자 삭제
      sentence = tolower(sentence)                   #— 소문자로 변환
      
      word.list = str_split(sentence, '\s+')        #— 하나 이상의 공백으로 단어 추출
      words = unlist(word.list)                      #— list를 벡터로 변환
      
      pos.matches = match(words, pos.words)          #— 긍정의 점수 계산 (긍정 단어와 매핑되는 개수 산정)
      pos.matches = !is.na(pos.matches)
      neg.matches = match(words, neg.words)          #— 부정의 점수 계산 (부정 단어와 매핑되는 개수 산정)
      neg.matches = !is.na(neg.matches)     
      score = sum(pos.matches) – sum(neg.matches)
      return (score)
    }, 
    pos.words, neg.words, .progress=.progress
  )
  scores.df = data.frame(score=scores, text=sentences)
  return(scores.df)
}
 
 
(result <- scores(lines, pos.words, neg.words))
library(ggplot2)
qplot(result$score)
hist(result$score)
 
###—————————————————————————–
### 연관 분석
###—————————————————————————–
library(KoNLP)
extractNoun("연습을 해보고자 한다. 명사가 잘 추출되는지 보자. 빨간색으로 글씨를 쓴다.")
sapply("연습을 해보고자 한다. 명사가 잘 추출되는지 보자. 빨간색으로 글씨를 쓴다.", extractNoun)
system.time(nouns <- sapply(head(lines, 1000), extractNoun, USE.NAMES = FALSE))
rm(nouns)
 
 
(data <- Map(extractNoun, lines))       #— 각 문장에서 명사 추출 (문장 -> 문자열 목록)
(data <- unique(data))[[1]]             #— 라인별 데이터를 unique하게
(data <- sapply(data, unique))[[1]]     #— 각 라인내 데이터를 unique하게
 
(data <- sapply(data, function(x) {     #— 2자 이상 4자 이하의 한글 단어 추출
  Filter(function(y) {
    nchar(y) <= 4 && nchar(y) > 1 && is.hangul(y)
  },
  x)
}))
(data <- Filter(function(x) { length(x) >= 2 }, data))   #— 단어가 2개 이상 포함된 문장만 추출
(names(data) <- paste("Tr", 1:length(data), sep = ""))   #— 데이터에 행 이름 지정
data                                    #— 문장별 단어 목록
 
library(arules)
(data <- as(data, "transactions"))
(dataTab <- crossTable(data))
 
#— 빈도수 5%, 같이 있을 확률이 10%인 단어 목록 추출
#—     최소지지도 5% 이상, 최소신뢰도 10% 이상인 연관 규칙 탐색
(m <- apriori(data, parameter = list(supp = 0.05, conf = 0.1)))   
inspect(m)
 
rm(list=ls(all=TRUE))                   #— 작업 영역에 저장된 데이터 모두 삭제
 

 
 

파일