본문 바로가기

R/텍스트 마이닝

영문 데이터에 대한 텍스트 마이닝 - 2 with 캐글 영화 리뷰 데이터

Movie Review And Rating 

https://www.kaggle.com/newra008/movie-review-and-rating

 

Movie Review And Rating

Movies review from year 2016-2022

www.kaggle.com

 

 

전 포스팅에서 빈도분석, 비교분석을 통해 데이터의 특징을 파악하는 기초분석을 실시하였다.

 

https://normalpdf.tistory.com/16

 

영문 데이터에 대한 텍스트 마이닝 - 1 with 캐글 영화 리뷰 데이터

이번 포스팅에서는 빈도 / 비교 분석에 대하여 다룰 예정입니다. 이후 포스팅에서 감정분석도 진행하니 참고해주세요. 빈도분석 , 비교분석  Spider , Matrix , Snowden 범주 별 최다 빈도 수 단어 분석

normalpdf.tistory.com

 

이번에는 영화 리뷰,평점 데이터에 대해 감정분석을 실시하려고 한다.

 

이러한 영화 리뷰,평점데이터 감정분석의 목적은 무엇일까 ?

 

아마 영화제작사나 관련 업계에선 해당 영화가 상품성이 있는지가 가장 큰 관심사일 것이다.

리뷰에 긍정의 내용이 많은지 부정의 내용이 많은지에 따라 상품성을 판단할 수 있으니

리뷰데이터와 평점데이터를 이용하여 감정분석을 실시하려고 한다.

( 감정분석은 Spider 데이터만 활용하였다. )

 

이후 리뷰의 감정분석 결과와 Rating(평점)이 서로 관련있는지 확인해보겠다.

 

 

 

분석 전에 텍스트마이닝에서 기본적으로 필요로 하는 라이브러리를 모두 호출하였다.

# 텍스트마이닝 라이브러리
library(readr)
library(dplyr)
library(stringr)
library(tidytext)
library(ggplot2)
library(tm)
library(SnowballC)
library(tidyr)
library(textdata)
library(textclean)

 

 

1. 영문 감정사전 알아보기

한글 텍스트 마이닝을 할 때는 군산대학교 소프트웨어융합공학과에서 만든 'KNU 한국어 감성사전' 을

이용해 감정분석을 하였다.  영문 텍스트 마이닝은 어떤 감정사전을 이용하여 감정분석을 하는지 알아보자.

 

참고 : https://rstatistics.tistory.com/67

 

textdata 라이브러리에 다음과 같은 사전 데이터(dictionary-based)가 내장되어 있다.

  • afinn : 단어 별 부정과 긍정 사이에 -5에서 5점까지 스코어를 매긴 데이터
  • bing : 긍/부정을 binary로 나타낸 데이터 (positive, negative)
  • nrc : positive, negative 외에 세 가지 이상의 감정을 분류한 데이터

 

library(textdata)

get_sentiments("afinn")
get_sentiments("bing")
get_sentiments("nrc")

 

 

  • 'afinn' 사전에는 위과 같이 단어에 대한 긍/부정 점수가 나타나고,
  • "bing" 과 "nrc" 에는 감정이 나타나있다. "nrc" 사전 에는 "bing" 사전 보다 더 많은 감정들이 담겨져있다.

 

 

 

bing <- get_sentiments("bing")
unique(bing$sentiment) # bing 사전에 있는 두가지 감정들

 

 

nrc <- get_sentiments("nrc")
unique(nrc$sentiment) # nrc 사전에 있는 다양한 감정들

 

 

  •  nrc 는 긍 / 부정 이외에도 다양한 감정이 담겨있다.

 

- 영문 감정사전에도 특수문자가 존재할까 ?

한글 감정사전의 경우 특수문자가 존재했었다.

영문 감정사전에도 특수문자가 들어있는지 확인해보자.

 

# 세 감정사전에 특수문자가 포함되어 있는가?
afinn <- get_sentiments("afinn")
afinn %>% filter(!str_detect(word,"[A-z]")) %>%
          arrange(word)

