1. 도입

감성 분석을 통해서 텍스트에서 감성/의견/감정/기분을 파악할 수 있다.

소셜 미디어, 여론조사, 온라인 리뷰, 피드백 등 다양한 분야에서 사용한다.

 

감정분석이라고 해서 거창하게 보이지만 실제로는 긍정/부정을 분류하는 단순한 이진 분류 문제라고 할 수 있다.

 

1)지도학습 - 일반적인 텍스트 분류 문제와 같다.

2)비지도학습 - 감정 어휘 사전라고 불리는 'lexicon'을 사용한다. 용어와 문맥에 대한 다양한 정보를 가지고 있다.

 

2. 지도학습

유명한 IMDB 영화 사이트의 영화평을 이용하자.

영화평의 감정을 분석해서 긍정인지 부정인지를 예측하는 것이 목적이다.

 

bag of words meets bags of popcorn이라는 kaggle dataset이다.

 

labeledTrainData.tsv를 사용한다.

 

간단하게 먼저 요약하자면, 데이터를 받는다. 데이터를 살펴보니 <br />가 너무 많고, 쓸모없는 문자나 특수문자가 있어서 이를 제외하는 전처리를 해준다. 원래 sklearn의 countvectorizer이나 tfidfvectorizer에도 전처리 과정이있지만 클렌징이나 숫자를 제외하는 것은 없다. replace, apply함수를 이용해서 정규표현식으로 전처리를 해주고 label dataframe, feature dataframe으로 나눠서 train_test_split에 넣고 trainset, testset으로 나눠준다. 그리고 pipeline에 tfidfvectorizer, logistic regression을 넣고 학습을 시키면 된다! 검증은 accuracy_score과 roc_auc_score을 이용한다.

 

 

-> 근데 궁금해서

특수문자, 숫자만 지웠을 때는 0.8932가 나왔다.

<br /> 없애는 전처리만 했을 때는 0.8935가 나왔다.

<br /> 없애는 전처리와 특수문자, 숫자를 지웠을 때는 0.8936이 나왔다.

아무것도 하지 않았을때는 0.8947로 제일 높게나왔다. --> 뭐야?? 사실상 거의 차이가 없다. 이유는 모르겠음..

 

즉, 

 

 

 

 

3. 비지도학습

lexicon을 기반으로 학습한다. 감성 지수가 표현된 감성 어휘 사전이다. 감성 지수는 단어의 위치, 주변 단어, 문맥, pos 등을 참고해서 결정된다.

 

nltk에서 구현한 감성 사전을 이용할 수 있다. wordnet을 이용하면 다양한 상황에서 같은 단어라도 다르게 사용되는 어휘의 semantic 정보를 제공하며 이를 위해 각각의 품사로 구성된 개별 단어를 synset 개념을 이용해 표현합니다.

 

그런데 nltk에서 구현한 wordnet은 생각보다 성능이 좋지 않다는 단점이 있어서 다른 패키지의 감성 사전을 사용하기도 합니다.

그래서 nltk의 sentiwordnet을 먼저 사용해보고 잘 쓰이는 vader을 사용해보도록 하겠습니다.

 

1) wordnet synset과 sentiwordnet sentisynset 클래스의 이해

감성 사전이 어떠한 방식으로 구성되어 있고 시맨틱 기반의 사전 구축 방식을 자세히 이해할 수 있도록 먼저 배워봅시다.

 

wordnet을 이용하기 위해서는 nltk의 모든 패키지를 받아야한다.

wordnet을 이용해서 synsets()을 사용하면 synset 객체 여러 개가 반환된다. 서로 다른 semantic을 가지는 객체다. 그리고 synset은 속성으로 part of speech(품사), definition, lemma 등을 가지고 있다. 의미를 구분해주기 위한 요소이다.

 

추가로 wordnet은 path_similarity를 통해 어휘 간의 유사도를 구할 수 있다.

 

sentiwordnet은 wordnet과 굉장히 유사한데, 감정 지수와 객관성 지수를 가지고 있다. 감정 지수는 긍정, 부정으로 나뉘고, 객관성 지수는 감성적이지 않으면 1이 된다. 나머지는 wordnet과 거의 똑같다고 볼 수 있다.

 

 

감성 지수가 0이라서 객관성 지수가 1이다.

 

 

2) sentiwordnet을 이용한 영화 감상평 감성 분석

이전에는 라벨이 주어졌지만 이번에는 라벨없이 학습을 시켜보는 시간입니다.

 

프로세스

