Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

류동균의 R 공부방입니다.

R로 카카오톡 채팅 분석하기 #2 본문

카테고리 없음

R로 카카오톡 채팅 분석하기 #2

R쟁이 2019. 9. 13. 16:21

R로 카카오톡 채팅 분석하기#1 에서 비정형데이터를 정형데이터로 바꾸는 작업을 완료하였다.

이번엔 그러한 정형데이터를 통해 오픈채팅방을 그래프, 표, 워드클라우드로 분석해보자.

 

분석하기에 앞서 밑의 코드는 Rmd확장자명을 가지는 R마크다운으로 작성하였다. R마크다운은 청크라는 것이 있는데,

이는 쉽게 구간을 나누어놓은 것이다. 직관성이 좋고 유지보수가 쉽고 웹에 올리기가 좋다. 이번엔 이를 이용하여 Rpubs에 간단한 보고서를 publish하는 과정까지 진행할 예정이다.

간단하게 R마크다운 사용법을 알아보면 다음과 같다.

 

청크생성 ctrl + alt + i
전체실행 ctrl + shfit + k
청크 실행 ctrl + shfit + enter
청크옮기기 ctrl + pageup/down

청크사이에는 script창이 있는데 #을 사용하여 제목을 추가하거나 글을 쓸 수 있다. html, css 와 비슷한 개념이다.

 

그럼 이제 그래프를 통한 시각화부터 시작해보자.

#필요한 패키지

library(dplyr)
library(plotly)
library(lubridate)
library(stringr)
library(ggplot2)
library(DT)
library(wordcloud)
library(RColorBrewer)
library(KoNLP)

 

지금해볼것은 정형화된데이터의 월, 일, 시간별 트래픽이나 사용빈도가 높은 단어를 분석 해볼 예정이다.

그러기위해선 day, wday(요일), hour, minute, count와 같은 컬럼을 추가해야한다. 다음과같이 해보자.

total_df_time<- total_df %>% 
  mutate(day = ymd(str_sub(total_df$Date,1,10))) %>% 
  mutate(wday = wday(str_sub(total_df$Date,1,10), TRUE)) %>% 
  mutate(hour = ymd_h(str_sub(total_df$Date,1,13))) %>% 
  mutate(minute = ymd_hm(str_sub(total_df$Date,1,16))) %>% 
  mutate(count = 1)

count라는 컬럼을 추가한이유는 각각의 row를 1이라는 통일된 수를 주고 나중에 트래픽을 sum으로 계산하기위해

추가해주었다.

이제 일별 카톡트래픽을 시각화하여 분석해보자.

#일별 카톡 트래픽
group_by_day_df <- total_df_time %>% 
  group_by(day) %>% 
  summarise(count = sum(count)) %>% 
  as.data.frame()

#트래픽을 그래프로 시각화
group_by_day_ggplot <- ggplot(group_by_day_df, aes(x=day, y=count)) +
  geom_line(stat = "identity") + 
  geom_point(stat = "identity")

#반응형 그래프
ggplotly(group_by_day_ggplot)

이 단계에서는 ggplot이라는 함수와 ggplotly라는 함수를 쓰게된다. ggplot의 기본형은 ggplot(data, aes(x=x, y=y))이다.

aes는 축제목과 같은 역할을하며 x축의 제목과 y축의 제목을 쓸 수 있다. geom_line()은 그래프를 선형그래프로, geom_point는 점형 그래프로 + 를 통해 옵션을 추가할 수 있다. 위의 코드는 선과점을 모두 나타내어보았다.

단순히 ggplot만 쓴다면 그냥 그래프가 나오게되는데 ggplot한 데이터를 ggplotly() 함수를 쓰게되면 확대 및 축소가 가능하게 반응형으로 그래프를 볼 수 있다.

 

day 변수를 wday, hour 등 다른 컬럼으로 변경하여 요일, 시간, 월, 일 의 트래픽을 알아 볼 수 있다.

 