bing %>% filter(!str_detect(word,"[A-z]")) %>%
          arrange(word)


nrc %>% filter(!str_detect(word,"[A-z]")) %>%
          arrange(word)

 

 

  • 영문 감정사전에는 특수문자가 존재하지 않음을 확인하였다.
  • 특수문자가 존재하지 않으므로 한글 감정분석과 달리 전처리 과정에서 특수문자까지 모두 제거해야 한다.
  • 따라서 전처리시 영어를 제외한 모든 문자를 제거하겠다.

 

- 세 개의 감정사전 중 어떤 감정사전을 이용할 것인가?

afinn , bing, nrc 감정사전을 모두 사용하면 각 사전마다 단어의 감정을 매기는 기준이 달라 점수 합산에 문제가 생긴다.

이에 관한 설명은 포스팅 마지막에 이어서 설명하겠다.

 

일단 감정 단어에 감정점수가 부여되어 있는 afinn 사전을 이용해서 분석을 진행하겠다.

 

 

2. 데이터 전처리

- 데이터 불러오기

raw_movie <- read_csv("C://WORK/R/Movie Review And Rating.csv")

# Spider  영화 데이터 추출
spider <- raw_movie %>%
  filter(Movie == "Spider-Man: No Way Home")
spider_review <- spider$Review  # 리뷰 데이터
spider_rating <- spider$Rating  # 평점 데이터

 

- 소문자 변환

앞에서 확인했듯이 사전에 등록된 단어들은 모두 소문자이다.

따라서 추출한 spider_review 데이터 또한 tolower() 함수를 이용하여 리뷰내용을 모두 소문자로 전환하겠다.

 

# 소문자로 변환 - 사전에 있는 단어들이 모두 소문자
spider_review <- tolower(spider_review)

 

 

  • spider_review 데이터를 보면 html 공백이 존재함을 확인할 수 있다.
  • 이는 전처리 과정에서 제거해주어야 한다.

 

- 고유 번호 변수 만들기

: 댓글의 내용이 같아도 구별할 수 있도록 mutate()  row_number() 를 이용해 고유 번호 id 를 추가

 

- html 특수 문자 제거하기

: 웹에서 만들어진 텍스트는 &nbsp; 같은 html 특수 문자가 포함되어 있어서 내용을 알아보기 불편하다.

: textclean 패키지 replace_html() 을 이용해 html 태그를 공백으로 바꾸고,

  stringr 패키지 str_squish() 를 이용해 중복 공백을 제거한다.

 

spider_review <- spider_review %>%
  as_tibble() %>%
  mutate(id = row_number(),
         reply = str_squish(str_replace_all(replace_html(value), "[^A-z]", " "))) %>% 
  select(id, reply)

 

  • 앞서 설명했듯이 "afinn" 감정사전에는 특수문자가 존재하지 않았으므로 영어를 제외한 모든문자를 공백 처리했다.
  • 분석에 적합하게 전처리가 됐음을 확인할 수 있다.

 

3. 토큰화 하기

unnest_tokens 함수에 token="words" 로 지정하여 단어 기준으로 토큰화 하였다.

 

# 단어 기준으로 토큰화

spider_comment <- spider_review %>%
  unnest_tokens(input = reply,
                output = word,
                token = "words",
                drop = F)

spider_comment %>%
  select(word, reply)

 

 

4. 감정 점수 부여하기

단어 기준으로 토큰화된 데이터에 감정점수를 부여하였다.

dplyr 패키지 left_join () 을 이용해 word 기준으로 감정 사전을 결합하면 각 단어에 감정 점수가 부여된다.

 

spider_comment <- spider_comment %>%
  left_join(afinn, by = "word") %>%  # afinn 사전과 결합
  mutate(polarity = ifelse(is.na(value), 0, value))  # 결측값은 0 값 부여

spider_comment %>%
  select(word, polarity)

 

 

  • 감정을 나타내는 단어가 아닌 것들은 polarity 에 0 을 부여하였다.

 

5. 댓글별 감정 점수 합산하기

평점과 감정점수를 비교하기 위해 평점변수도 추가하였다.

 

