R을 이용한 한글 텍스트마이닝 & 워드클라우드
Preview
비정형 텍스트를 기반으로 의미있는 정보를 추출하는 기술을 텍스트마이닝이라고 합니다. 데이터마이닝과는 다른 것으로, 데이터마이닝은 구조화되고 사실적인 방대한 데이터베이스에서 관심 있는 패턴을 찾아내는 기술 분야라고 한다면 텍스트마이닝은 구조화되지 않고 자연어로 이루어진 텍스트에서 의미를 찾아내는 기술 분야입니다.
우리는 비정형 텍스트에서 텍스트마이닝을 통해 원하는 텍스트를 걸러내, R을 통한 시각화를 해 볼 겁니다.
워드클라우드는 아래의 사진과 같이 문서의 단어들을 분류하여 그 빈도를 한눈에 보기 쉽게 하는 겁니다.
(이런거)
포스팅에는 영화 박열의 네이버 리뷰를 크롤링해 .txt 파일로 저장한 것을 사용할 겁니다. 아래 첨부파일을 다운받으세요.
1. 경로 선택과 파일 읽어오기
R studio에서 경로를 선택할때는 setwd()를 사용합니다.
다운받은 폴더 경로를 복사하세요. 주의할 것은 기존 경로를 복사해서 사용하면 \(역슬래쉬)로 복사되지만 R에서는 /(슬래쉬)로 바꿔주어야 합니다. 혹은 역슬래쉬 두개(\\)를 사용해도 무방합니다.
(역슬래쉬를 슬래쉬로 바꿔줍시다)
1 | setwd("C:/Users/kutar/Dropbox/R_Text") | cs |
아래와 같이 입력해봅시다.
list.files() : 현재 작업경로에 저장되어있는 파일목록을 불러옵니다.
1 2 | > list.files() [1] "review.txt" | cs |
파일을 읽는 방법은 여러가지가 있으나, 크롤링한 파일이라 한줄씩 읽는 readLines()를 사용하겠습니다.
readLines()는 파일을 행단위로 읽어 벡터로 저장해주는 메서드입니다.
1 | data <- readLines("review.txt") | cs |
아마 data를 출력하면 엄청나게 긴 출력문이 나올 것입니다.
간단한 확인을 위해 head()를 이용해 처음 부분만 출력해봅시다.
head()는 첫 5인덱스까지만 출력해주는 메서드이고, 파라미터로 원하는 숫자를 넣어 그 인덱스를 조절할 수 있습니다.
1 2 3 4 5 6 7 | > head(data) [1] "배우의 국적을 의심하게 만듬." [2] "" [3] "여주를 잘 알려지지 않은 배우로 캐스팅한게 정말 탁월했습니다! 진짜 일본인이 연기하는 줄 착각할 정도로 연기가 정말 좋았네요! 최희서 배우님 진짜 앞으로 더욱 기대되는 배우입니다!" [4] "" [5] "" [6] "" | cs |
2. 패키지 설치
본격적으로 들어가기 전에 설치할 패키지가 있습니다.
wordcloud : 말 그대로 워드클라우드를 위한 패키지입니다.
RColorBrewer : 여러 색을 제공해주는 팔레트 같은 패키지입니다. R의 기본 컬러는 처참할 정도로 쨍한 원색입니다. 이 패키지는 기본서에도 등장할 정도로 애용되니 설치합시다.
KoNLP : 한국어 텍스트마이닝을 위한 패키지입니다. R에서는 유일한...
install.packages("패키지이름")을 하면 설치가 자동으로 이루어집니다.
그리고 설치 후 library("패키지이름")을 하면 해당 패키지를 사용하겠다는 선언이 됩니다.
차례로 따라 타이핑해봅시다.
1 2 3 4 5 6 7 8 | install.packages("wordcloud") install.packages("RColorBrewer") install.packages("KoNLP") #import library(wordcloud) library(RColorBrewer) library(KoNLP) | cs |
wordcloud는 기본적으로 wordcloud(데이터, 빈도수)로 출력할 수 있습니다.
데이터의 빈도수가 클수록 글자가 크게 나타나는 것입니다.
물론 데이터는 여러개가 들어갈 수 있으며, 따라서 벡터형식으로 들어가게 됩니다. 간단하게 시험삼아 아래와 같이 쳐봅시다.
1 2 3 | word <- c("사과","바나나","키위","망고","오렌지","딸기","파인애플") fre <- c(30,20,10,4,5,6,3) wordcloud(word, fre) | cs |
각각 순서대로 매칭되어 사과가 30, 바나나가 20, 키위가 10... 이라는 의미입니다.
아마 옵션을 주지 않아 위치가 랜덤값이라 조금씩 모양은 다르겠지만 아래와 같이 이런 못생긴 워드클라우드가 등장할 것입니다.
wordcloud()의 옵션
wordcloud()안에서 여러 옵션을 줄 수 있습니다.
1 2 3 4 5 6 7 8 9 10 | wordcloud() scale 가장 빈도가 큰 단어와 가장 빈도가 작은단어 폰트사이의 크기차이 scale=c(10,1) minfreq 출력될 단어들의 최소빈도 maxwords 출력될 단어들의 최대빈도(inf:제한없음) random.order(true면 랜덤, false면 빈도수가 큰 단어를 중앙에 배치하고 작은순) random.color(true면 색 랜덤, false면 빈도순) rot.per(90도 회전된 각도로 출력되는 단어비율) colors 가장 작은빈도부터 큰 빈도까지의 단어색 family 글씨체 | cs |
간단히 사용법을 알았으니 이제 텍스트마이닝을 진행해봅시다.
시작 전 useSejongDic()으로 사전을 추가해줍시다. (대소문자 주의)
1 | useSejongDic() | cs |
3. 명사 추출
extractNoun으로 명사를 추출합니다.
sapply() 메서드를 사용할 건데 sapply()는 인자로 sapply(data, function) 이 기본적으로 들어가며, 이 function에 extractNoun을 넣으면 됩니다.
리뷰 텍스트파일인 만큼 컬럼은 필요없으니 USE.NAMES=F 라는 옵션으로 컬럼명은 빼주기로 하겠습니다.
1 | data <- sapply(data, extractNoun, USE.NAMES = F) | cs |
sapply는 리스트형태로 리턴이 됩니다.
분석을 위해 unlist()를 이용해 다시 벡터로 변환해주겠습니다.
1 | data_unlist <- unlist(data) | cs |
항상 변환후에는 확인하는 습관을 들여야 된다고 했습니다.
1 2 | > head(data_unlist) [1] "배우" "국적" "의심" "" "여주를" "배우" | cs |
이 단어들의 빈도수를 출력하기 위해 table로 바꿔주겠습니다.
1 | wordcount <- table(data_unlist) | cs |
table로 변경해 출력하면 아마 이런 모양이 될 것입니다.
1 2 3 4 5 | > head(wordcount) data_unlist '그시대 '박열' '박열'에 '박열'은 '박열'이 15001 1 2 1 1 1 | cs |
아직 전처리 전이니 공백 등은 신경 쓸 필요없습니다.
이 엄청난 데이터들을 워드클라우드로 뽑아내면, 컴퓨터가 멈출 정도로 끝없는 구름에 휩싸이게 됩니다.
모양이 제대로 나오지도 않음은 물론이고 그래서는 텍스트마이닝의 의미가 없습니다.
head()를 이용해 최대빈도 100개 정도면 뽑아 다른 변수에 넣어주겠습니다.
1 | wordcount_top <-head(sort(wordcount, decreasing = T),100) | cs |
sort()는 정렬메서드인데, sort()의 decreasing 옵션은 True면 내림차순, False면 오름차순으로 정렬해 줍니다.
또한 위에서 언급했지만 head()에 두번째 인자로 숫자를 넣으면 첫 5인덱스만 빼주는게 아니라 인자만큼 빼줍니다.
head()에 100을 넣고, 정렬까지 내림차순으로 완료하였으면 다음과 같이 상위 100개가 출력됩니다.
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 32 | > wordcount_top data_unlist 영화 연기 한 배우 들 것 15001 3190 1711 1400 1161 1135 829 적 역사 지루 진짜 수 감동 생각 800 783 685 562 557 538 525 재미 코 후미 화 이제훈 일본인 감독 481 473 471 438 361 356 354 박열 분 내용 함 줄 최고 인물 351 336 333 316 304 296 280 연기력 스토리 나 듯 중간 사람 이 278 269 263 263 263 261 261 음 만 님 점 일 이준익 실화 260 246 243 236 226 223 220 감사 몰입 들이 시간 사실 최희서 평점 218 211 210 195 194 192 191 본 기대 번 해서 말 우리 재밌게 190 188 188 173 172 172 172 중 ^ㅎ 저 데 그 연출 리얼 170 169 168 164 156 155 154 가슴 ㅠ ^ㅋ 동주 잔잔 두 독립 153 148 146 146 143 142 140 때 여자 시대 박열이라는 이야기 여배우 주인공 134 134 131 130 128 127 125 웃음 장면 도 작품 한국인 추천 일본어 122 121 120 120 119 118 113 부분 기억 하나 훌륭 사랑 고증 대단 108 106 105 104 103 102 102 내 박열과 애국심 지 여주인공 매력 표현 101 101 101 101 100 99 99 눈물 대한 98 98 | cs |
보기만해도 정신사나운 데이터입니다. 가장 많은 단어가 공백이고
^ㅋ와 같은 특수문자는 물론 보조사와 명사들이 붙어 나오거나
만, 듯, 수 등 보통명사가 아닌 의존명사들이 하나의 명사로 등록되어 있습니다.
(한국어문법상 의존명사도 실질형태소이자 자립형태소로 분류하기 때문입니다.)
그래도 한번 워드클라우드에 띄워봅시다.
처음 해본 것과 같이 wordcloud() 에는 데이터와 빈도수가 파라미터로 들어간다고 했습니다.
names()를 이용하면 table의 제목을 벡터형식으로 뽑아낼 수 있는데 이를 data로 넣고
table 내용물은 그대로 빈도수(freq)에 넣습니다.
1 2 | wordcloud(names(wordcount_top), wordcount_top) | cs |
조금 그럴듯해지지 않았나요?
등록
이제 전처리가 필요합니다.
영화리뷰를 써보거나 본 분들은 알겠지만 요즘은 신조어 등으로 제대로 된 데이터를 뽑기가 힘듭니다.
사전에 없는 단어들이고, 그것마저 사람마다 여러 형태로 변형해서 쓰며 띄어쓰기는 고사하고 오타가 너무나 빈번하기 때문입니다.
그래도 처리는 해야하기 때문에
KoLNP의 사전에 mergeUserDic() 을 사용해 우리가 수동으로 단어들을 등록해줘야만 합니다.
간단히 예를 들면 '꿀잼', '노답' 등등 많이 쓰이면서도 사전에는 없는 단어들을 등록해주어야 합니다.
(ncn은 형태소분석상 명사라는 뜻입니다. 자세한 형태소분석태그를 보고 싶으면: http://kkma.snu.ac.kr/documents/index.jsp?doc=postag 링크를 참조하세요.)
1 2 3 4 5 6 7 8 | > mergeUserDic(data.frame(c("노잼"), "ncn")) 1 words were added to dic_user.txt. | cs |
(밑의 경고메시지는 무시해도 됩니다.)
이렇게 한줄 한줄 단어를 어느세월에 추가할 수 있을까요?
한꺼번에 등록하기 위해서 반복문을 사용할 수 있습니다.
메모장에 한줄한줄 새로 추가할 단어를 쓰고, 반복문(for)으로 한줄씩 읽어들이면서 한꺼번에 merge시키는 것입니다.
setwd()를 이용해 경로를 새로 만든 단어집이 있는 곳으로 재설정해주는 과정을 거치거나,
현재 진행중인 코드가 있는 폴더에서 단어집을 만들어야 합니다.
1 2 3 4 5 6 | setwd("D:/R_Practice/Practice") add_dic <- readLines("addNoun.txt") for(i in 1:length(add_dic)){ mergeUserDic(data.frame(add_dic[i], "ncn")) } | cs |
이런식으로 한 번에 추가하고,
1 2 3 4 | 1 words were added to dic_user.txt. 1 words were added to dic_user.txt. 1 words were added to dic_user.txt. | cs |
대충 이렇게 뜨면 성공입니다. (경고는 또 무시합시다)
1 | mergeUserDic(data.frame(readLines("addNoun.txt"), "ncn")) | cs |
이후, 위에서 했던 extractNoun부터
1 2 | data <- sapply(data, extractNoun, USE.NAMES = F) | cs |
차근차근 wordcount table을 빼는 곳까지 반복하면 새로운 단어가 추가되어 정리된 것을 볼 수 있습니다.
R은 인터프리터 언어라 위로 올려서 같은 코드를 블럭해 실행하면 다시 타이핑할 필요가 없으니 까먹지 말고 단어를 추가했으면 꼭 위로 올라가 반복합시다.
주의할 점은, merge 과정에서 대충 단어를 등록하면 전혀 다른 결과가 나온다는 것입니다.
요즘은 혹평받는 영화들이라도 베스트댓글 혹은 정성들여 쓴 댓글은 대부분 칭찬으로 되어 있으며,
욕하는 사람들은 대충 툭툭 던지지 굳이 댓글을 정성들여 쓰지 않습니다.
head()만으로 top100 단어를 보고 노잼, 극혐, 스렉 등과 같은 단어를 무심코 넘겨버렸다고 가정합시다.
씹노잼이네요, 씹노잼입니다, 씹노잼극혐, 씹노잼임, 개노잼 등등 수천가지의 문장에 들어있는 '노잼' 하나의 단어를 놓치면
혹평으로 가득한 영화임에도 결과창에는 '연기', '감동' 등과 같은 긍정적인 단어가 가장 많이 나오는 경우가 있습니다.
5. 전처리 - filter() 필터
다음은 필터입니다. filter()는 내가 만든 함수를 적용시키는 메서드입니다.
1 2 | data_unlist <- Filter(function(x){nchar(x)>=2}, data_unlist) | cs |
2글자 이상의 단어만 걸러주는 함수를 만들어 넣었습니다.
약간 복잡해 보일 수 있으나 구조는 생각보다 단순합니다.
함수의 기본구조는 function(파라미터){ 함수내용 } 으로, 위 Filter() 안에 쓰인 nchar(x)는 파라미터 x의 길이를 구해주는 메소드입니다.
즉 data_unlist 에 들어있는 우리의 데이터들이 하나씩 function() 안에 x로써 들어가고,
nchar(x)>=2 를 통해 2글자 이상인 단어만 살아남아 다시 data_unlist에 담기는 구조입니다.
이것만으로도 데, 등, 도, 수 와 같은 수많은 의존명사들을 거를 수 있습니다. 위에서 언급했듯 한국어문법상 의존명사도 실질형태소이자 자립형태소이기 때문에 이 과정은 필수입니다.
6. 전처리 - gsup() 불용어처리 (중요)
다음은 불용어처리인데, gsub(찾을 단어, 바꿀 단어, 찾을 곳)을 이용하여 바꿔줄 수 있습니다.
불용어란 주제색인어로서 의미가 없는 단어들을 의미합니다.
내가 워드클라우드를 만들고자 할 때 필요없거나 원하지 않는 단어를 제거함은 물론이요,
동사나 형용사의 활용형을 기본형으로 바꾸거나 ( ex)달리는 -> 달리다 )
같은 명사인데 다른 조사나 보조사가 붙은 것들을 모두 제거하여 하나의 단어로 통일시키는 등
빠져서는 안되는 필수적 과정입니다.
아까 봤던 테이블에서, 영화라는 단어의 빈도가 가장 많았습니다.
영화 리뷰임을 이미 알고 있는데 영화라는 단어가 워드클라우드의 메인에 자리잡는것은 원하지 않습니다.
지워버리도록 하겠습니다.
문자열은 "" 처리로 없는 것처럼 눈속임이 가능합니다.
아래와 같은 방법으로 필요없는 기본단어를 제거할 수 있습니다.
1 | data_unlist <- gsub("영화", "", data_unlist) | cs |
그러나 이 방법은 사실상 비효율적입니다.
'영화'는 지워지겠지만 '영화를' 이라는 단어는 '영화'가 ""로 대체되어 '를' 이라는 단어가 됩니다.
'이영화를' '그영화는' 이렇게 띄어쓰기를 하지 않아 한 단어로 분류되어버린 단어가 있었다면
'영화'가 ""로 사라졌으므로 '이를', '그는' 이라는 전혀 딴판의 단어로 바뀌어 버립니다.
여기서 정규표현식이라는 것이 필요합니다.
정규표현식은 모든 프로그래밍 언어에서 널리 쓰이므로 알아두는 것도 좋겠습니다.
아래의 링크를 참조하세요.
- 위키: https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%ED%91%9C%ED%98%84%EC%8B%9D
- R 정규식 : https://statkclee.github.io/ds-authoring/regex-r.html
특수문자 삭제
1 | data_unlist<- gsub('[~!@#$%&*()_+=?<>]','',data_unlist) | cs |
아마 저 안에 등록해도 몇몇 특수문자는 삭제가 잘 되지 않을 것입니다.
용도가 정해진 특수문자들이 있는데, R에서 그 특수문자를 걸러버리기 때문입니다. (위 링크 참조)
\\를 앞에 사용하면 텍스트 그대로 인식하니 삭제하면 됩니다.
아래는 간단한 예입니다.
1 | data_unlist <- gsub("\\[","",data_unlist) | cs |
자음 삭제(ㅋㅋ,ㅎㅎ,ㅇㅇ 등)
1 | data_unlist <- gsub('[ㄱ-ㅎ]','',data_unlist) | cs |
ㅜㅜ나 ㅠㅠ 등 삭제
1 | data_unlist<- gsub('(ㅜ|ㅠ)','',data_unlist) | cs |
숫자 삭제
1 | data_unlist <- gsub("\\d+","",data_unlist) | cs |
이렇게 여러 불용어처리 후에는, 위의 필터를 이용해 한번 더 2글자 미만 단어를 걸러줘야 합니다.
"" 눈속임으로 빈 칸이 되어버리고 붙어있던 특수문자나 숫자, 자모가 없어지면서 2글자 미만 단어가 많이 생겼을 것이기 때문입니다.
여기까지 했으면
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 | data_unlist 박열 연기 재밌 스토 이준 이제훈 최희 405 358 333 269 223 209 193 영화 한국 박열이라 여배 주인 애국 우리 182 174 130 128 128 123 105 여주인 독립 운동 최희서 아나키스 여주 박열이 101 88 88 87 67 62 60 조선 재밌어 한국영 잘봤습니 후미 인물 캐릭 57 51 50 49 49 48 48 감사 일제 다시한 봤습 사람 일제강점 추천 47 46 45 43 41 41 41 독립투 재밌었 캐스 분위 이영화 이준익감 일본사 40 39 39 37 37 37 37 좋았습 연출 임팩 재밋 이준익감독 영화였습 시간 36 35 35 35 33 32 31 실존 포스 최희서라 박열보 재밌었어 지루 한국사 30 30 29 28 28 28 28 쓰레 아쉬 재판 재미 긴장 로맨 이런영화 27 27 27 26 25 24 24 이준익 재밌습니 민족 평론 개연 한마 10 24 23 22 22 21 21 20 OO 좋은영 최고 시대 명연 역사 주연 20 20 20 19 18 18 18 감동 꼭보세 소소 관동대지 다큐멘터 인상깊 잘봤습 17 17 17 16 16 16 16 집중 감정 같습 국뽕 잘봤 잘봤습니다 재발 16 15 15 15 15 15 15 쪽바 한국배 스타 잘봤어 재밌다 친일 류승범 15 15 14 14 14 14 13 메시 무언 13 13 | cs |
아직도 이렇게 어이없는 데이터가 나오게 됩니다.
불용어처리가 덜 되었기 때문입니다.
마찬가지로 따로 텍스트파일을 저장해서 쓸모없는 단어들을 교체하거나 지우는 과정을 거치도록 합시다.
조사와 어미 등이 어간에 붙어버리면 이걸 구별할 방법이 R에서는 사실상 없고 띄어쓰기가 잘 안 된 문장도 형태소분석이 거의 불가합니다. 노가다 하세요.
예를 들어
1. '아버지가방에들어가신다'를 KoNLP로 분석하면 '아버지가방에들어가신'이 명사로, '다'가 어미로 분류됩니다.
띄어쓰기가 되어있지 않으면 거의 분석이 불가한 수준임을 알 수 있습니다.
2. '구경꾼'이라는 단어를 분석하면 '구경'과 '꾼'으로 나눠버립니다.
구경꾼은 구경이라는 명사에 명사파생접미사 -꾼이 붙어 구경꾼이라는 하나의 명사가 된 것입니다.
'꾼'이라는 단어가 있기는 하지만 이건 띄어쓰기가 되어있지 않음에도 나눠집니다.
마찬가지로 고급스럽다, 평화롭다 등등 파생접미사가 붙은 단어들은 거의 분류하지 못한다고 봐도 좋습니다.
3. 2.와 연관되어 있는데 '잠을 잠'을 분석하면 잠, 잠으로 나눠집니다.
앞의 잠은 '자-'의 어간에 명사파생접미사 -ㅁ이 붙은 명사지만 뒤의 잠은 명사형 어미 -ㅁ이 붙은 동사입니다.
어떤 알고리즘인지 모르겠으나 그냥 사전에 명사로 등록되어 있는 단어가 있으면 전부 명사로 인식해버리는 것이 아닌가 싶습니다.
4. '재밌다' 를 분석하면 '재밌'을 명사로 뱉어냅니다.
'재밌다'는 '재미있다'라는 형용사의 준말이고 이것은 재미있- 이라는 어간과 어미 -다가 붙은 것입니다.
어떻게 보아도 어간인 '재밌-'이 명사로 나오는 것은 이해할 수 없습니다. 아예 나오지 않으면 모를까..
마찬가지로 '재미있다'를 분석해도 어간 '재미있-'이 명사로 튀어나옵니다.
알고리즘상 어미와 조사 몇개만을 정해놓고 앞에 붙은 것은 명사로 도매처리하는 것인가 싶습니다.
이렇게 추측하는 이유는 파생접미사 '-하'와 어미 '-다'가 붙은 꼴인 기본 형용사 '순수하다', '정직하다' 등에서는 명사를 잘 빼오지만 '정직하였다'와 같이 선어말어미 하나로 조금만 변화를 줘도 전혀 분석하지 못하기 때문입니다. ㅎㅎ;
자바의 형태소분석기 라이브러리들은 조금 더 똑똑하게 분류하는 것 같으니 텍스트마이닝만 따로 하고 싶다면 참고합시다.
하지만 이게 귀찮다고 대충 하면 위에서 말했듯 정반대의 결과가 나올 가능성이 있으니..
가장 좋은 방법은 head()를 뽑아보지 말고 전체 wordcount 를 확인해서 가장 밑에서부터 차근차근 gsup()해주는 것입니다. ^오^
정규식을 이용하면 이 귀찮음을 조금은 덜 수 있으니 꼭 활용합시다.
단어들을 보다 보면 띄어쓰기가 되지 않아 단어로 인식하지 못한 것들을 찾을 수 있습니다.
멍청하게도 단어를 사전에 추가했지만 인식하지 못하는 경우들이 있는 것입니다.
'박열이라는사람이', '박열이이렇게나' '박열에게꼭' ... 과 같은 경우입니다.
보통 이런 경우 '박열'이라는 명사를 제외한 뒤의 어미나 조사 등등의 형식형태소들은 필요없게 됩니다.
이 gsup의 바꿀 단어 안에 정규식을 이용합시다.
1 | data_unlist = gsub("박열\\S*", "박열", data_unlist) | cs |
\S 라는 말은 박열 뒤에 붙은 공백,탭,개행을 제외한 모든 문자라는 말이고, 뒤의 *는 뒤에 몇글자가 오든 상관없다는 뜻입니다.
즉 "박열\\S*"의 뜻은
'박열이라는 단어 뒤에 뭐가 얼마나 붙었는지간에' 라는 의미입니다.
(참조)
*
: 적어도 0 번 매칭한다.+
: 적어도 1 번 매칭한다.?
: 많아아 1 번 매칭한다.{n}
: 정확히 n 번 매칭한다.{n,}
: 적어도 n 번 매칭한다.{n,m}
: n 번에서 m 번 매칭한다.
이렇게 하면 박열로 시작하고 뒤에 뭐가 붙었든 전부 선택해서 박열로 바꿔버리게 됩니다.
상기 언급한 바와 같이 어떤 단어에 접두사와 접미사(혹은 보조사나 조사) 등이 모두 붙어버렸으면
단순 gsup()으로는 전혀 다른 단어를 만들어버릴 수 있기 때문에 추천하지 않습니다.
정규식을 활용해 각자 열심히 전처리를 해 봅시다.
그리고 gsup()도 mergeUserDic()과 마찬가지로, 메모장에 단어들을 등록해놓고 한꺼번에 불용어처리 할 수 있습니다.
다 해보셨다고 가정하고 이제 결과를 낼 시간입니다.
100개만 추려서 대충 처리했습니다.
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 32 33 34 35 36 | data_unlist 박열 최희서 이준익 연기 스토리 이제훈 793 358 346 339 262 209 여주 한국 잘봤어요 여배우 주인 애국 179 172 137 129 126 119 좋았어 우리 후미코 재밌어 독립 운동 112 102 102 100 84 83 아나키스트 조선 다시 캐릭터 한국영화 인물 69 54 53 49 49 48 인상 일제 캐스팅 감사 사람 일제강점기 47 46 45 44 43 41 독립투사 국뽕 일본사 추천 분위기 임팩트 39 38 38 38 37 37 역사 좋은 연출 노잼 실존 감동 36 35 34 33 30 28 관동대지진 시간 쓰레기 오글 지루 한국사 28 28 28 28 28 28 로맨스 아쉬 재판 포스 재미 긴장 27 27 27 27 26 24 다큐 꼭보세요 민족 개연 시대 좋은영화 23 22 22 21 20 20 최고 평론 남주 자극 명연기 주연 20 20 19 19 18 18 쪽바리 한마디 소소 오랜만 집중 가네코후미코 18 18 17 16 16 15 감정 재발 몰랐어 스타 마케팅 메시 15 15 14 14 13 13 무언 상업 전개 트랜스 당시 류승범 13 13 13 13 12 12 빨갱이 생각 스크린 이미지 재조명 존경 12 12 12 12 12 12 친일 코미 201 강점 기대 무정부주의 12 12 11 11 11 11 시나리 시사 실화 11 11 11 | cs |
(재밌다, 좋았다 류는 명사가 아니지만 평점류 의견에서 무시하기 힘들다고 생각하여 '-어' 형태로 통일했습니다.)
7. 출력
wordcloud에 옵션을 주는건 포스팅 첫 부분의 옵션을 참고해
1 2 | wordcloud(names(wordcount_top), wordcount_top, scale=c(5,0.5),random.order = FALSE, random.color = TRUE, colors = color, family = "font") | cs |
이런식으로 한땀한땀 주면 됩니다.
colors 에 들어있는 변수 color는 아까 사용하겠다고 선언한 패키지인 RColorBrewer를 이용한 것입니다.
RColorBrewer
전체 제공하는 색깔을 보기 위해서는 이렇게 타이핑해 봅시다.
1 | display.brewer.all() | cs |
실행하면 오른쪽 창에 팔레트가 뜹니다.
색깔세트의 이름과 개수가 보일 텐데, 이걸
1 | color <- brewer.pal(12, "Set3") | cs |
이런 식으로 변수에 담아 사용하면 됩니다.
첫번째 매개변수는 내가 활용할 색깔 개수고(팔레트의 최대치를 넘을 수 없습니다), 두번째 매개변수는 색 세트의 이름입니다.
Font
1 | windowsFonts(font=windowsFont("a한글사랑L")) | cs |
폰트는 위 코드와 같이 가져올 수 있습니다.
font 변수에 a한글사랑L 폰트를 담은 겁니다.
wordcloud family 속성에 위 변수를 담아주면 됩니다.
결과
그럴듯한 워드클라우드를 완성했습니다.
폰트들에 보면 기본적으로 Bold(굵게) 옵션이 주어진 것들이 있습니다.
단어의 개수를 많이 늘리고(응 전처리~), 폰트만 잘 골라주면 처음 올렸던 사진과 비슷한 워드클라우드가 완성될 것입니다.