IT

[R programming] 재미로 알아보는 카카오톡 대화 분석

urosie 2019. 7. 6. 20:50

최근에 R을 배우기 시작하면서 여러가지 재밌는(?) 통계 데이터들을 보다가 
카카오톡 대화 분석을 해보면 어떨까 하고 검색해봤더니, 이미 여러 훌륭하신 분들께서 샘플 코드를 올려주신 걸 봤다! 

(야호)

접근하기 쉬운 데이터일 뿐만 아니라, 데이터에 대한 연관성 및 정확성 등도
나에게서 나온 데이터이기 때문에 판단이 쉽고 또 재밌는 결과를 볼 수 있을 것 같았다.

아래의 순서를 잘 따라가다 보면 재밌는 결과를 볼 수 있다.

① 분석 대상 데이터 추출

분석하고자 하는 대화를 해당 카카오톡 대화방에서 "대화내용 내보내기" 기능을 통해 텍스트 파일로 내려받는다.

카카오톡에서 내려주는 파일 여러개를 합쳐서 막 해보려고 했는데, 데이터가 많으면 소스가 돌아가다가 오류가 난다.
적정수준은 구현 환경에 따라 다르겠으나, 1MB이하의 파일이면 빠르게 확인이 가능하다.

② 데이터 읽기

내려받은 파일을 R Studio에서 불러와 데이터를 읽어본다.
분석하려는 대화가 저장된 텍스트 파일은 programmer.txt이고 이를 읽어들여 data에 저장한다.
txt가 한글일 경우는 R에서 인식하지 못하고 인코딩이 깨질 수 있기 때문에 iconv로 UTF-8 인코딩을 해준다 

data <- readLines('programmer.txt') 
data <- iconv(data, 'UTF-8')

③ 데이터 확인

데이터를 확인하는 과정은 필수!
데이터를 확인하여 쓸모 없는 데이터를 제거하는 전처리 과정을 해준다.

분석하는 데이터에 오류가 발생되지 않도록 미리 제거해주는 것!
첫번째와 마지막 행을 몇 개 읽어보고 데이터를 파악해야 한다.

str(data)     ## 데이터 구조, 변수 개수 등 구조 파악 
head(data,10) ## 상위 10개 데이터  
tail(data,10) ## 하위 10개 데이터 

 

④ 데이터 전처리

데이터 전처리를 진행해줘야 유의미한 데이터를 가지고 분석을 할 수 있다.

예시를 들면

카카오톡 대화 파일을 열면 "2017년 9월 22일 금요일" 이런식으로 그 날의 처음 부분을 명시해 주는데
이 부분은 실질적 대화내용이 아니므로 제거해야하고 
대화 앞에 붙는 "2017. 9. 22. 오후 6:39," 이런 일시도 제거해줘야 한다.!

그리고 각자 대화내용에 맞춰 전처리를 해주면 되는데 내가 전처리한 내용은 아래와 같다. 

i1 <- gsub('(2017).+(일)', '', data)   ## 날짜 제거 
i2 <- gsub('(2018).+(일)', '', i1)     ## 날짜 제거 
i3 <- gsub('(저장한).+(\\d)', '', i2)  ## 알림 제거 
i4 <- gsub('(http).+(\\w)', '', i3)    ## 공유한 링크 제거 
i5 <- gsub('(2018).+(:)', '', i4)      ## 날짜 제거 
i6 <- gsub('(2017).+(:)', '', i5)      ## 날짜 제거 
i7 <- gsub('[ㄱ-ㅎ]','',i6)            ## '자음 ㄱ부터 ㅎ까지 전부' 제거 
i8 <- gsub('(ㅜ|ㅠ)+','',i7)           ## (ㅜ 또는 ㅠ)를 의미, +는 '하나 이상' 제거 
i9 <- gsub('이모티콘','',i8)           ## 이모티콘 제거 
i10 <- gsub('사진','',i9)              ## 사진 제거 
i11 <- gsub('동영상','',i10)           ## 동영상 제거 
i12 <- na.omit(i11)                    ## NA 값 제거 

 