spider_score <- spider_comment %>%
  group_by(id, reply) %>%
  summarise(score = sum(polarity)) %>%
  ungroup() %>%
  mutate(rating = spider_rating)

 

 

6. 긍정 / 부정 댓글 살펴보기

score 변수를 내림차순 , 오름차순 정렬하여 각 긍정 / 부정 댓글이 무슨내용인지 확인해보자.

 

# 긍정 댓글
spider_score %>%
  select(score, rating, reply) %>%
  arrange(-score)     # 내림차순 정렬

# 부정 댓글
spider_score %>%
  select(score, rating, reply) %>%
  arrange(score)      # 오름차순 정렬

 

- 긍정 댓글

 

  •  incredible , amazing , masterpiece , great 와 같은 긍정적인 단어가 나타난다.
  • 대부분의 댓글 평점이 높게 나타난다.
  • 하지만 리뷰내용이 "줄거리가 지루하다 ~ " 식의 부정의 내용으로 평점이 1임에도 불구하고 감정점수가 높게 나온 경우가 있다. 
  • 이를 통해 감정사전을 수정할 필요가 있다고 판단하였다. 추후에 감정 사전 수정을 진행하겠다.

 

- 부정 댓글

 

+ 댓글 원문

'Got dragged to this by friends, and was not disappointed in how bad it sucked. The film does have stellar action scenes; and I can understand that if you like Spiderman, then you will love this film. I do not care about Peter Parker, he's a goof, and not cool or alpha. I did enjoy him in small doses, as an ensemble character in the Avenger films, but he cannot hold with me to lead a film. The costume is lame, and his powers are pretty boring. Never saw the last two films and will skip the next inevitable snoozefest, epic fail,' 

 

  • "이 영화의 유일한 좋은 점은 캐스팅이였다." , "의상도 구리고 능력도 지루했다." 등 부정적인 이야기가 담겨있다.
  • 대부분의 평점이 1,2 점대이다.
  • 감정점수가 음수인 경우는 6 개로 매우 적다.
  • 긍정 댓글과 마찬가지로 평점이 4점임에도 불구하고 감정점수가 높게나온 경우가 있다.

 

 

 

7. 자주 사용된 감정 단어 살펴보기

감정을 분류하고 , 중립단어를 제외한 긍정 / 부정 단어 중 자주 사용된 단어를 10개씩 추출해 막대그래프를 만들자.

   polarity : "afinn" 사전을 통해 감정 점수를 부여한 것

 

- 감정 분류하기

  • polarity 가 0 보다 크면  pos (긍정)
  • polarity 가 9 보다 작으면  neg (부정)
  • 그 외에는 neu (중립) 
# afinn 감정사전 점수를 이용하여 긍정/부정/중립 단어 분류
spider_afinn <- spider_comment %>%
  mutate(sentiment = ifelse(polarity >0, "pos",  
                             ifelse(polarity <0 , "neg","neu")))

 

- 상위 10개 단어 추출

중립단어를 제외한 긍 / 부정 단어 상위 10개를 추출하였다.

 

# 긍정 / 부정 단어 중 자주 사용된 단어 10개씩 추출 

top10_spider_afinn <- spider_afinn %>%
  filter(sentiment != "neu") %>%  # 중립 단어는 제외
  count(sentiment, word) %>%
  group_by(sentiment) %>%
  slice_max(n, n = 10, with_ties =F ) # slice_max() : 값이 큰 상위 n개의 행을 추출해 내림차순으로 정렬하는 함수

top10_spider_afinn

 

- 막대그래프 그리기

