영화 리뷰를 가지고 하나하나 리뷰를 명사로 추출하고 추출한 명사로 워드 클라우드를 만들었습니다
이번에는 영화 리뷰를 가지고 좀 더 리뷰를 쓸모 있게(?) 하기 위해
하나하나 리뷰를 감성사전으로 감성을 분석해 보겠습니다
데이터 준비
먼저 감성 분석을 하기 위해서는 데이터가 필요합니다
데이터는 이전에 영화리뷰를 크롤링한 데이터로 하겠습니다
데이터가 준비되면 데이터와 비교할 사전이 필요합니다
깃허브에 있는 군산대 감성사전을 쓰겠습니다
https://github.com/park1200656/KnuSentiLex
군산대 감성사전 다운로드
들어가게 되면 이런 화면이 뜨는데 저는 neg_pol_word.txt 와 pos_pol_word.txt 파일을 사용합니다
다운로드 받고 보기 좋게 neg_pol_word.txt 는 negative.txt 로 pos_pol_word.txt 는 positive.txt로 바꿉니다
그리고 파일을 열어서 출처와 단어수, 극성이 적혀있는것을 다 지워주고 저장합니다
위에 처럼 확인할 수 있습니다
군산대 감성사전에서는 미리 점수가 매겨져있는 사전도 있는데 그사전을 사용하려고 했지만
R에서 계속 오류가 나서 긍부정어를 다 1점으로 하고
각 문장에 대하여 긍정에서 부정을 빼는 방식으로 정했습니다
예를 들어
재미있지만 마지막 결말이 별로네요
이런 문장에서 재미있다는 긍정어 하나와 별로라는 부정어 하나가 있는데
1(재미) - 1(별로) = 0이 나와 중립이 되는 방식입니다
패키지 준비
감성분석에 필요한 패키지는
1
2 |
library(plyr)
library(stringr) |
cs |
두개가 있습니다
시작하기 전에는 항상 파일을 저장하고 가져올 폴더를 지정합니다
1 |
setwd("C://Temp") |
cs |
긍부정어 단어 파일을 setwd로 지정한 폴더에 넣어준다
감성분석
1
2
3
4
5 |
positive <- readLines("positive.txt", encoding = "UTF-8")
positive=positive[-1]
negative <- readLines("negative.txt", encoding = "UTF-8")
negative=negative[-1] |
cs |
다음으로 감성사전에서 가져온 positive.txt 와 negative.txt 를 변수에 불러옵니다
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 |
sentimental = function(sentences, positive, negative){
scores = laply(sentences, function(sentence, positive, negative) {
sentence = gsub('[[:punct:]]', '', sentence) # 문장부호 제거
sentence = gsub('[[:cntrl:]]', '', sentence) # 특수문자 제거
sentence = gsub('\\d+', '', sentence) # 숫자 제거
word.list = str_split(sentence, '\\s+') # 공백 기준으로 단어 생성 -> \\s+ : 공백 정규식, +(1개 이상)
words = unlist(word.list) # unlist() : list를 vector 객체로 구조변경
pos.matches = match(words, positive) # words의 단어를 positive에서 matching
neg.matches = match(words, negative)
pos.matches = !is.na(pos.matches) # NA 제거, 위치(숫자)만 추출
neg.matches = !is.na(neg.matches)
score = sum(pos.matches) - sum(neg.matches) # 긍정 - 부정
return(score)
}, positive, negative)
scores.df = data.frame(score=scores, text=sentences)
return(scores.df)
}
|
cs |
어디서 가져온지 모르겠지만 구글링하다가 찾게 되었습니다
긍,부정어를 비교하는 함수인데 만든 사람 리스펙...
1
2
3
4
5 |
result=sentimental(txt, positive, negative)
result$color[result$score >=1] = "blue"
result$color[result$score ==0] = "green"
result$color[result$score < 0] = "red" |
cs |
저 함수를 이용해서 result 변수에 함수에 의해 분석한 결과가 들어갑니다
긍정은 1점이상 0점은 중립 부정은 0점 아래로 설정하기 위해
color에 긍정을 blue 중립은 green 부정은 red로 설정
> table(result$color)
blue green red
547 1693 161
1
2
3 |
result$remark[result$score >=1] = "긍정"
result$remark[result$score ==0] = "중립"
result$remark[result$score < 0] = "부정" |
cs |
이어서 1점이상은 긍정으로 0점은 중립으로 0점 아래는 부정이라고 설정합니다
1
2
3
4 |
sentiment_result= table(result$remark)
pie(sentiment_result, main="감성분석 결과",
col=c("blue","red","green"), radius=0.8) |
cs |
pie(sentiment_result, main="감성분석 결과",
> sentiment_result
긍정 부정 중립
547 161 1693
이렇게 결과가 나온다 하지만 이런 식으로 할 경우
5개의 영화리뷰를 감성분석한 결과 중립이 대다수를 차지합니다
아무래도 긍, 부정어에서 점수가 다 1점이라서 중립이 많이 생기는것 같습니다
중립을 빼고 볼때 영화 평점이 높을수록 긍정이 많이 있다.
하지만 예외도 있다 평점이 좋은 영화지만 슬픈분위기의 영화는 긍정과 부정이 거의 동일하게 나온다
'프로그래밍 > R ' 카테고리의 다른 글
R KoNLP로 명사 추출, 명사로 워드클라우드 만들어보기 (2) | 2019.02.12 |
---|---|
R 기본으로 크롤러 만들기 (14) | 2019.01.24 |
R [1]. 설치하기 (0) | 2019.01.09 |