안녕하십니까!
3주만에 돌아왔습니다,, 그동안 여행도 다녀오고 책을 혼자 진행해보고 다시 업로드 하는 식으로 하다보니 이렇게 오래 걸렸네요!
죄송합니다.. ㅎㅎㅎㅎ 꾸준히 업로드 해보겠습니다!!!!
이번 포스팅은 텍스트 마이닝에 대해 진행해 볼 예정입니다!
문자로 된 데이터에서 가치 잇는 정보를 얻어 내는 분석 기법을 '텍스트 마이닝'이라고 합니다.
텍스트 마이닝을 진행하기 전에, 문장을 구성하는 어절들이 어떤 품사로 되어 있는지 파악하는 '형태소 분석' 작업을 진행합니다!
명사, 동사, 형용사 등 의미를 지닌 품사의 단어를 추출해 각 단어들이 어느 정도의 빈도로 나타났는지 확인해야하죠!
이번 챕터에서는 음악 가사, SNS 속 글을 분석해보도록 하겠습니다!
저는 지금까지 R을 공부하면서 가장 어렵고 진행에 어려움을 겪은 부분이 바로 '텍스트 마이닝'입니다..
패키지를 설치하고 로딩하는 그 모든 과정에서 오류가 나타났죠,,,
여러분들은 꼭 쉽게 성공할 수 있도록 포스팅 슈웃!
# 텍스트 마이닝 준비하기
텍스트 마이닝 이전에 우리는 형태소 분석을 실시해야합니다.
KoLNP(Korean Natural Language Processing) 패키지를 이용하면 한글 텍스트의 형태소를 분석할 수 있기에 이를 설치!
1. 자바와 rJava 패키지 설치하기
KoLNP 패키지는 '자바'와 rJava 패키지가 설치되어 있어야 사용할 수 있고, 이 둘은 multilinguer 패키지의 install_jdk()를 이용해 설치 가능합니다!
install.packages("multilinguer")
library(multilinguer)
> install_jdk()
ℹ Target JDK: amazon-corretto-11-x64-windows-jdk.msi
Are you sure you want to install jdk?
1: No way
2: Yeah
3: Negative
선택: 2
이렇게 코드를 실행해주면 jdk를 설치하고 완료까지 할 수 있습니다!
2. KoLNP 의존성 패키지 설치하기
A 패키지가 B 패키지의 기능을 이용한다고 했을 때, B를 함께 설치해야만 작동합니다. 이러한 관계를 '의존성 패키지'라고 합니다.
*KoLNP 의존성 패키지를 먼저 설치하기
#KoLNP 패키지 사용 위해 의존성 패키지 설치
> install.packages(c("stringr", "hash", "tau", "Sejong", "RSQLite", "devtools"),
+ type = "binary")
3. KoLNP 패키지 설치하기
install.packages("remotes")
remotes::install_github("haven-jeon/KoNLP",
+ upgrade = "never",
+ INSTALL_opts = c("--no-multiarch"))
Skipping install of 'KoNLP' from a github remote, the SHA1 (960fbbcf) has not changed since last install.
Use `force = TRUE` to force installation
remotes 패키지의 install_github()를 이용해 깃허브에 있는 KoLNP 패키지를 설치할 수 있습니다.
저 같은 경우에는 이미 설치되어 있기에, ~has not changed since last install. 이라는 메시지가 출력되었으며, 아래와 같이 force = T를 추가로 입력하면 강제로 설치할 수 있습니다.
remotes::install_github("haven-jeon/KoNLP",
+ upgrade = "never",
+ INSTALL_opts = c("--no-multiarch"),
+ force = T)
library(KoNLP)
library(KoLNP)를 통해 KoLNP 패키지를 로드하면, 오류가 날 수 있습니다,,
Fail to locate 'scala-library-2.11.8.jar'. Recommand to locate 'scala-library-2.11.8.jar' manually on C:/Users/82107/AppData/Local/R/win-library/4.2/KoNLP/java
이러한 형태의 오류 메세지가 출력될 것이며, 저 같은 경우에는
이 블로그를 참고하여 java 파일을 새로 다운로드 받고,
C:/Users/82107/AppData/Local/R/win-library/4.2/KoNLP
위의 주소에 존재하는 java 파일을 통채로 덮어쓰기 해주었더니 이 오류가 해결되었습니다ㅠㅠ 도움이 되길 바랄게요!!
4. 형태소 사전 설정하기
KoLNP 패키지가 사용하는 'NIA 사전' - useNIADic() : 아래와 같이 출력될 것입니다!
useNIADic()
Backup was just finished!
1213109 words dictionary was built.
5. 데이터 준비하기
깃허브에 존재하는 hiphop.txt 파일을 다운로드 하고, readLines()로 불러와 일부를 출력할 예정입니다!
txt <- readLines("hiphop.txt")
head(txt)
[1] "\"보고 싶다" "이렇게 말하니까 더 보고 싶다" "너희 사진을 보고 있어도"
[4] "보고 싶다" "너무 야속한 시간" "나는 우리가 밉다"
6. 특수문자 제거하기
문장에 이모티콘이나 특수문자가 포함되어 있으면 오류가 발생할 수 있으니 이를 제거하는 작업을 거쳐야합니다!
문자처리 패키지(stringr의 str_replace_all())을 이용하겠습니다!
install.packages("stringr")
library(stringr)
txt <- str_replace_all(txt, "\\W", " ")
이렇게 stringr 패키지를 설치하고 로드 후, txt 파일 내에 \\W (특수문자를 의미)를 빈칸으로 수정하는 작업입니다.
다섯 번째 단계에서의 head(txt)와 비교해보겠습니다.
head(txt)
[1] " 보고 싶다" "이렇게 말하니까 더 보고 싶다" "너희 사진을 보고 있어도"
[4] "보고 싶다" "너무 야속한 시간" "나는 우리가 밉다"
맨 처음 존재하는 역슬래시가 사라졌습니다!
이젠 준비 단계를 다 진행했습니다!
가장 많이 사용된 단어를 알아보겠습니다.
1. 명사 추출하기
extractNoun("대한민국의 영토는 한반도와 그 부속도서로 한다")
[1] "대한민국" "영토" "한반도" "부속도서" "한"
위의 예시와 같이 명사가 추출됩니다! (마지막 한은 명사인가요,,?)
2. 힙합 가사에서 추출하기!
명사를 추출하고 각 단어가 몇 번 사용되었는지 그 빈도표도 만들어보겠습니다.
nouns <- extractNoun(txt)
> wordcount <- table(unlist(nouns))
> df_word <- as.data.frame(wordcount, stringsAsFactors = F)
> df_word <- rename(df_word,
+ word = Var1,
+ freq = Freq)
txt에서 명사를 추출한 것을 nouns이라 하고, 추출한 명사 list를 문자열 벡터로 변환하고 단어별 빈도표를 생성한 것을 wordcount라고 합니다. 이를 데이터 프레임으로 변경하고, 그 변수명들을 word와 freq로 수정하는 작업을 거쳤습니다.
3. 자주 사용된 단어 빈도표 만들기
#3. 자주 사용된 단어 빈도표 만들기
> df_word <- filter(df_word, nchar(word) >= 2)
한 글자로 된 단어는 보통 의미가 없기에 두 글자 이상 된것으로 추출할 것이며, nchar(word) >=2 word가 두 글자 이상인 것을 추출하는 것을 의미하는 코드입니다.
4. 빈도 순으로 정렬 후 상위 20개 단어 추출하기
#4. 빈도 순으로 정렬 후 상위 20개 단어 추출
> top20 <- df_word %>%
+ arrange(desc(freq)) %>%
+ head(20)
> top20
word freq
1 you 89
2 my 86
3 YAH 80
4 on 76
5 하나 75
6 오늘 51
7 and 49
8 사랑 49
9 like 48
10 우리 48
11 the 43
12 시간 39
13 love 38
14 to 38
15 we 36
16 it 33
17 em 32
18 not 32
19 역사 31
20 flex 30
top20이라는 변수를 하나 생성하여 빈도수에 따라 내림차순(arrange(desc(freq)) 정렬하여 상위 20개(head(20))을 추출할 수 있습니다!
# 워드 클라우드 만들기
워드 클라우드란, 단어의 빈도를 구름 모양으로 표현한 그래프입니다!
단어의 빈도에 따라 글자의 크기와 색깔이 다르게 표현되기 때문에 그 빈도를 파악할 수 있습니다!
1. 패키지 준비하기
install.packages("wordcloud")
library(wordcloud)
library(RColorBrewer)
wordcloud 패키지를 이용하기 위해 패키지를 먼저 설치하고, wordcloud를 로드, 내부에 색을 입히는 패키지인 RColorBrewer 패키지를 로드하는 과정입니다.
2. 단어 색상 목록 만들기
RColorBrewer 패키지의 brewer.pal()를 이용할 것이며, 괄호 안에 추출할 색상 갯수, 색상 목록명을 입력하면 됩니다.
pal <- brewer.pal(8, "Dark2")
pal이라는 색상 목록을 "Dark2" 색상 목록에서 8개 추출한 것을 입력할 수 있습니다.
3. 난수 고정하기
wordcloud()는 함수를 실행할 때마다 난수를 이용해 매번 다른 모양의 워드 클라우드를 만들어냅니다. 이를 고정하기 위해 set.seed()로 난수를 고정할 수 있습니다.
set.seed(1234)
4. 워드 클라우드 만들기
df_word를 이용해 만들 것이며, 이는 단어와 빈도 두 변수로 구성된 데이터 프레임임을 알고 있습니다.
wordcloud의 파라미터들은 워드 클라우드의 모양을 결정하며 word, freq, min.freq, max.words, random.order, rot.per, scale, colors 등 여러 가지 파라미터들이 있으며, 실행 코드를 통해 살펴보도록 하겠습니다.
random.order 파라미터의 경우 F로 입력하였을 때, 고빈도 단어가 중앙에 배치됩니다!
wordcloud(words = df_word$word, #단어
+ freq = df_word$freq, #빈도
+ min.freq = 2, #최소 단어 빈도
+ max.words = 200, #표현 단어 수
+ random.order = F, #고빈도 단어 중앙 배치
+ rot.per = .1, #회전 단어 비율
+ scale = c(4, 0.3), #단어 크긱 범위
+ colors = pal) #색상 목록
이렇게 워드 클라우드를 얻을 수 있으며, 많이 사용된 단어일수록 글자가 크고 가운데에 배치되며, 덜 사용될수록 작고 바깥쪽에 배치되는 형태로 구성되어있습니다!
단어 색상을 변경하고 싶은 경우 단어 색상 목록을 새로이 설정하여 wordcloud 내에 색상 목록을 새로 입력하면 됩니다!
다음은, 다른 자료들을 통해 텍스트 마이닝을 진행하겠습니다!
#10-2 국정원 트윗 텍스트 마이닝
1. 데이터 준비하기
twitter라는 데이터 프레임을 만들어보겠습니다.
twitter <- read.csv("twitter.csv",
+ header = T,
+ fileEncoding = "UTF-8")
csv 파일을 불러오면서, 첫 행을 헤더로 처리하여 컬럼의 이름으로 설정하는 것, fileEncoding의 경우 UTF-8로 설정하여 한글 파일임에도 깨지지 않게 불러올 수 있습니다.
다음은 변수명이 한글로 되어있기 때문에 영어로 변수명을 수정하겠습니다.
X 번호 계정이름 작성일
1 1 1 ahkorea 11/2/2011
2 2 2 parkkeewoo 12/30/2011
3 3 3 zndvn33 1/5/2012
4 4 4 hong_jihee77 1/23/2012
5 5 5 ceasar1000 2/5/2012
6 6 6 sunsetyellowsky 2/13/2012
내용
twitter <- rename(twitter,
+ no = 번호,
+ id = 계정이름,
+ date = 작성일,
+ tw = 내용)
X no id date
1 1 1 ahkorea 11/2/2011
2 2 2 parkkeewoo 12/30/2011
3 3 3 zndvn33 1/5/2012
4 4 4 hong_jihee77 1/23/2012
5 5 5 ceasar1000 2/5/2012
6 6 6 sunsetyellowsky 2/13/2012
tw
초기 결과값과 rename을 처리한 결과 변수명들이 상이한 것을 확인할 수 있습니다.
이후, 힙합 가사 텍스트 마이닝에서 거친 과정과 같이 특수문자를 제거해야합니다!
str_replace_all 함수입니다!
twitter$tw <- str_replace_all(twitter$tw, "\\W", " ")
tw(기존의 내용)에 많은 특수 문자를 제거할 수 있습니다.
2. 단어 빈도표 만들기
힙합 가사 텍스트 마이닝과 동일한 과정을 거쳐 df_word1이라는 변수를 만들겠습니다!
nouns1 <- extractNoun(twitter$tw) #트윗에서 명사 추출
> wordcount1 <- table(unlist(nouns1)) #추출한 명사 list를 문자열 벡터로 변환, 단어별 빈도표 생성
> df_word1 <- as.data.frame(wordcount1, stringsAsFactors = F)#데이터 프레임으로 변환
> df_word1 <- rename(df_word1, #변수명 수정
+ word = Var1,
+ freq = Freq)
# stringsAsFactor=F 옵션 추가
# Species 변수를 chr 타입으로 불러옴
stringsAsFactors = F 필수입니다!!!! filter 함수를 사용하기 위해 chr 변수로 불러오기 기능을 해요!
3. 두 글자 이상으로 된 단어 추출, 빈도 순으로 정렬하여 top20 추출하기
df_word1 <- filter(df_word1, nchar(word) >= 2)
top20_1 <- df_word1 %>%
+ arrange(desc(freq)) %>%
+ head(20)
> top20_1
word freq
1 종북 2431
2 북한 2216
3 세력 1162
4 좌파 829
5 대한민국 804
6 우리 780
7 들이 566
8 국민 550
9 친북 430
10 단체 394
11 김정일 342
12 진보 335
13 대선 329
14 천안함 319
15 사회 307
16 정부 286
17 전교조 278
18 주장 269
19 정권 265
20 연평도 262
4. 단어 빈도 막대 그래프 만들기
order <- arrange(top20_1, freq)$word
빈도 변수를 생성하여 scale_x_discrete(limit = order)를 진행하기 위해!
ggplot(data = top20_1, aes(x= word, y = freq)) +
+ ylim(0,2500) +
+ geom_col() +
+ coord_flip() +
+ scale_x_discrete(limit = order) + #빈도순 막대 정렬
+ geom_text(aes(label = freq), hjust = 0.1) #빈도 표시
top20_1을 데이터로 하여, x축은 word, y축은 freq, y축의 최댓값을 2500으로 설정하고, geom_col을 통해 막대 그래프를 얻습니다. 이후 축 회전을 위해 coord_flip을 사용하고 나머지 코드를 실행하면 됩니다!
5. 워드 클라우드 만들기
워드 클라우드는 힙합 가사와 동일한 값으로 진행해보겠습니다! 데이터만 바꾸면 되겠죠?
wordcloud(words = df_word1$word, #단어
+ freq = df_word1$freq, #빈도
+ min.freq = 2, #최소 단어 빈도
+ max.words = 200, #표현 단어 수
+ random.order = F, #고빈도 단어 중앙 배치
+ rot.per = .1, #회전 단어 비율
+ scale = c(4, 0.3), #단어 크긱 범위
+ colors = pal) #색상 목록
한 눈에 봐도 북한, 종북이란 단어가 많이 사용되었음을 알 수 있습니다!
다시금 포스팅을 진행하면서도 굉장히 어려웠던 챕터였습니다... 제가 실수했던 부분들을 조금 더 다뤄보았던 것 같아요!
텍스트 마이닝은 여기까지 해보겠습니다!
'R' 카테고리의 다른 글
데이터 분석 시작기-19 (단계 구분도 만들기) (0) | 2023.03.26 |
---|---|
데이터 분석 시작기-17 (데이터 분석 프로젝트_3) (0) | 2023.02.07 |
데이터 분석 시작기-16 (데이터 분석 프로젝트_2) (0) | 2023.02.06 |
데이터 분석 시작기-15 (데이터 분석 프로젝트_1) (0) | 2023.02.05 |
데이터 분석 시작기-14 (그래프 만들기) (0) | 2023.02.01 |