library(ggplot2)
ggplot(top10_spider_afinn, aes(x = reorder(word, n), 
                            y = n, 
                            fill = sentiment)) +
  geom_col() +
  coord_flip() +
  geom_text(aes(label = n), hjust = -0.3) +
  facet_wrap(~ sentiment, scales = "free") +
  scale_y_continuous(expand = expansion(mult = c(0.05, 0.15))) +  
  labs(x = NULL) +
  ggtitle("감정 범주별 최다 빈도 단어") +  # 그래프 제목 지정
  theme(text = element_text(family = "nanumgothic"),
         plot.title = element_text(hjust=0.5))  # 제목 위치를 가운데로 지정

 

 

  • 그래프를 보면 긍정 최빈 단어에 "like , marvel" 이 상위에 존재한다
  • 하지만 Spider 영화의 제작사가 "marvel" 이고 , "like" 의 경우 전치사로 쓰이면 "~같은" 의 의미를 가지며     "doesn't like" 로 쓰였을 가능성도 있으므로 긍정적인 단어로 확정지어 분류하기 어렵다.
  • 추가로 "hero" 라는 단어를 사용한 문장도 10 개가 존재하는데 히어로물인 Spider 영화 특성상 이는 단순히        등장인물을 지칭하는 것이므로  긍정 단어로 분류시 문제가 생긴다. 

 

  • 따라서 이러한 감정단어가 쓰인 원문을 살펴보아야 한다.
  • 원문을 살펴본 후 감정 사전 수정을 진행하겠다.

 

 

 

- "hero" 라는 단어는 어떤 감정으로 분류되어 있을까? ( afinn 사전 기준 )

afinn %>% 
filter(str_detect(word,"hero"))

  • 긍정 단어로 분류되어 있다.

 

8. 감정 단어가 사용된 원문 살펴보기

spider_score %>% 
filter(str_detect(reply,"marvel"))  %>%   # marvel 이 쓰여진 문장 추출
select(reply)

spider_score %>% 
filter(str_detect(reply,"like"))  %>%   # like 이 쓰여진 문장 추출
select(reply)

spider_score %>% 
filter(str_detect(reply,"hero"))  %>%   # hero 이 쓰여진 문장 추출
select(reply)

 

- marvel 이 사용된 원문

 

+ 댓글 원문 ( Excel 추출 )

3. This opens so many timelines and possibilities for Marvel and Sony to create amazing stories. 

 

5. Marvel Universes, DC Universes, Covid_19 Universes, etc. 

 

6. it felt as if it was more marvel trying to pump nostalgia then anything instead of focusing on crafting a good,

   believe-able storyline. 

 

7. And seriously, after so many Marvel outings and so many losses and tragedies, how can they still show him 

   as a carefree kid! And What The Hell Happened to DON'T MESS WITH THE TIMELINES!!!!!!!!!! sad.

 

8. I and my friends saw this as the perfect opportunity for Marvel to showcase some cool stuff with the obvious

   introduction of the other two Spidermen but rather all we saw were unnecessary jokes stuffed in with a plot that     was lame tbf. 

 

10. the post credit teases pluging the next marvel movie kinda does answer some of the questions however.....

 

12. Marvel as a studio along with Sony learns to blend the best elements of all franchises together 

    in order to create the perfect on screen Spider-Man and this gave us a taste of it,

    especially in the manner it ended. 

 

13. The Movie ends opens up marvel to a completely new direction and it's exciting to see what comes next.

 

15. Worth the watch guys Sony and Marvel done a great job. 

 

 

  • 다음과 같이 "marvel " 이  원래 단어 뜻인 "경이롭다" 가 아닌
  • 단순히 영화 제작사를 지칭함을 알 수 있다.
  • 따라서 이 경우 긍정의 뜻을 담고 있지 않으므로 감정 사전의 감정 점수를 0 으로 수정해야 한다.

 

- like 가 사용된 원문

 

  •  like 가 사용된 원문을 보면,  원래 의미인 "좋다" 가 아닌 다른 의미로 사용됐음을 알 수 있다.
  • 이 경우도 감정 점수를 수정해야 한다.

 

- hero 가 사용된 원문 

spider_score %>% 
filter(str_detect(reply,"hero"))  %>%   # hero 이 쓰여진 문장 추출
select(reply)

 

이 경우 R 에서는 원문이 짤려 보이지 않아 Excel 에서 일부를 추출하였다.

 

- main character of a superhero/comic 

- female superhero 

- Super Hero Comic Book

 

 

  • hero 라는 단어 또한 spider 리뷰에서는 등장인물을 지칭하는 것으로 감정을 나타내는 단어로 보면 안된다.

 