## 빈도 찾는 함수
# wordcloud 할 문장만 선택
word_test_df <- total_df$Message

# 공백 제거 
word_test_df <- word_test_df[which(word_test_df != "")]


# 특수 문자 제거
word_test_df <- str_replace_all(word_test_df, "\\W", " ")

# extractNoun()문장을 형태소로 분리
# 간단하게 설명하자면 "배가 고프다"라는 문장을 "배","가","고프다" 와 같이 형태소로 분리한다.
# KoNLP::를 앞에 붙여준 이유는 extractNoun()이란 이름의 함수가 여러 패키지에 있기 때문에,
# KoNLP이라는 패키지의 extractNoun() 함수를 사용한다는 의미이다.
nouns <- KoNLP::extractNoun(word_test_df)

# table 형태로 변환
wordcount <- table(unlist(nouns))
df.word <- as.data.frame(wordcount, stringsAsFactors = FALSE)
df.word <- rename(df.word, word = Var1, freq = Freq)

#filter()를 통해 단어가 2글자 이상인 것만 추출하고 freq가 높은 것부터 나오도록 내림차순으로 정렬
word.freq  <- df.word %>% filter(nchar(word) >=2) %>% arrange(desc(freq))

다음과 같이 했다면 word.freq라는 data.frame이 형성 되었을 것이다. 여기서 바로 시각화해도 좋지만

"ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ", "ㅎㅎㅎㅎㅎㅎㅎㅎㅎ", "ㄱㄱ" 등 약간의 단어 분석을 어렵게만드는 요소들을 제거해보자.

 

## 용어 전처리
#제거할 단어 선택
cleanging_list <- c("ㅋ","ㄴ","ㅇ","ㅎ","ㄱ","ㅅ","ㄷ","ㅂ")

#total_index 빈공간 만들어주기
total_index <- F

#for문을 사용하여 벡터에 있는 문자들이 있는 row를 index로 만들기
for(i in cleanging_list){
  current_index <- grepl( i, word.freq[,1])
  total_index1 <- total_index | current_index
}

#index를 제거한 나머지 row만 추출
word.freq <- word.freq[!total_index,]

 다음의 과정을 통해 필요없는 단어나 문자를 제거 했다면 이제 밑의 코드를 실행시켜보면 data가 반응형 표로 만들자.

 word.freq %>% datatable()

막대그래프

##reorder word 빈도 역순

#word.freq의 빈도수가 상위 30개인것, 그리고 aes 옵션에서 x축을 word의 freq가 높은것부터 차례대로
#나오게 하기위해 reorder(word,-freq)라고 옵션을 추가해준다.
plot_word <- ggplot(word.freq[1:30,], aes(x = reorder(word,-freq), y=freq)) + 
  geom_bar(stat = "identity") +
  #막대그래프 밑의 글자를 기울여줌 angle의 값을 설정하면 된다.
  theme(axis.text.x = element_text(angle = 30))


#ggplotly()를 사용해 반응형 그래프로 시각화 height, width 옵션으로 그래프의 높이와 너비를 설정할 수 있다. 
ggplotly(plot_word, height = 600, width=800)

워드클라우드 만들기

### Wordcloud
#pal은 색깔과 관련된 함수이다. 다음과 같이 설정해준다.
pal <- brewer.pal(8, "Dark2")[5:9]

# 난수 설정(안하면 그릴때 마다 바뀜)
# set.seed(1004)

# 워드 클라우드 그리기
a <- wordcloud::wordcloud(words = word.freq$word, freq = word.freq$freq,
                          min.freq = 2, max.words = 150,
                          random.order = FALSE, rot.per = 0.1,
                          scale= c(5,0.3),
                          colors = pal)

 

다음과 같이 카카오톡의 단체채팅방을 분석해 보았다. 분석한 그래프는 링크에서 확인 할 수 있다.

https://rpubs.com/ryoo/527113