R + Textmining (텍스트마이닝)

R rtweet 트위터 (twitter) 로 좋아하는 연예인 텍스트 마이닝 (text mining) 하기 + 워드 크라우드 (wordcloud)

구렁이 알(Python/R) 2020. 2. 14. 18:38

 

출처 : Stonemusic Entertainment.Inc

필요 라이브러리(library)

  • library(base64enc)

  • library(KoNLP)

  • library(NIADic)

  • library(RmecabKo)

  • library(rtweet)

  • library(tidyverse)

  • library(igraph)

  • library(twitteR)

 

 

#### KoNLP 사전작업

install_mecab("C:/Rlibs/mecab") 
devtools::install_github('haven-jeon/NIADic/NIADic', build_vignettes = TRUE)
Sys.setenv(JAVA_HOME='C:/Program Files/Java/jre1.8.0_241') 
buildDictionary(ext_dic = "woorimalsam") 
useNIADic()

 

 

 

앞에 게시글에서 추출한 게시글 데이터는 

https://r-pyomega.tistory.com/16?category=875331

 

R rtweet 트위터 (twitter) 로 좋아하는 연예인 텍스트 마이닝 (text mining) 하기 + 트윗 크롤링 (Crawling)

우리나라에서는 다소 제한적으로 사용되어지지만, 좋아하는 연예인(특히, 아이돌)의 소식을 알고 싶거나 팬들끼리 소통할 때 트위터(twitter)는 아마도 오늘날 가장 많이 활용하는 SNS일겁니다. 서양권과 특히,..

r-pyomega.tistory.com

"izone_ko"(한국어)에 저장하였습니다

지금부터 이를 텍스트 마이닝으로 전처리하여

워드 크라우드와 빈도그래프를 그리겠습니다

 

 

 

 

#### 텍스트 파일 추출

izone_ko_word <- sapply(izone_ko,function(t) t$getText()) 

게시글에서 텍스트 파일만 가져와 izone_ko_word에 저장합니다

 

 

 

 

 

#### 한글 - 품사별 처리

izone_ko_words <- izone_ko_word %>% SimplePos09() 

 

 

izone_ko_word에 SimplePos09( )를 적용하여 품사별로 뽑아냅니다 

개인적으로 extraNoun, nouns보다는

품사별 추출이 가능한 SimplePos09를 선호합니다

아래는 SimplePos09와 SimplePos22에 대한 인포그래픽입니다

출처 : KAIST 품사 태그셋 

 

 

 

#### 데이터 셋 만들기

izone_ko_words <- izone_ko_words %>%   
                   melt() %>%  
                   as_tibble() %>% 
                   select(3,1)    ## 3열과 1열 추출
 

SimplePos09( )로 추출한 단어를 데이터 셋으로 만들어 봅시다

 

 

 

 

#### 명사 용언 수식언만 추출하기

 

## 명사 추출

izone_ko_명사 <- izone_ko_words %>%  
                  mutate(명사=str_match(value,'([가-힣]+)/N')[,2]) %>%      ## "명사" variable을 만들고 한글만 저장                   

                  na.omit() %>%                                      ## ([가-힣]+)/P') 한글 중 명사(N)만을 선택하는 정규표현식

                  mutate(글자수=str_length(명사)) %>%   ## "글자수" variable을 만듭니다 

                  filter(str_length(명사)>=2)                               ## 2글자 이상만 추려냅니다

 

 

 

아래와 같은 결과를 확인합니다

 

 

 

 

 


## 용언 추출

izone_ko_용언 <- izone_ko_words %>%  
                   mutate(용언=str_match(value,'([가-힣]+)/P')[,2]) %>%   ## "용언" variable을 만들고 한글만 저장 
                   na.omit() %>%                           ## ([가-힣]+)/P') 한글 중 용언(P)만을 선택하는 정규표현식

                   mutate(글자수=str_length(용언)) %>%        ## "글자수" variable을 만듭니다 
                   filter(str_length(용언)>=2)                         ##  2글자 이상만 추려냅니다

 

 

 

아래와 같은 결과를 확인합니다 

 

 

 

 

 

 

## 수식언 추출

izone_ko_수식언 <- izone_ko_words %>%  
                mutate(수식언=str_match(value,'([가-힣]+)/M')[,2]) %>%    ## "수식언" variable을 만들고 한글만 저장
                na.omit() %>%                                ## ([가-힣]+)/M') 한글 중 수식언(M)만을 선택하는 정규표현식
                mutate(글자수=str_length(수식언)) %>%  ## "글자수" variable을 만듭니다 
                filter(str_length(수식언)>=2)                 ##  2글자 이상만 추려냅니다

 

 

아래와 같은 결과를 확인합니다 

 

 

 

 

 

 

#### 데이터 전처리

 

워드크라우드와 빈도그래프의 목적은 객체간의 빈도확인에 있습니다

이를 위해서는 3가지 조건을 만족하는 데이터가 있어야 합니다

  • 객체 빈도숫자 (Counting)

  • 내림차순 정렬 (Descending)

  • 불필요 객체 제거 (Triming)

 