9. 감정 사전 수정하기

-  감정 사전 수정 전  "marvel , like, hero" 의 감정점수 확인

 각 단어 "marvel , like, hero" 가 감정사전 afinn 에서 어떤 점수를 가지고 있나 확인해보자.

afinn %>% 
filter(word %in% c("marvel","like","hero"))

  • "hero , llike" 는 감정 점수가 2점이고 , "mavel" 은 감정 점수가 3 점이다.
  • 이 단어들은 Spider 영화리뷰에서 감정을 나타내는 단어가 아니므로 감정점수를 0 으로 수정한다.

 

- 감정 사전 수정

new_afinn <- afinn %>%
  mutate(value = ifelse(word %in% c("marvel", "like", "hero"), 0, value))

new_afinn %>% filter(word %in% c("marvel", "like", "hero"))

 

  • 다음과 같이 감정 사전이 잘 수정되었음을 확인할 수 있다.

 

 

10. 수정한 감정 사전으로 감정 점수 구하기

# 수정한 감정사전으로 감정 점수 부여하기
new_spider_comment <- spider_comment %>%
  select(-polarity,-value) %>%  # 앞에서 부여한 감정 점수 제거
  left_join(new_afinn, by = "word") %>%
  mutate(polarity = ifelse(is.na(value), 0, value))


# 댓글별 감정 점수 구하기
new_spider_score <- new_spider_comment %>%
  group_by(id, reply) %>%
  summarise(score = sum(polarity)) %>%
  ungroup() %>%
  mutate(rating = spider_rating)  # 평점 변수 추가

 

이제 긍정 댓글과 부정 댓글을 살펴보자.

 

# 긍정 댓글
new_spider_score %>%
  select(score, rating, reply,) %>%
  arrange(-score)  # 내림차순 정렬


# 부정 댓글
new_spider_score %>%
  select(score, rating, reply) %>%
  arrange(score)  # 오름차순 정렬

 

- 긍정 댓글 

 

  • 평점이 모두 3점 이상이다.
  • 긍정 댓글의 내용을 살펴보면 영화 자체, 스토리에 대한 칭찬이 주를 이룬다.

 

- 부정 댓글

 

  • 부정 댓글의 내용을 살펴보면 "캐스팅만 좋았다 ~" ,"형편없는 영화" 등의 내용이 있다.
  • 감정사전을 수정했음에도 불구하고 평점과 감정 점수가 상이한 문제는 해결되지 않았다.                                    ( 평점은 4점으로 높은 점수를 갖지만 감정 점수는 0 , 1 점이다. )

 

 

11.  감정 범주별 빈도와 비율 구하기

- score를 기준으로 댓글의 감정 분류

# 감정 사전 수정 전
spider_score <- spider_score  %>%
  mutate(sentiment = ifelse(score >=  1, "pos",
                     ifelse(score <= -1, "neg", "neu")))

# 감정 사전 수정 후
new_spider_score <- new_spider_score  %>%
  mutate(sentiment = ifelse(score >=  1, "pos",
                     ifelse(score <= -1, "neg", "neu")))

 

- 감정 범주별 빈도와 비율 

# 원본 감정 사전 활용
spider_frequency <- spider_score %>%
  count(sentiment) %>%           # 감정 범주별 빈도
  mutate(ratio = n/sum(n)*100)   # 감정 범주별 비율


# 수정한 감정 사전 활용
new_spider_frequency <- new_spider_score %>%
  count(sentiment) %>%           # 감정 범주별 빈도
  mutate(ratio = n/sum(n)*100)   # 감정 범주별 비율

 

 

 

  • 원본 감정 사전을 사용했을 때 부정 단어의 비율은  12 % , 긍정 단어는 88 % 였다. 중립 단어는 존재하지 않는다.
  • "marvel , like, hero" 긍정 단어를 중립단어로 바꾼 결과 ,                                                                         수정한 감정 사전은 부정 단어의 비율이 14 % 로 증가하였고, 긍정 단어는 82 % 로 감소하였다.                         또한 중립 단어가 추가되었음을 알 수 있다.

 

