저번 포스팅에서는 Sentiment Analysis(SA)의 방법 중 하나인 knowledge based technique에 대해서 살펴봤습니다.
이번에는 Statistical methods을 통해서 감성 분석을 해보겠습니다.
- Naive Bayes classifier
나이브 베이즈 분류기를 다루기 전에 먼저 TF-IDF(Term Frequency – Inverse Document Frequency)와 같은 벡터 공간 모형에 대해서 알아보겠습니다.

TF_IDF는 이와 같은 형태로 문장에서 해당하는 단어의 등장 여부에 따라서 다음과 같이 나타냅니다. 이 때 단어의 등장여부를 T/F로 보는 boolean model, 단어의 등장 횟수로 보는 frequency model 둘다 가능합니다.
여기서 자주 등장하는 단어를 통해 하나하나의 dimension을 생성하는 것이 벡터 공간 모형의 기초적인 형태입니다. 그리고 이러한 feature에 기계학습 알고리즘을 통해서 train을 진행합니다.
| import os files=os.listdir('[저장된 폴더 주소]/aclImdb/train/pos') from nltk.corpus import stopwords stopWords=set(stopwords.words('english')) from nltk.corpus import sentiwordnet as swn words = [] for file in files: with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/pos/{}'.format(file),'r',encoding = 'utf-8') as f: review = nltk.word_tokenize(f.read()) for token in review: if token not in stopWords: words.append(token) print(len(words)) |
먼저 긍정 학습 데이터에서의 모든 토큰을 words라는 리스트에 저장합니다. 이때 Stopwords도 함께 제거해줍니다
| files=os.listdir('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/neg') for file in files: with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/neg/{}'.format(file),'r',encoding = 'utf-8') as f: review = nltk.word_tokenize(f.read()) for token in review: if token not in stopWords: words.append(token) print(len(words)) |
같은 방식으로 부정 학습 데이터에서 Stopwords 를 제거하고 words리스트에 붙여 넣습니다.
| words=nltk.FreqDist(words) word_features=list(words.keys())[:3000] |
words리스트를 이용해서 3000 dimension의 word feature를 생성합니다.
| def find_features(doc): words = set(doc) features = {} for w in word_features: features[w] = (w in words) return features |
word feature를 통해서 분석할 데이터의 feature를 생성하는 함수도 만들어 줍니다.
이제 첫번째 리뷰 데이터의 문장들을 이용해서 feature를 생성해보겠습니다.
| with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/neg/{}'.format(files[0]),'r',encoding='utf-8') as f: review = nltk.word_tokenize(f.read()) find_features(review) |

첫 번째 리뷰 데이터의 feature생성 결과입니다.
| feature_sets =[] files = os.listdir('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/pos')[:1000] for file in files: with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/pos/{}'.format(file),'r',encoding='utf-8') as f: review = nltk.word_tokenize(f.read()) feature_sets.append((find_features(review),'pos')) |
같은 방법으로 1000개의 리뷰 데이터에 대해 feature set을 생성해서 리스트에 저장합니다.
본격적으로 나이브 베이즈 분류기(Naive Bayes Classifier)를 통해 감성분석을 시작하겠습니다. 분류기는 nltk에 내장되어 있기 때문에 따로 설치할 것은 없습니다.
가장 먼저 2000개의 영화 리뷰를 긍/부정으로 분류해보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | feature_sets =[] files = os.listdir('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/pos')[:1000] for file in files: with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/pos/{}'.format(file),'r',encoding='utf-8') as f: review = nltk.word_tokenize(f.read()) feature_sets.append((find_features(review),'pos')) files = os.listdir('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/neg')[:1000] for file in files: with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/train/neg/{}'.format(file),'r',encoding='utf-8') as f: review = nltk.word_tokenize(f.read()) feature_sets.append((find_features(review),'neg')) files = os.listdir('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/test/pos')[:1000] for file in files: with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/test/pos/{}'.format(file),'r',encoding='utf-8') as f: review = nltk.word_tokenize(f.read()) feature_sets.append((find_features(review),'pos')) files = os.listdir('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/test/neg')[:1000] for file in files: with open('C:/Users/lifebloom/Desktop/udsl/text_mining/aclImdb/test/neg/{}'.format(file),'r',encoding='utf-8') as f: review = nltk.word_tokenize(f.read()) feature_sets.append((find_features(review),'neg')) |
training,test set을 위한 feature set을 만들어준다음
| training_set = feature_sets[:2000] test_set = feature_sets[2000:] |
순서대로 앞의 2000 set은 training 나머지는 test set으로 분류합니다
| clf = nltk.NaiveBayesClassifier.train(training_set) |
그 다음 nltk의 나이브 베이즈 분류기를 실행해주면 됩니다. 전처리에 비해 정말 간단합니다…
| result = nltk.classify.accuracy(clf, test_set)*100 |
분류기를 training한 뒤에는 test set에서 얼마나 잘 작동하는지 살펴봅니다.
| print('Accuracy of the Naive Bayes classification model: ', result) |
82%의 분류율이 나옵니다. 샘플 데이터라서 그런지 생각보다 높은 분류율을 보여주는 것 같네요. 같은 방법으로 전체 데이터(train 25000, test 25000)으로 한 결과 82.756의 정확도로 2000개의 train 데이터의 경우와 비교해 크게 향상되진 않았습니다.
다음 포스팅에서는 나머지 감성 분석 방법들에 대해 알아보겠습니다.