그러면 명사, 용언, 수식언 각각에 3가지 조건에 만족하는 데이터 전처리를 합시다

 

 

##명사 전처리 

izone_ko.명사 <- izone_ko_명사$명사 
izone_ko.명사 <- izone_ko.명사 %>% unlist() 
izone_ko.명사 <- izone_ko.명사 %>% as.vector() 
izone_ko.명사 <- str_replace_all(izone_ko.명사, "[^[:alnum:][:blank:]+?&/\\-]","")          ## 특수문자를 처리합니다
izone_ko.명사 <- str_replace_all(izone_ko.명사, "^.{1}$","")         ## 혹시라도  들어갈 수 있는 한글자를 처리합니다
izone_ko.명사 <- str_replace_all(izone_ko.명사, "\\d+","") 
izone_ko.명사 <- izone_ko.명사 %>% as.list() 
izone_ko.명사[izone_ko.명사 ==""] <- NULL 
izone_ko.명사 <- izone_ko.명사 %>% unlist()                         ## 공백을 제거합니다
izone_ko.명사 <- izone_ko.명사 %>% as.data.frame()

 

 

##용언 전처리

izone_ko.용언 <- izone_ko_용언$용언 
izone_ko.용언 <- izone_ko.용언 %>% unlist() 
izone_ko.용언 <- izone_ko.용언 %>% as.vector() 
izone_ko.용언 <- str_replace_all(izone_ko.용언, "[^[:alnum:][:blank:]+?&/\\-]","")          ## 특수문자를 처리합니다
izone_ko.용언 <- str_replace_all(izone_ko.용언, "^.{1}$","")      ## 혹시라도  들어갈 수 있는 한글자를 처리합니다
izone_ko.용언 <- izone_ko.용언 %>% as.list() 
izone_ko.용언[izone_ko.용언 ==""] <- NULL 
izone_ko.용언 <- izone_ko.용언 %>% unlist()                    ## 공백을 제거합니다
izone_ko.용언 <- izone_ko.용언 %>% as.data.frame() 





##수식언 전처리

izone_ko.수식언 <- izone_ko_수식언$수식언 
izone_ko.수식언 <- izone_ko.수식언 %>% unlist() 
izone_ko.수식언 <- izone_ko.수식언 %>% as.vector() 
izone_ko.수식언 <- str_replace_all(izone_ko.수식언, "[^[:alnum:][:blank:]+?&/\\-]","")          ## 특수문자를 처리합니다
izone_ko.수식언 <- str_replace_all(izone_ko.수식언, "^.{1}$","")   ## 혹시라도  들어갈 수 있는 한글자를 처리합니다
izone_ko.수식언 <- izone_ko.수식언 %>% as.list() 
izone_ko.수식언[izone_ko.수식언 ==""] <- NULL 
izone_ko.수식언 <- izone_ko.수식언 %>% unlist()                ## 공백을 제거합니다
izone_ko.수식언 <- izone_ko.수식언 %>% as.data.frame()          



 

 

#### 명사 용언 수식언을 묶어서 하나로 만듭니다

izone_ko <- bind_rows(izone_ko.명사,izone_ko.용언,izone_ko.수식언)

 

 

 

 

#### 최다 빈도 단어 Top30을 뽑습니다

 

시각화에 적합한 수준으로 데이터를 추려봅니다

izone_ko_count <- table(izone_ko)                       ## 객체별 빈도를 셉니다
izone_ko_count <- sort(izone_ko_count, decreasing = TRUE)         ##내림차순 정렬 합니다

izone_ko_count30 <- izone_ko_count[1:30]            ## Top 30까지 추립니다

 

 

 

 

 

#### 빈도그래프 작성

izone_ko_count30df <- izone_ko_count30 %>% as.data.frame()             ## data frame변환하고 그래프 작성 
ggplot(izone_ko_count30df, aes(x=izone_ko, y=Freq)) + geom_bar(stat="identity")

 

default 값으로 ggplot을 사용해서 그래프가 이쁘진 않네요;;;

자세한 커스터마이징은 구글링으로 해결하기기 바랍니다

 

 

 

 

#### 워드크라우드 작성

izone_ko_count %>% wordcloud2()       

시험삼아 전체를 워드크라우드로 만들어봤는데....

검색 키워드가 너무 크군요 ㅎㅎ

다른 결과도 보기 위해 수정합시다

 

 

 

## 최다 빈출 단어인 "아이즈원"을 뺍니다

izone_ko_count[2:length(izone_ko_count)] %>% wordcloud2()   

 

 

 

 

 

 

다음페이지에선 좀 더 고급(?) 텍스트 마이닝인 연관분석 (Assosiation Rule)을 해봅시다

 

 

※ 이 글을 작성하는 중에 반가운 메일이 왔네요. 거의 100일만에 받습니다. 앞으로도 쭉 끊기지 않고 받았으면 합니다. 진심으로 컴백을 환영합니다.