12. 자주 사용된 감정 단어 살펴보기 - 수정된 감정사전 사용 

- 감정 분류하기

수정된 감정사전을 이용하여 구한 polarity 를 0 보다 크면 긍정단어, 작으면 부정단어, 그 외에는 중립단어로 분류한다.

 

# 감정 분류하기
new_spider_afinn <- new_spider_comment %>%
  mutate(sentiment = ifelse(polarity > 0, "pos",
                     ifelse(polarity < 0, "neg", "neu")))

 

- 감정별 상위 10개 단어 추출

중립 단어를 제외하고 각 감정별 상위 10개 단어를 추출한다.

 

# 긍정 / 부정 단어 중 자주 사용된 단어 10개씩 추출 
new_top10 <- new_spider_afinn %>%
  filter(sentiment != "neu") %>%  # 중립 단어는 제외
  count(sentiment, word) %>%
  group_by(sentiment) %>%
  slice_max(n, n = 10, with_ties =F ) # slice_max() : 값이 큰 상위 n개의 행을 추출해 내림차순으로 정렬하는 함수

new_top10

 

 

- 막대그래프 그리기

ggplot(new_top10, aes(x = reorder(word, n), 
                            y = n, 
                            fill = sentiment)) +
  geom_col() +
  coord_flip() +
  geom_text(aes(label = n), hjust = -0.3) +
  facet_wrap(~ sentiment, scales = "free") +
  scale_y_continuous(expand = expansion(mult = c(0.05, 0.15))) +  
  labs(x = NULL) +
  ggtitle("감정 범주별 최다 빈도 단어 - 수정 후") +  # 그래프 제목 지정
  theme(text = element_text(family = "nanumgothic"),
         plot.title = element_text(hjust=0.5))  # 제목 위치를 가운데로 지정

 

 

  • 감정 사전 수정 결과, like, marvel  이 최빈 긍정 단어에서 제거 되었다.
  • 부정 단어의 경우 bad, sad, disappointed ... 등 영화를 보고 난 후 느낀 감정의 단어들의 빈도가 높다.
  • 긍정 단어 또한 good, amazing, love, great 등 긍정의 감정이 담긴 단어들로 나타났다.

 

 

13. 감정점수와 평점의 상관관계

그렇다면 감정점수와 평점은 어떠한 관계가 있을까?

우선 누적막대 그래프 시각화를 통해 감정점수와 평점의 관계를 알아보자.

 

- 댓글별 감정 비율을 시각화한 누적 막대그래프 비교 : 감정 점수

 

   new_spider_frequency 에는  x 축을 구성할 변수가 없기 때문에 임의의 값을 넣은 더미변수를 생성한다.

 

# 감정 점수의 비율 누적 막대 그래프

new_spider_frequency$dummy <- 0   # dummy 변수 생성 

ggplot(new_spider_frequency, aes(x = dummy, y = ratio, fill = sentiment)) +
  geom_col() +
  geom_text(aes(label = paste0(round(ratio, 1), "%")),
            position = position_stack(vjust = 0.5)) +
  theme(axis.title.x = element_blank(),     # x축 이름 삭제
        axis.text.x = element_blank(),     # x축 값 삭제
        axis.ticks.x = element_blank())  +    # x축 눈금 삭제
  ggtitle("댓글별 감정 비율") +   # 그래프 제목 추가
  theme(plot.title = element_text(hjust = 0.5))  # 제목 위치 가운데 지정

 

- 댓글별 감정 비율을 시각화한 누적 막대그래프 비교 : 평점

 

평점이 4점 이상일 때는 "긍정" , 2점 이하일 때는 "부정" , 그 외에는 "중립"으로 분류하였다.

 

그 후 sentiment 별 빈도와 비율을 구한다.

 

spider_score2 <- spider_score %>%
  mutate(sentiment = ifelse(rating >= 4, "pos",
                            ifelse(rating <= 2, "neg", "neu")))

