ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • R rtweet 트위터 (twitter) 로 좋아하는 연예인 텍스트 마이닝 ( text mining ) 하기 + 연관 분석 ( Association Rules )
    R + Textmining (텍스트마이닝) 2020. 2. 19. 14:52

     

    필요 라이브러리(library)

    • library(base64enc)

    • library(arules)

    • library(KoNLP)

    • library(NIADic)

    • library(RmecabKo)

    • library(rtweet)

    • library(tidyverse)

    • library(igraph)

    • library(twitteR)

     

     

     

     

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

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

     

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

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

    r-pyomega.tistory.com

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

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

    연관 분석 ( Association Analysis )을 하겠습니다

     

     

     

    #### 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()

     

     

     

     

    #### 연관분석이란?

     

    연관분석은 군집분석에 의해서 그룹으로 묶인 집단을 대상으로 하며 그룹에 대한 특성을 분석하는 방법입니다. 장바구니 분석으로 잘 알려져있고, 마트에서 기저귀-맥주의 연관성을 파악하는데 이용된 예시로 널리 알려져 있습니다

     

     

     

     

    #### 텍스트 파일 추출


    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() %>%                                     

                             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글자 이상만 추려냅니다

     

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

     

     

     

    #### 품사 추출 파일을 모아 데이터 프레임(Data Frame)으로 만들기

    izone_ko_연관 <- bind_rows(izone_ko_명사, 
                               izone_ko_용언, 
                               izone_ko_수식언)

     

     

    연관분석에 활용할 Data Frame을 확인해봅시다

    (필수작업은 아니지만 확인도 할겸)

     

    View(izone_ko_연관)

     

     

     

     

     

    #### 품사별 추출

    izone_ko_연관_명사 <- izone_ko_연관 %>%  
                           select(3, 1) %>%                      ## 3열(명사)과 1열 추출
                           na.omit() 

     

     

    izone_ko_연관_용언 <- izone_ko_연관 %>%  
                           select(5, 1) %>%                        ## 5열(용언)과 1열 추출
                           na.omit() 

     

     

    izone_ko_연관_수식언 <- izone_ko_연관 %>%  
                          select(6, 1) %>%                        ## 6열(수식언)과 1열 추출
                          na.omit() %

     

     

     

     

     

    #### 품사별 글자수를 "단어"로 통합

    izone_ko_연관_명사 <- rename(izone_ko_연관_명사, 
                             c(단어 = 명사))

                             ## 명사, 용언, 수식언을 "단어"변수로 통합하기 위해 변수명 "단어"로 변경

     

     

    izone_ko_연관_용언 <- rename(izone_ko_연관_용언, 
                                c(단어 = 명사))

                               ## 명사, 용언, 수식언을 "단어"변수로 통합하기 위해 변수명 "단어"로 변경

     

     

    izone_ko_연관_수식언 <- rename(izone_ko_연관_수식언, 
                                    c(단어 = 명사))

                                ## 명사, 용언, 수식언을 "단어"변수로 통합하기 위해 변수명 "단어"로 변경

     

     

     

    izone_ko_연관_단어 <- bind_rows(izone_ko_연관_명사, 
                                    izone_ko_연관_용언, 
                                    izone_ko_연관_수식언)

                                 ## 변경한 변수명 "단어"로 기준으로 통합

     

     

     

     

     

     

    #### 연관분석 그래프에 맞게 리스트 만들기

    izone_ko_연관_단어df <- split(izone_ko_연관_단어,izone_ko_연관_단어$L1)      ## 리스트를 "열(column)별로 쪼갭니다
    izone_ko_연관_단어list <- lapply(izone_ko_연관_단어df, function(x){ 
                                      return(x$단어)})                                                                   ## 아래의 그림처럼 리스트를 만듭니다

     

     

     

     

     

    ※ 리스트 파일에서 일부만 추출

     

    데이터분석은 전수분석(?)이 가장 좋다는 지론을 가지고 있습니다

    하지만 일반 PC로 수천개로 구성된 리스트(list)가 만약 다양한 형태를 가지고 있는데 이를 연관분석한다면 시간이 굉장히 오래 걸릴수도 있습니다.(izone_ko_연관_단어list는 비교적 단순한 형태)

    본인의 따라 아래 코드를 참고하여 원하는 만큼 추출하시길 바랍니다

    rd_n <- 1:length(raw_list) 
    rd_n <- rd_n %>% sample(n, replace = FALSE)   ## n = 추출하고 싶은 칼럼 개수
    raw_list_n <- raw_list[rd_n]



     

     

     

     

     

    ## transactions 생성

    names(rd_n_list) <- paste("Tr", 1:length(rd_n_list), sep="") 
    rd_n_list_tran <- as(rd_n_list, "transactions")              ##  중복데이터가 있으면 error가 발생합니다

     

     

    감을 잡기위해 transactions구조를 살펴봅시다. "trans"에 저장하고 View()함수로 봅니다

    trans <- izone_ko_tran %>% crossTable() 
    View(trans)             

     

    908 X 908 matrix 형태입니다. 변수 교차지점에서 카운팅 된 데이터가 연관분석의 기반이 됩니다

                     

     

     

    ## apriori 함수를 사용

    izone_ko_tran_apr <- apriori(izone_ko_tran, parameter = list(supp=0.05, conf=0.05))

     

     

    ## parameter에서 supp는 "지지도(support)", conf는 "신뢰도(confidence)"를 의미합니다. 데이터 마이닝 결과를 해석하려면 한번쯤 공부해야하는 개념입니다. 여기서 설명하면 너무 길어니까 다음 기회에 포스팅(Posting)하기로 하고 지금은 다른 고수님 글을 인용하겠습니다

    https://needjarvis.tistory.com/59
     

    추천을 위한 연관성 규칙(Association Rules)의 지지도, 신뢰도, 향상도

    A상품을 구매할 경우 어떤 상품을 추천해야 좋을까? 라는 질문은 수많은 현업, 통계학자, 데이터 분석 전문가들의 고민거리이다. 여러가지 방식의 추천시스템들이 존재한다. 1. 사용자의 프로파일링 기반 2. 상품..

    needjarvis.tistory.com

     

     

    apriori 함수 결과를 보도록 합시다 

    izone_ko_tran_apr %>% summary()

     

     

     

    해석해봅시다

     

    • 총 69개 법칙(rules)를 찾아냈습니다

    • 법칙의 길이(예 : A - B - C -> 길이3)는 평균적으로 2.449이며 최대 4입니다

    • support / confidence / lift는 위의 인용 URL를 참고해주세요

     

    support / confidence가 0.05이하로 설정하면 분석이 어려웠습니다(R이 잘 안돌아가더라고요...) 참조해주세요

     

     

     

     

    ## 데이터 구조 변경 : 연관규칙 결과 -> 행렬구조 변경(matrix 또는 data.frame)

    rd_n_list_rul <- izone_ko_tran_apr %>%  labels(ruleSep=" ")  ## labels 함수로 rules변수의 내용을 입력

     

     

     


    ## rules변수의 내용을 리스트 구조로 변경 

    rd_n_list_rul <- sapply(rd_n_list_rul, strsplit, " ",USE.NAMES=F) 

     

     

     

     


    ## 행 단위로 묶어서 matrix로 반환 

    rd_n_list_mat <- do.call("rbind", rd_n_list_rul) 

     

     

     

     

     

    ## 그래프를 그리기 위해 데이터 변환(graph.edgelist 함수)

    rd_n_list_mat_rulg <- rd_n_list_mat %>% graph.edgelist(directed=FALSE)  

     

     

     

     

     

    ## 그래프 그리기

    plot.igraph(rd_n_list_mat_rulg, 

                       vertex.label=V(rd_n_list_mat_rulg)$name, 
                       vertex.label.cex=1.5,

                       vertex.label.color='#000000',  
                       vertex.size=30,

                       vertex.color='#E85100',

                       vertex.frame.color='#E85100')

     

    연관분석 그래프를 완성하였습니다!

    다음 포스팅은 의미연결망 분석(Semantic Network Analysis) 입니다

     

    댓글

R/Python은 겉치레가 아니야