이렇게 전처리까지 완료되어야 분석할 수 있는 데이터가 된다.
전처리가 완료된 다음에도 ③,④번 작업을 계속 반복하여 이상치를 없애주는 작업을 계속 해준다.

⑤ 형태소 분석

이 부분은 형태소를 분석해주는 방식을 결정하는데, 나는 명사만 추출하는 로직으로 처리했다.

## 명사 추출 
ko.words <- function(doc){ 
  d <- as.character(doc) 
  extractNoun(d) 
}

 

⑥ 말뭉치 만들기

단어가 몇 번 쓰였는지 카운트해주기 위해 데이터의 텍스트를 단어의 말뭉치로 분리해준다.

cps <- VCorpus(VectorSource(i12))

 

⑦ TermDocumentMetrix 만들기

tdm <- TermDocumentMatrix(cps,control = list(tokenize=ko.words,
                                              removePunctuation = TRUE, 
                                              removeNumbers = TRUE, 
                                              sentence_pre=FALSE))

tokenize : 형태소 분석을 의미하며, 앞서 만들었던 형태소 분석 방식을 입력한다.
removePunctuation :  마침표를 제거여부
removeNumbers : 숫자를 제거여부

tdm을 확인하고 싶다면 as.marix 함수를 사용해 Metirx파일로 바꿔주면 분석 결과를 볼 수 있다. 

tdm2 <- as.matrix(tdm)
view(tdm2)

 

그리고 sort 함수로 데이터에 대해서 내림차순으로 정렬을 해주고, 전체 데이터를 출력할 필요가 없으므로
상위 100개 데이터만 추출해준다.

그리고 wordcloud로 데이터를 확인할 예정이기 때문에
wordcloud함수가 지원하는 데이터프레임 형식으로 변환해준다.

X변수에는 name함수로 v 데이터의 이름을 추출한 값을, freq변수에는 v의 값을 입력해준다.

v <- head(sort(slam::row_sums(tdm2), decreasing = T),100)
data <- data.frame(X=names(v),freq=v)

이제 다 끝났다!!

결과를 재밌게 볼 일만 남았다.

일단 그냥 wordcloud로 볼 수 도 있으나 나는 wordcloud2함수를 써서 좀 더 내 입맛대로 보려고 한다.

 

⑧ wordcloud

나는 brewer.pal 함수를 사용해서 상위 8개에 대해서는 색을 지정했다.

그리고 wordcloud의 위치, 크기, 모양, 글꼴 등을 지정해서 출력했다

pal <- brewer.pal(n=8, name='Set2')

wordcloud2(data2,  
           color       = pal,  
           fontFamily  = 'NanumGothic',  
           shape       = 'circle', 
           minRotation = -pi/4, 
           maxRotation = pi/4, 
           rotateRatio = 0.25, 
           ellipticity = 0.6)

 

⑨ 최종

최종 결과이다!!!

이 결과를 보면 이 대화방은 ... ㅋㅋㅋ 상대적으로 자전거, 지하철, 데이트, 필라테스 단어가 많이 사용되었고

애두라와 여러 사람의 이름이 노출되는 걸 봐서는 친구들의 단체 대화방임을 예측해볼 수 있다 ^_^

글씨가 클수록 더 많은 노출이 있었던 단어이다!

이렇게 해보니 대화분석하는게 어려운 것만은 아닌 것 같다.
사실 구글에서 검색하여 훌륭하신 분들의 소스코드를 참고하긴 해서 제대로 하려면 조금 더 공부가 필요할 것 같다. 

 

참고 사이트 : http://blog.naver.com/PostView.nhn?blogId=coder1252&logNo=221047157058&parentCategoryNo=&categoryNo=10&viewDate=&isShowPopularPosts=true&from=search