spider_frequency2 <- spider_score2 %>%
  count(sentiment) %>%
  mutate(ratio = n / sum(n) * 100)

 

 

# 평점의 비율 누적 막대 그래프
spider_frequency2$dummy <- 0   # 더미 변수 생성

ggplot(spider_frequency2, aes(x = dummy, y = ratio, fill = sentiment)) +
  geom_col() +
  geom_text(aes(label = paste0(round(ratio, 1), "%")),
            position = position_stack(vjust = 0.5)) +
  theme(axis.title.x = element_blank(),     # x축 이름 삭제
        axis.text.x = element_blank(),     # x축 값 삭제
        axis.ticks.x = element_blank())  +   # x축 눈금 삭제
  ggtitle("평점별 감정 비율") +   # 그래프 제목 추가
  theme(plot.title = element_text(hjust = 0.5))  # 제목 위치 가운데 지정

 

 

 

 

  • 감정사전을 이용한 감정분류 , 평점을 이용한 감정분류 모두 긍정의 감정 비율이 가장 높으며                            이후 부정, 중립의 순으로 감정 비율을 차지한다.
  •  댓글별 감정 비율을 보면 긍정의 감정이 압도적으로 높은 반면                                                                   평점별 감정 비율은 긍정과 부정의 감정비율 차이가 크지 않다.
  • 이는 댓글을 이용하여 부여한 감정점수와 평점 사이 어느 정도 상관관계가 있긴 하지만                                   그러한 상관관계가 크진 않다고 예상할 수 있다.

 

 

누적 막대 그래프를 통해 감정점수와 평점 사이의 상관관계를 예측해보았으니

상관분석을 통해 더 정확하게 두 사이의 관계를 파악해보자.

 

 

- 상관분석

cor.test(new_spider_score$score, new_spider_score$rating)   # 상관분석

 

 

  • 상관분석 결과 , p-value 가 0.0003 로 유의수준 5% 하에서 귀무가설을 기각한다.
    즉, 상관계수가 0 이 아니라고 할 수 있고 감정 점수와 평점이 유의미한 상관관계를 가진다고 할 수 있다.

  • 상관계수는 0.49 로 위에서 예측한 바와 같이 상관계수가 크게 나오진 않았지만,                                             어느 정도 양의 상관관계를 가짐을 알 수 있다.

 

  • 감정점수가 높으면 평점도 어느정도 높다고 할 수 있다.

 

 

14. 그 외의 감정 사전들

 

앞에서 잠깐 언급하였던  bing, nrc 감정사전에 대해 알아보자.

bing

bing 사전은 단어의 속성을 긍정/ 부정으로 분류하는 사전이다.

 

앞에서 afinn 감정 사전을 기준으로 감정점수를 부여한 spider_comment 데이터에

bing 사전을 이용하여 긍정/부정 감정을 분류해보았다.

 

이 때 bing 사전에서 긍/부정으로 판단할 수 없는 단어는 중립단어로 분류하였다.

 

- bing 사전을 이용한 감정 분류

# 감정 분류하기- bing 이용

spider_comment2 <- spider_comment %>%
 left_join(bing, by = "word") %>%
 mutate(spider_bing = ifelse(is.na(sentiment), "neu", sentiment))  %>%
 select(-sentiment)   # 기존의 sentiment 값 삭제

 

- 최빈 단어 막대 그래프

# 막대그래프 만들기

top10_spider_bing <- spider_comment2 %>%
  filter(spider_bing != "neu") %>%
  count(spider_bing, word) %>%
  group_by(spider_bing) %>%
  slice_max(n, n = 10, with_ties = F)


