반응형

책, 영화등과 같은 매체를 보고나면 그에 대한 피드백이 발생합니다. 어떤 사람들은 주위 지인들에게 평가를 공유하기도 하고 어떤 사람들은 어떤 인상을 받았는지 인터넷 상에 글을 남깁니다. 이번 포스팅에서는 이러한 리뷰들의 단어에 긍/부정을 평가하여 그 리뷰, 더나아가 그 영화에 대한 감정이 긍정적인지 부정적인지 살펴보려고 합니다.

Sentiment Analysis(SA) 에는 크게 세 가지 방식이 있습니다.

  • knowledge-based techniques
  • statistical methods
  • hybrid approaches

먼저 knowledge-based technique은 단어들의 감정의 정도를 평가하는 사전을 만들고 이를 활용해서 단어 또는 글의 감정 상태를 평가하는 방법입니다.

예를 들어 SentiWordnet은 단어 마다의 긍/부정 척도를 더한 대표적인 db로 Python의 nltk에 포함되어 있습니다.

 

다음으로 statistical method는 SVM(support vector machine)이나 ‘bag of words’등 다양한 ML 방법론을 활용해서 단어의 감정을 분류하는 방법입니다. Python의 nltk 패키지에 naive bayes classifier도 통계적 방법 중 하나입니다.

 

마지막으로 hybrid approaches의 경우 두 방법을 적절하게 혼합하여 활용하는 방법입니다.

 

SA에서 가장 힘든 부분 중 하나는 비정형인 자연어의 노이즈들이 많다는 점입니다. 인간의 경우 다양한 문맥에 따라서 흐름을 쉽게 파악할 수 있지만 기계는 어렵습니다.

예를 들어 ‘내가 치킨을 싫어하는 것은 아니야.’ 라는 문장을 보았을 때 사람들은 이 문장이 postive 또는  neutral 하다고 쉽게 판단하지만 긍/부정 단어에 점수를 매기는 knowledge-based technique에서는 negative 문장으로 해석될 수 있습니다. 이처럼 이중 부정문을 다루거나 비속어, 은유, 비유 또는 풍자 등과 같은 skill을 학습하기 힘들기 때문에 현재까지는 한계점이 뚜렸하다고 생각합니다.

 

네이버 평점 9점대에 빛나는 바로 그 영화! – sarcastic review의 대표적인 사례

 

이제 본격적으로 샘플 데이터를 활용해서 SA를 해보겠습니다.

http://ai.stanford.edu/~amaas/data/sentiment/

에서 데이터셋을 받습니다. 이 데이터는 IMDb라는 미국 영화 사이트의 리뷰를 50,000개 수집하여 리뷰마다 각각 긍/부정 분류로 나눈 데이터 셋입니다.

os 패키지는 operating system의 약자로 운영체제에서 쓰는 여러 기능들을 python에서도 쓸수 있게 해주는 패키지입니다.

먼저 긍정 리뷰중 하나를 review에 담았습니다.

 

제대로 리뷰가 담긴것을 확인하시면 for문을 이용해서 전체 긍정 리뷰를 pos_train_list에 저장합니다.

 

train positive 리뷰를 모두 저장했다면 이제 knowledge-based techniques 중 하나인 SentiWordNet에 대해 알아보겠습니다.

[SentiSynset(‘hate.n.01’), SentiSynset(‘hate.v.01’)]

 

sentiwordnet을 쓰기 위해 nltk 패키지를 import하고 ‘hate’라는 단어를 불러왔습니다. filter object 타입을 list로 바꾸면 n, v로 각각 명사 동사의 유의어가 나온것을 볼 수 있습니다.

0.0

0.75

hate라는 동사의 긍/부정 스코어를 확인하면 각각 0, 0.75점 입니다.

 

단어마다 여러 유의어가 존재하는 경우가 있습니다. 그래서 편의를 위해 특정 단어의 모든 유의어의 긍/부정 스코어를 각각 평균한 것으로 쓰기 위해 함수를 정의합니다.

(0.625, 0.03125)

love의 동사 유의어 점수 평균은 0.625이다.

 

2.5/4=0.625이므로 잘 동작하는 것을 알 수 있습니다.

 

원리를 그대로 사용해서 for문을 이용하면 문장에서의 긍/부정 지수도 쉽게 구할 수 있습니다.

 

이제 본격적으로 아까 다운받은 영화 리뷰 자료에서 postive train 리뷰 10가지와 negative train 리뷰 10가지를 불러와 SA를 해보겠습니다.

긍정적 리뷰와 부정적 리뷰를 순서대로 10개씩 불러왔기 때문에 actual에는 1(긍정)을 10번 반복하고 0(부정)을 10번 반복했습니다. 그 다음 과정은 앞과 마찬가지로 리뷰를 10개씩 불러와서 tokenize를 하고 pos_tag를 붙여서 리스트로 만들어주는 작업입니다. 합산된 긍/부정 스코어를 if문을 통해 대소비교를 하는데, 긍정 수치가 높으면 1을 반환하고 그렇지 않다면 0을 predicted에 반환합니다.

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1]
Number of correct instance: 12
Number of incorrect instance: 8

코드를 실행하면 다음과 같은 결과가 출력됩니다. 60%의 확률로 긍/부정 리뷰를 맞추는 성능을 보이고 있습니다.

 

다음 포스팅에서는 statistical methods중 하나인 Naive Bayes를 통한 감성 분석에 대해 알아보겠습니다.

반응형

+ Recent posts