1)문서를 문장으로 문장을 단어로 토큰화하고 품사태깅합니다.

2)품사태깅된 단어 기반으로 synset, senti_synset 객체를 생성합니다.

3)senti_synset에서 긍정/부정 지수를 구하고 합산해서 특정 임계치를 넘으면 긍정 평가, 그렇지 않을 때는 부정 평가로 결정합니다.

 

앞서 다운 받은 데이터셋을 활용합니다. review column에 swn_polarity를 적용하고 sentiment column과 비교하여 metric을 측정합니다.

 

 

3) vader을 이용한 감정분석

소셜 미디어 감성 분석 용도로 만들어진 룰 기반의 lexicon입니다. vader은 sentimentintensityanalyzer을 이용해 쉽게 감정 분석을 제공합니다. nltk의 서브 모듈로 제공돼서 nltk.download('all')로 다운을 받아야합니다. 그러면 polarity_score()메소드를 통해서 neg, pos, neu, compound 부정 긍정 중립 조합 점수를 알 수 있습니다. 이때 compound를 기준으로 threshold와 비교를 통해서 긍/부정으로 나눕니다!

 

그러면 review에 polarity_score을 통해서 긍/부정을 나누고 실제 sentiment 값과 비교하여 accuracy를 구할 수 있습니다.!

 

 

결론적으로, sentiwordnet보다 성능이 개선된 것을 확인할 수 있습니다! 정확도, 정밀도, 재현율이 모두 좋지만 지도학습보다는 성능이 안좋은 것을 확인할 수 있습니다.

 

 

총정리. 지난 시간에는 문서가 주어졌을 때 어떤 topic인지 구분하는 텍스트 분류를 실습했습니다. 이번 시간에는 문서의 감성을 분석하는 감성 분석에 대해 알아보았습니다. 감성 분석은 소셜 미디어의 반응, 여론 조사, 온라인 리뷰, 평점 등 다양한 분야에서 사용될 수 있습니다. 이번 실습에서는 영화 리뷰를 이용하여 긍정/부정 리뷰를 분류(감성 분석)하였습니다. 그리고 지도학습과 비지도학습을 모두 알아보았습니다. 지도학습에서는 데이터를 받아서 전처리를 하고 train_test_split을 이용해서 train, test로 나눴습니다. 그리고 pipeline을 이용해서 문서를 tfidf vectorizer을 하고 logistic regression에 넣어서 긍/부정을 분류하였습니다. 비지도학습에서는 lexicon라는 감성 어휘 사전을 이용하였습니다. 단어마다 품사, 위치, 주변 단어 등(synset)을 참고하여 semantic을 담고 있습니다. 그리고 또 긍/부정의 수치도 가지고 있습니다.

패키지로는 wordnet, sentiwordnet, vader, pattern이 있습니다. 실제 성능은 vader이 좋지만 lexicon이 어떻게 구성되어있는 지를 알아보기 위해서 wordnet에서 synset, sentiwordnet에서 senti_synset을 이용하며 구조를 살펴보았습니다. wordnet의 synset은 단어의 semanitc을 담고 있다면 sentiwordnet에는 semantic과 더불어 sentiment의 정도(pos_score, neg_score, obj_score)도 함께 들어있습니다. synset은 semantic을 담고 있어서 단어의 유사성도 알 수 있습니다. 구조를 살펴보고 실제로 sentiwordnet을 이용해서 실습을 해봤습니다. swn_polarity함수를 만들어서 문서를 문장으로 문장을 단어로 토큰화하고 품사를 태깅하고 lemmatizer을 이용해서 원형을 추출하고 그걸 senti_synset에 대입해서 긍/부정 값을 더하고 문서의 모든 문장에 대해서 같은 과정을 통해 긍/부정을 구하고 임계치를 기준으로 긍/부정으로 분류하였습니다. 그리고 정답값과 비교하여 정확도를 비교하였습니다. 요약하면 문서의 단어를 감성 사전에서 찾아서 단어의 긍/부정을 추합해서 문서를 긍/부정으로 분류했다고 보면 될 것 같습니다. 마지막으로 vaderdm의sentimentintensityanalyzer의 polarity_score함수를 사용해서 compound를 통해 문서의 긍/부정을 구분했습니다.

 

 

과제1. synset을 제외하고 swn_polarity 함수작성해서 시험해보기

 

과제2. precision_score, recall_score, roc_auc_score에 대해서 정리하기

 

과제3. pattern 패키지를 통해서 감성 분석 시도하기

 

 

+ Recent posts