ggplot(top10_spider_bing, aes(x = reorder(word, n),
                         y = n,
                         fill = spider_bing)) +
  geom_col() +
  coord_flip() +
  geom_text(aes(label = n), hjust = -0.3) +
  facet_wrap(~spider_bing, scales = "free") +
  scale_y_continuous(expand = expansion(mult = c(0.05, 0.15))) +
  labs(x = NULL) +
  theme(text = element_text(family = "nanumgothic"))

 

  •  afinn 사전을 이용하여 감정을 분류했을 때와 다른 결과가 나왔다.
  • 이는 사전마다 감정을 분류하는 기준이 다르기 때문에 발생하는 문제 인 것 같다.

 

  • 부정 감정으로 분류된 단어를 보면 다소 관계 없는 단어들이 최빈 단어로 선정된 것을 볼 수 있다.  또한 afinn 사전을 활용하여 감정을 분류했을 때도 발생하였던 "like , marvel" 단어가 긍정으로 분류되는 문제가 발생한다.

 

  • bing 사전은 결합하였을 때 단어의 속성을 부정/ 긍정으로만 분류하기 때문에 단어의 감정점수를 알기 어렵다.

 

 

 Q. 두 사전을 같이 사용하지 않는 이유

앞에서 afinn 사전을 이용하여 감정 분석을 할 때 감정 분류를 bing 으로 하면 안되나 ? 라는 의문점이 들 수도 있다.

 

여기에 대한 답은 afinn 사전을 이용하여 부여된 감정점수 polarity 와

   bing 사전을 이용하여 분류된 감정 spider_bing 을 살펴보면 알 수 있다.

 

- polarity 와 spider_bing 의 관계

# polarity 가 0 점이 아닌데 bing 으로 했을 때 neu 인 언어

spider_comment2 %>%
  filter(polarity !=0  & spider_bing == "neu")  %>%
  select(word, polarity, spider_bing)

 

 

  • 다음과 같이 afinn 사전 상으로는 중립단어가 아닌데 bing 사전을 적용하면 중립 단어로 분류되는 문제가 생긴다.
  • 즉 , 두 사전 간 같은 단어의 감정을 분류하는데 차이가 있다.
  • 따라서 한가지 감정 사전을 사용하여 감정분석을 하는 것이 좋다.

 

 

nrc

nrc 사전은 단어의 속성을 긍정, 부정 뿐만 아니라 여러가지 범주로 분류한 사전이다.

 

 

  • 다음과 같이 여러개의 감정이 존재한다.

 

- nrc 사전을 이용한 감정 분류

# 감정 분류하기- nrc 이용

spider_comment3 <- spider_comment %>%
 left_join(nrc, by = "word") %>%
 mutate(spider_nrc = ifelse(is.na(sentiment), "neu", sentiment))  %>%
 select(-sentiment)   # 기존의 sentiment 값 삭제

 

- 최빈 단어 막대 그래프

# 막대그래프 만들기

top10_spider_nrc <- spider_comment3 %>%
  filter(spider_nrc != "neu") %>%
  count(spider_nrc, word) %>%
  group_by(spider_nrc) %>%
  slice_max(n, n = 10, with_ties = F)


ggplot(top10_spider_nrc, aes(x = reorder(word, n),
                         y = n,
                         fill = spider_nrc)) +
  geom_col() +
  coord_flip() +
  geom_text(aes(label = n), hjust = -0.3) +
  facet_wrap(~spider_nrc, scales = "free") +
  scale_y_continuous(expand = expansion(mult = c(0.05, 0.15))) +
  labs(x = NULL) +
  theme(text = element_text(family = "nanumgothic"))

 

 

  • 위 막대 그래프와 같이 nrc 사전을 사용하여 감정을 분류하면 같은 단어가 여러번 분류되는 문제가 생긴다.
  • 즉, 같은 단어라도 여러가지 감정을 가진다.

 

# nrc 사전의 문제점
nrc  %>%
filter(word %in% "marvel")

 

 

  • 이를 in 연산자를 통해 확인해본 결과 , marvel 이라는 단어는 positive 라는 감정도 되고 surprise 라는 감정도 된다.

 

  • 따라서 감정 점수를 부여할 수 있는 afinn 사전과 같이 사용한다면 같은 단어가 여러번 분류되는 문제점이 있기 때문에 한 가지 감정사전을 사용하여 감정분석을 수행하는 것이 바람직하다.

 

 

+ 추가 분석사항

1. 평점별로 어떠한 단어를 많이 사용하는지 알아보기

2. 이를 반영하여 감정사전을 수정해보기