Python으로 감정 분석 시작하기

감정 분석이란 매우 인기 있는 텍스트 분석법 중 하나입니다. 감정 분석으로 다양한 영역에서 사용자들이 어떻게 느끼는지 한눈에 파악할 수 있으며, 이는 고객 서비스, 시장/제품 조사 및 경쟁사 분석 등과 같은 분야에 유용하게 활용할 수 있습니다.
다른 자연어 처리(NLP) 분야와 마찬가지로 감정 분석도 복잡해질 수 있습니다. 다행히도 Python에는 이러한 NLP 분야에 더욱 쉽게 접근할 수 있도록 도와주는 탁월한 패키지와 도구가 있습니다.
이번 블로그 글에서는 Python으로 감정 분석을 하는 데 쓸 수 있는 인기 패키지와 그 작동 방식을 살펴보고 최신 기법을 활용하여 고유한 감정 분석 모델을 트레이닝하는 방법을 알아보겠습니다. 그리고 이러한 패키지로 더 쉽고 빠르게 작업할 수 있도록 도와주는 PyCharm 기능도 함께 살펴보겠습니다.
감정 분석이란?
감정 분석은 텍스트 조각을 분석하여 감정적 어조를 파악하는 것을 말합니다. 이 정의에서 알 수 있듯이 감정 분석은 매우 광범위한 분야로서 자연어 처리 분야의 다양한 방법론을 사용합니다.
‘감정적 어조’를 정의하는 방법에는 여러 가지가 있습니다. 가장 일반적으로 사용되는 방법은 텍스트에서 표현되는 감정이 얼마나 긍정적인지, 부정적인지 나타내는 감정가(valence, 감정의 긍정 또는 부정적 정도) 또는 양극성(polarity, 긍정 및 부정의 구별)을 판별하는 것입니다. 또한 감정적 어조는 일반적으로 텍스트가 긍정 또는 부정으로 구분되는 텍스트 분류 문제로 간주됩니다.
다음의 Amazon 제품 리뷰를 예시로 살펴보겠습니다.

고객이 확실히 만족하지 못하고 있으므로, 감정 분석 기술은 이 리뷰를 부정적인 것으로 분류할 것입니다.
훨씬 만족하고 있는 고객과 비교해 보겠습니다.

이번에는 감정 분석이 이 리뷰를 긍정적인 것으로 분류합니다.
여러 종류의 감정 분석
텍스트에서 감정 정보를 추출하는 방법에는 여러 가지가 있습니다. 그 중에서 중요한 방법 몇 가지를 검토해 보겠습니다.
감정을 정의하는 방법
먼저, 감정 분석은 여러 가지 방법으로 감정 또는 감성을 정의합니다.
바이너리: 이 방식에서는 문서의 감정가가 SST-2 데이터세트에서처럼 긍정 또는 부정의 두 가지로 분류됩니다. 이와 관련된 감정가 분류에서는 중립 클래스(텍스트에 주제에 대한 감정이 표현되지 않음)나 충돌 클래스(텍스트에 주제에 관한 긍정적인 감정과 부정적인 감정이 모두 표현됨)를 추가합니다.
일부 감정 분석기는 관련 측정치를 활용하여 텍스트를 주관적 또는 객관적으로 분류하기도 합니다.
세분화: 이 용어는 감정 분석을 하는 여러 가지 방법을 의미하지만 이 글에서는 긍정적이거나 부정적인 감정가를 리커트 척도로 세분화하는 방법을 말합니다. 이 방식 중에서 잘 알려진 예시는 강한 긍정, 긍정, 중립, 부정과 강한 부정으로 구성된 5단계 리커트 척도를 사용하는 SST-5 데이터세트입니다.
지속적: 텍스트의 감정가는 지속적으로 측정될 수도 있습니다. 여기서 점수는 글쓴이의 감정이 어느 정도 긍정 또는 부정적이었는지를 나타냅니다. 예를 들어 VADER 감정 분석기는 텍스트에 -1점(강한 부정)에서 1점(강한 긍정) 사이의 점수를 부여하며, 0점은 중립적인 감정을 의미합니다.
감정 기반: 감정 탐지 또는 감정 식별이라고도 알려진 이 방식은 텍스트에서 표현된 구체적인 감정을 탐지합니다. 두 가지 방식으로 시도해 볼 수 있습니다. 분류적 감정 탐지 방법은 텍스트에 표현된 감정을 여러 가지 구분되는 감정으로 분류하며, 일반적으로 분노, 혐오, 두려움, 기쁨, 슬픔과 놀람의 감정을 포함하는 에크먼 모델을 기반으로 합니다. 이러한 유형의 감정 탐지에 사용할 수 있는 데이터세트가 다수 있습니다. 차원적 감정 탐지는 감정 분석에서 사용되는 빈도가 다소 낮으며, 텍스트에서 세 가지 감정 요소인 양극성, 흥분(감정의 흥분도)과 통제력(감정 표현의 억제력)을 측정합니다.
분석 기준
텍스트를 분석할 때 여러 수준을 고려할 수 있습니다. 이를 더 정확히 이해하기 위해 커피 머신의 리뷰를 살펴보겠습니다.

문서 수준: 가장 일반적인 분석 기준으로 전체 텍스트에서 하나의 감정이 반환됩니다. 문서 수준의 분석은 트윗과 같이 매우 짧은 텍스트에는 적합하지만, 복합적인 감정이 표현된 경우 오해의 여지가 있는 답이 나올 수 있습니다. 예를 들어 전체 문서에서 이 리뷰에 대해 감정 분석을 수행하면, 같은 커피 머신에 대해 두 가지의 상충하는 감정이 포함되어 있으므로 중립 또는 충돌로 분류될 가능성이 높습니다.
문장 수준: 각 문장의 감정을 각각 예측하는 방식입니다. 커피 머신 리뷰의 경우 문장 수준의 분석에서는 리뷰 작성자가 제품의 어떤 부분에는 긍정적으로 느꼈고 그 외의 부분은 부정적으로 느꼈다고 나올 것입니다. 그러나 이 분석은 리뷰 작성자가 커피 머신의 어떤 부분을 좋아했고 어떤 부분을 싫어했는지 말해주지 않습니다.
측면 기반: 이러한 방식의 감정 분석은 텍스트를 심층적으로 분석하여 특정 측면에 대해서 사용자가 어떤 감정을 느꼈는지 분석합니다. 커피 머신 리뷰에서는 리뷰 작성자가 외관과 소음, 총 두 가지의 요소를 언급했습니다. 이러한 요소를 추출하여 사용자가 구체적으로 무엇을 좋아하고 싫어했는지 더 자세히 파악할 수 있습니다. 리뷰 작성자는 커피 머신의 외관에 관해서는 긍정적인 감정을 느꼈으나 소음으로 인해 부정적인 감정을 느꼈습니다.
다른 NLP 기술과 감정 분석의 연계
의도 기반: 마지막 감정 분석 기법으로서 표현된 감정과 텍스트의 주제를 기반으로 두 가지 방식으로 텍스트가 분류됩니다. 예를 들어 통신 회사에 서비스가 자주 중단된다는 불만 티켓이 접수된 경우 이 텍스트의 의도 또는 주제는 서비스 신뢰도로, 감정은 부정으로 분류할 수 있습니다. 측면 기반 감정 분석과 마찬가지로 이러한 분석을 활용하면 고객이 전반적으로 만족하는지 또는 불만을 느끼는지 회사가 더욱 자세히 파악할 수 있습니다.
감정 분석의 활용
지금쯤이면 감정 분석이 활용될 수 있는 사례가 이미 떠오르실 수도 있습니다. 기본적으로 텍스트 피드백이나 주제에 관한 의견을 받을 수 있는 곳이면 어디든 감정 분석이 활용될 수 있습니다. 조직이나 개인이 감정 분석을 사용하여 소셜 미디어를 모니터링하고 브랜드, 정부 단체 또는 주제에 관해서 사람들이 어떻게 느끼는지 파악할 수 있습니다.
고객 피드백 분석을 활용하면 피드백이나 티켓에 드러난 감정을 알아낼 수 있습니다. 제품 리뷰를 분석하면 고객이 회사의 제품에 얼마나 만족 또는 불만족하는지 알 수 있습니다. 마지막으로 감정 분석은 시장 분석과 경쟁사 분석에도 매우 중요한 요소이며, 이러한 분석에서 최근에 뜨는 유행, 기능 및 경쟁사에 관해서 사람들이 어떻게 느끼는지 파악하면 회사의 전략을 세울 때 도움이 됩니다.
감정 분석의 작동 방식
일반적으로 감정 분석은 단어(또는 더 정교한 모델에서는 텍스트의 전체적 어조)와 감정을 연결합니다. 가장 일반적인 감정 분석 방식은 다음의 세 가지 방법 중 하나에 해당합니다.
사전 기반 방법
이 방법은 광범위한 단어에 감정 점수가 매겨진 사전에 의존합니다. 여러 원칙에 따라 점수가 조합되어 텍스트의 전체적인 감정을 파악합니다. 이러한 방법은 매우 빠른 편이며 세분화되고 지속적인 감정 점수를 얻을 수 있다는 장점이 있습니다. 그러나 사전을 수작업으로 만들어야 되기 때문에 많은 시간과 비용이 소요될 수 있습니다.
머신러닝 모델
이러한 방식은 머신러닝 모델(일반적으로 Naive Bayes 분류기)을 영화 리뷰처럼 텍스트와 감정 라벨이 포함된 데이터세트를 바탕으로 트레이닝합니다. 일반적으로 이 모델은 텍스트를 긍정, 부정이나 때로는 중립으로 분류합니다. 이러한 모델도 속도가 매우 빠르지만 일반적으로 입력된 데이터에서 단어 간의 관계를 고려하지 않으며, 한정어나 부정 표현이 포함된 복잡한 텍스트는 제대로 처리하지 못할 수 있습니다.
대형 언어 모델
이 방법은 앞서 언급된 머신러닝 기반의 분류기를 트레이닝하는 데 사용되는 것과 동일한 데이터세트로 사전에 트레이닝된 트랜스포머 기반의 대형 언어 모델을 세밀하게 조정합니다. 이렇듯 정교한 모델은 텍스트에 포함된 단어 간의 복잡한 관계를 모델링할 수 있지만 다른 두 가지 방법보다는 느린 편입니다.
Python을 이용한 감정 분석
Python의 에코시스템에는 NLP를 위한 패키지가 매우 많기 때문에 Python으로 감정 분석을 할 때는 선택지가 정말 다양합니다.
감정 분석에 사용되는 Python 패키지 중 가장 유명한 몇 가지를 검토해 보겠습니다.
감정 분석을 위한 최고의 Python 라이브러리
VADER
VADER(Valence Aware Dictionary and Sentiment Reasoner)는 인기 있는 사전 기반의 감정 분석기입니다. 강력한 NLTK 패키지에 포함되어 있는 이 분석기는 긍정, 중립, 부정과 복합으로 구성된 네 가지 감정 점수를 반환합니다. 긍정, 중립 및 부정 점수의 범위는 0~1이며, 긍정, 중립 또는 부정적 텍스트의 비율을 나타냅니다. 복합 점수는 -1(매우 부정적)에서 1(매우 긍정적)로 매겨지고 텍스트의 전체적인 감정가를 나타냅니다.
어떤 식으로 동작하는지 간단한 예시를 통해 살펴보겠습니다.
from nltk.sentiment.vader import SentimentIntensityAnalyzer import nltk
먼저 VADER 사전을 다운로드해야 합니다.
nltk.download('vader_lexicon')
그런 다음 VADER SentimentIntensityAnalyzer()
를 인스턴스화하고 polarity_scores()
메서드를 사용하여 감정 점수를 추출할 수 있습니다.
analyzer = SentimentIntensityAnalyzer() sentence = "I love PyCharm! It's my favorite Python IDE." sentiment_scores = analyzer.polarity_scores(sentence) print(sentiment_scores)
{'neg': 0.0, 'neu': 0.572, 'pos': 0.428, 'compound': 0.6696}
VADER가 이 텍스트의 전체적인 감정 점수를 0.67점으로 매기고, 콘텐츠를 긍정 43%, 중립 57%, 부정 0%로 분류했습니다.
VADER는 각 단어의 감정 점수를 사전에서 찾은 다음 뉘앙스를 담은 규칙 집합를 사용하여 이를 조합합니다. 예를 들어 한정어는 단어에 포함된 감정의 세기를 높이거나 줄일 수 있습니다. 따라서 단어 앞에 있는 ‘약간’과 같은 한정사는 감정의 세기를 낮추지만 ‘매우’는 높입니다.
VADER의 사전에는 ‘smh'(shaking my head: 절레절레)와 같은 약어와 이모지도 포함되어 있어서 소셜 미디어 텍스트에도 매우 적합합니다. VADER의 주요 한계는 영어 외의 언어는 지원하지 않는다는 점입니다. 하지만 vader-multi
와 같은 프로젝트를 대안으로 사용할 수 있습니다.
NLTK
또한, NLTK를 활용하면 scikit-learn
의 분류기를 사용하여 머신러닝 기반의 고유한 감정 분류기를 트레이닝할 수 있습니다.
텍스트를 처리하여 이러한 모델에 입력하는 방법은 많습니다. 하지만 가장 간단한 방식은 텍스트에 있는 단어를 기반으로 하는 단어 가방(bag-of-words)이라는 텍스트 모델링입니다. 단어 가방 모델링 중에서 가장 직관적인 유형은 바이너리 벡터화입니다. 여기에서 각 단어는 특징으로 간주되며, 각 특징의 값은 0 또는 1(텍스트 내 각 단어의 유무를 의미)입니다.
텍스트 데이터와 NLP 작업을 처음 접하는 사용자 중에서 텍스트가 머신러닝 모델의 입력으로 변환되는 방법을 자세히 알고 싶으신 경우, 제가 이 주제에 관한 논의한 영상에 간단히 소개해 드렸습니다.
NLTK 문서에서도 텍스트 조각이 주관적인지 아니면 객관적인지 예측하도록 Naive Bayes 분류기를 트레이닝하는 예시를 확인할 수 있습니다. 이 예시에서는 추가적인 부정 한정어가 규칙에 따라 일부 용어에 추가되어 있습니다. 이 규칙은 단어 또는 글자가 텍스트의 다른 곳에 표현된 감정을 부정하는 데 사용되었을 가능성을 나타냅니다. 이 주제에 대해서 자세히 알고 싶다면, Real Python에서 NLTK를 사용하여 고유한 분류기를 트레이닝하는 감정 분석 튜토리얼도 확인해 보세요.
Pattern과 TextBlob
Pattern 패키지는 감정 분석에 사용할 수 있는 사전 기반의 또 다른 방법을 제공합니다. SentiWordNet 사전이 사용되며, 이 사전에서는 WordNet에서 가져온 각 동의어 그룹(synset)에 긍정, 부정, 객관성 점수가 부여됩니다. 각 단어의 긍정 및 부정 점수는 여러 규칙에 따라 조합되어 최종 양극성 점수가 나옵니다. 이와 유사하게 각 단어의 객관성 점수도 조합되어 최종적인 주관성 점수가 나옵니다.
WordNet에는 품사 정보도 있기 때문에 단어 앞에 붙는 형용사 또는 부사가 단어의 감정을 수식하는지 여부를 규칙에 반영할 수 있습니다. 이 규칙 집합은 부정 표현, 느낌표, 이모지 등을 고려하며, 관용어나 비꼬기를 처리하기 위한 규칙도 일부 포함하고 있습니다.
그러나 독립실행형 라이브러리 형태의 Pattern은 Python 3.6하고만 호환됩니다. 그렇기 때문에 Pattern을 사용하는 가장 일반적인 방법은 TextBlob을 이용하는 것입니다. TextBlob 감정 분석기는 기본적으로 자체적으로 구현된 Pattern 라이브러리를 사용하여 감정 점수를 생성합니다.
어떻게 실행되는지 지금부터 살펴보겠습니다.
from textblob import TextBlob
보시는 것처럼 텍스트를 사용하여 TextBlob 메서드를 실행한 다음 sentiment
속성을 사용하여 감정을 추출할 수 있습니다.
pattern_blob = TextBlob("I love PyCharm! It's my favorite Python IDE.") sentiment = pattern_blob.sentiment print(f"Polarity: {sentiment.polarity}") print(f"Subjectivity: {sentiment.subjectivity}")
Polarity: 0.625 Subjectivity: 0.6
이 예시 문장에서 TextBlob의 Pattern은 극성 점수 0.625(VADER의 점수와 상대적으로 근접함)를, 주관성 점수 0.6을 부여하였습니다.
하지만 TextBlob으로 감정 점수를 얻는 두 번째 방법이 있습니다. 이 패키지에는 사전에 학습된 Naive Bayes 분류기가 포함되어 있습니다. 이 분류기는 텍스트가 긍정적인지 또는 부정적인지 라벨을 지정한 다음 텍스트가 긍정적이거나 부정적일 확률을 알려줍니다.
이 방법을 사용하려면 먼저 NLTK로부터 이 모델을 트레이닝하는 데 사용되는 punkt
모듈과 movie-reviews
데이터세트를 다운로드해야 합니다.
import nltk nltk.download('movie_reviews') nltk.download('punkt') from textblob import TextBlob from textblob.sentiments import NaiveBayesAnalyzer
다시 한 번 TextBlob
에 텍스트를 실행해야 하지만 이번에는 analyzer=NaiveBayesAnalyzer()
인수를 추가합니다. 그런 다음 이전과 마찬가지로 감정 속성을 사용하여 감정 점수를 추출합니다.
nb_blob = TextBlob("I love PyCharm! It's my favorite Python IDE.", analyzer=NaiveBayesAnalyzer()) sentiment = nb_blob.sentiment print(sentiment)
Sentiment(classification='pos', p_pos=0.5851800554016624, p_neg=0.4148199445983381)
이번에는 pos
(긍정) 라벨이 출력되며, 모델이 이 텍스트가 긍정적일 확률은 59%, 부정적일 확률은 41%라고 예측합니다.
spaCy
또 다른 옵션으로 spaCy를 사용하여 감정 분석을 할 수도 있습니다. spaCy는 Python으로 작성된 또 다른 인기 NLP 패키지이며 텍스트 처리에 사용할 수 있는 다양한 옵션을 갖고 있습니다.
첫 번째 방법은 spacytextblob 플러그인을 통해 TextBlob 감정 분석기를 spaCy 파이프라인의 일부로 사용하는 것입니다. 이렇게 하기 전에 먼저 spacy
와 spacytextblob
을 모두 설치한 다음 적절한 언어 모델을 다운로드해야 합니다.
import spacy import spacy.cli from spacytextblob.spacytextblob import SpacyTextBlob spacy.cli.download("en_core_web_sm")
그런 다음 언어 모델을 로드하고 spacytextblob
을 텍스트 처리 파이프라인에 추가합니다. TextBlob은 spaCy의 pipe
메서드를 통해 사용될 수 있습니다. 이는 품사 태그 분류, 기본형 변환, 고유명사 인식 등과 같은 전처리 단계를 포함한 더욱 복잡한 텍스트 처리 파이프라인에도 포함될 수 있다는 의미입니다. 전처리는 텍스트를 정규화 및 강화하여 다운스트림 모델이 텍스트 입력으로부터 최대한 많은 정보를 추출할 수 있도록 도와줍니다.
nlp = spacy.load('en_core_web_sm') nlp.add_pipe('spacytextblob')
지금은 전처리 없이 샘플 문장만 분석해 보겠습니다.
doc = nlp("I love PyCharm! It's my favorite Python IDE.") print('Polarity: ', doc._.polarity) print('Subjectivity: ', doc._.subjectivity)
Polarity: 0.625 Subjectivity: 0.6
위에서 TextBlob을 사용했을 때와 같은 결과가 나옵니다.
spaCy에서 감정 분석을 하는 두 번째 방법은 TextCategorizer 클래스를 사용해서 고유한 모델을 트레이닝하는 것입니다. 이렇게 하면 감정 분석 트레이닝 세트를 사용하여 spaCY로 생성된 다양한 모델을 트레이닝할 수 있습니다. 이 방식도 spaCy 파이프라인의 일부로 사용될 수 있기 때문에 모델을 트레이닝하기 전에 다양한 옵션으로 텍스트를 전처리할 수 있습니다.
마지막으로 spacy-llm을 통해 대형 언어 모델을 사용하여 감정 분석을 할 수도 있습니다. 이 방법에서는 OpenAI, Anthropic, Cohere과 Google의 다양한 자체 대형 언어 모델(LLM)을 사용하여 텍스트의 감정 분석을 수행할 수 있습니다.
이는 지금까지 논의한 다른 방법과는 조금 다르게 작동합니다. 모델을 트레이닝하는 대신 GPT-4와 같은 범용 모델을 사용하여 텍스트의 감정을 예측할 수 있습니다. 이때 제로샷 러닝(예시 없이 프롬프트만 모델에 전달) 또는 퓨샷 러닝(프롬프트와 다수의 예시를 모델에 전달) 방식을 활용할 수 있습니다.
Transformers
마지막으로 논의할 마지막 Python 감정 분석 패키지는 Hugging Face의 Transformers입니다.
Hugging Face는 무료로 사용할 수 있는 모든 주요 오픈 소스 LLM을 호스팅하며(컴퓨터 비전 및 오디오 모델 포함), 이러한 모델을 트레이닝, 배포 및 공유할 수 있는 플랫폼을 제공합니다. Transformers 패키지에는 Hugging Face에 호스팅된 LLM으로 작업할 때 사용할 수 있는 기능(감정 분석 포함)이 다양하게 있습니다.
감정 분석 결과의 이해
지금까지 Python으로 감정 분석을 하는 방법을 모두 살펴보았습니다. 그러면 ‘내 데이터에는 이걸 어떻게 적용할 수 있을까?’라는 궁금증이 생길 수 있습니다.
이를 이해하기 위해 PyCharm을 사용하여 VADER와 TextBlob이라는 두 가지 패키지를 비교해 보겠습니다. 두 패키지는 다수의 감정 점수를 제공하여 데이터와 관련된 다양한 시각을 제공합니다. 두 패키지를 사용하여 Amazon 리뷰 데이터세트를 분석해 보겠습니다.
PyCharm Professional은 코드 완성, 검사 및 디버그, 풍부한 데이터베이스, Jupyter, Git, Conda 등을 기본적으로 지원하는 데이터 과학을 위한 강력한 Python IDE입니다. 또한, DataFrame Column Statistics(열 통계) 및 Chart View(차트 뷰)는 물론 LLM을 더 빠르고 쉽게 사용할 수 있도록 도와주는 Hugging Face 통합 등과 같은 매우 유용한 기능도 사용할 수 있습니다. 이 블로그 글에서는 DataFrame을 처리할 때 사용할 수 있는 PyCharm의 고급 기능을 살펴보겠습니다. 이러한 기능을 통해 두 패키지에서 감정 점수가 어떻게 분포되는지 간략하게 확인할 수 있습니다.
고유한 감정 분석 프로젝트를 시작할 준비가 되셨다면, PyCharm 3개월 무료 구독을 이용해 보세요. 아래의 링크를 클릭한 다음 프로모션 코드 PCSA24를 입력하세요. 그러면 이메일로 활성화 코드를 받으실 수 있습니다.
먼저 데이터를 로드해야 합니다. Datasets 패키지의 load_dataset()
메서드를 사용하면 Hugging Face Hub의 데이터를 다운로드할 수 있습니다.
from datasets import load_dataset amazon = load_dataset("fancyzhx/amazon_polarity")
PyCharm 내에서 데이터세트의 이름을 마우스로 가리키면 Hugging Face 데이터세트 카드를 바로 볼 수 있기 때문에 IDE를 나가지 않고도 Hugging Face 애셋 정보를 편리하게 가져올 수 있습니다.

여기에서 데이터세트의 내용을 볼 수 있습니다.
amazon
DatasetDict({ train: Dataset({ features: ['label', 'title', 'content'], num_rows: 3600000 }) test: Dataset({ features: ['label', 'title', 'content'], num_rows: 400000 }) })
트레이닝용 데이터세트에는 360만 건의 관측치가 있으며, 테스트 데이터세트에는 40만 건이 있습니다. 이 튜토리얼에서는 트레이닝용 데이터세트를 사용하겠습니다.
이제 VADER SentimentIntensityAnalyzer
및 TextBlob 메서드를 로드합니다.
from nltk.sentiment.vader import SentimentIntensityAnalyzer import nltk nltk.download("vader_lexicon") analyzer = SentimentIntensityAnalyzer()
from textblob import TextBlob
트레이닝용 데이터세트에 관측치가 너무 많아 안정적으로 시각화할 수 없으므로 전체 리뷰어의 전체적인 감정을 대표하는 무작위 샘플 1,000개를 추출하겠습니다.
from random import sample sample_reviews = sample(amazon["train"]["content"], 1000)
이제 리뷰의 VADER 점수와 TextBlob 점수를 각각 가져오겠습니다. 각 리뷰 텍스트를 반복 처리하며 감정 분석기를 실행한 다음 점수를 전용 목록에 연결하겠습니다.
vader_neg = [] vader_neu = [] vader_pos = [] vader_compound = [] textblob_polarity = [] textblob_subjectivity = [] for review in sample_reviews: vader_sent = analyzer.polarity_scores(review) vader_neg += [vader_sent["neg"]] vader_neu += [vader_sent["neu"]] vader_pos += [vader_sent["pos"]] vader_compound += [vader_sent["compound"]] textblob_sent = TextBlob(review).sentiment textblob_polarity += [textblob_sent.polarity] textblob_subjectivity += [textblob_sent.subjectivity]
그런 다음 이러한 목록을 pandas DataFrame에 별도의 열로 각각 추가하겠습니다.
import pandas as pd sent_scores = pd.DataFrame({ "vader_neg": vader_neg, "vader_neu": vader_neu, "vader_pos": vader_pos, "vader_compound": vader_compound, "textblob_polarity": textblob_polarity, "textblob_subjectivity": textblob_subjectivity })
이제는 결과를 살펴볼 차례입니다.
일반적으로 이 시점부터 실험적 데이터 분석을 위한 다양한 코드가 작성됩니다. 이는 pandas의 describe
메서드를 사용하여 열의 요약 통계를 얻거나 Matplotlib 또는 seaborn 코드를 작성하여 결과를 시각화하는 작업이 될 수 있습니다. 그런데 PyCharm에는 이 모든 작업의 속도를 높여주는 몇몇 기능이 있습니다.
그러면 DataFrame을 출력해 보겠습니다.
sent_scores
오른쪽 상단 모서리에 Show Column Statistics(열 통계 표시)라는 버튼이 보입니다. 이 버튼을 클릭하면 Compact(컴팩트)와 Detailed(상세)라는 두 가지 옵션이 표시됩니다. Detailed(상세)를 선택하겠습니다.

이제 요약 통계가 열 헤더의 일부로 표시됩니다! 통계를 보면 VADER 복합 점수의 평균은 0.4(중윗값 = 0.6)이고 TextBlob 양극성 점수의 평균은 0.2(중윗값 = 0.2)입니다.
이 결과를 보면 VADER는 평균적으로 TextBlob에 비해 같은 리뷰를 더 긍정적으로 평가하는 경향이 있습니다. 또한, 두 감정 분석기 모두 부정적 리뷰보다는 긍정적 리뷰가 더 많을 가능성이 높다고 합니다. 일부 시각화를 확인하면 더 자세히 확인할 수 있습니다.

DataFrame Chart View(차트 뷰)도 사용해 볼 만한 PyCharm 기능입니다. 이 기능의 버튼은 왼쪽 상단 모서리에 있습니다.

버튼을 클릭하면 차트 에디터로 전환됩니다. 여기서부터 DataFrame를 사용하여 바로 노코드 방식으로 시각화를 만들 수 있습니다.
VADER 복합 점수로 시작해 보겠습니다. 차트 생성을 시작하려면 오른쪽 상단 모서리의 Show Series Settings(계열 설정 표시)로 이동합니다.

X Axis(X 축)과Y Axis(Y 축)의 디폴트 값을 삭제합니다. X Axis(X축) 값을 vader_compound
로 바꾸고 Y Axis(Y축) 값은 vader_compound
로 바꿉니다. Y Axis(Y축) 필드의 변수 이름 옆에 있는 화살표를 클릭한 다음 count
를 선택합니다.
마지막으로 Series Settings(계열 설정)의 차트 아이콘에서 Histogram(히스토그램)을 선택합니다. 이제 VADER 복합 점수에 대한 두 가지 분포가 나온 것 같습니다. -0.8 부근에서 약간 높고 0.9 부근에서 훨씬 높이 올라갑니다. 이 높은 부분은 부정적인 리뷰와 긍정적인 리뷰의 구분을 나타내는 것일 확률이 높습니다. 긍정적인 리뷰가 부정적인 리뷰보다 훨씬 많습니다.

이제 똑같은 작업을 반복하여 TextBlob 양극성 점수의 분포를 나타내는 히스토그램을 생성해 보겠습니다.
반대로 TextBlob은 대부분의 리뷰를 중립적인 것으로 평가하고 소수의 리뷰만 강한 긍정 또는 부정으로 분류합니다. 두 감정 분석기에서 나온 점수에 편차가 있는지 파악하기 위해 VADER가 강하게 긍정적인 것으로 평가한 리뷰와 VADER는 강하게 부정적인 것으로 평가했지만 TextBlob은 중립으로 평가한 리뷰를 살펴보겠습니다.

VADER가 긍정적인 것으로 평가했지만 TextBlob은 중립으로 평가한 첫 번째 리뷰의 색인을 가져오겠습니다.
sent_scores[(sent_scores["vader_compound"] >= 0.8) & (sent_scores["textblob_polarity"].between(-0.1, 0.1))].index[0]
42
그런 다음 VADER가 부정적인 것으로 평가했지만 TextBlob은 중립으로 평가한 첫 번째 리뷰의 색인을 가져오겠습니다.
sent_scores[(sent_scores["vader_compound"] <= -0.8) & (sent_scores["textblob_polarity"].between(-0.1, 0.1))].index[0]
0
먼저 긍정적인 리뷰를 가져오겠습니다.
sample_reviews[42]
"I love carpet sweepers for a fast clean up and a way to conserve energy. The Ewbank Multi-Sweep is a solid, well built appliance. However, if you have pets, you will find that it takes more time cleaning the sweeper than it does to actually sweep the room. The Ewbank does pick up pet hair most effectively but emptying it is a bit awkward. You need to take a rag to clean out both dirt trays and then you need a small tooth comb to pull the hair out of the brushes and the wheels. To do a proper cleaning takes quite a bit of time. My old Bissell is easier to clean when it comes to pet hair and it does a great job. If you do not have pets, I would recommend this product because it is definitely well made and for small cleanups, it would suffice. For those who complain about appliances being made of plastic, unfortunately, these days, that's the norm. It's not great and plastic definitely does not hold up but, sadly, product quality is no longer a priority in business."
이 리뷰는 긍정과 부정이 섞여 있지만 전체적으로는 긍정적인 것 같습니다.
이제는 부정적인 리뷰를 살펴보겠습니다.
sample_reviews[0]
'The only redeeming feature of this Cuisinart 4-cup coffee maker is the sleek black and silver design. After that, it rapidly goes downhill. It is frustratingly difficult to pour water from the carafe into the chamber unless it's done extremely slow and with accurate positioning. Even then, water still tends to dribble out and create a mess. The lid, itself, is VERY poorly designed with it's molded, round "grip" to supposedly remove the lid from the carafe. The only way I can remove it is to insert a sharp pointed object into one of the front pouring holes and pry it off! I've also occasionally had a problem with the water not filtering down through the grounds, creating a coffee ground lake in the upper chamber and a mess below. I think the designer should go back to the drawing-board for this one.'
이 리뷰는 의심의 여지 없이 부정적입니다. 이 두 리뷰를 비교할 때는 VADER가 더 정확해 보이지만, 텍스트 내 긍정적 단어를 너무 우선하는 경향이 있습니다.
마지막으로 각 리뷰가 얼마나 객관적이거나 주관적인지 고려해 볼 수 있습니다. 이는 TextBlob의 주관성 점수로 히스토그램을 생성하여 확인할 수 있습니다.

흥미롭게도 리뷰 주관성의 분포가 상당히 좋습니다. 대부분의 리뷰가 객관적인 내용과 주관적인 내용을 모두 포함하고 있습니다. 몇몇 리뷰는 매우 주관적이거나(1에 가까움) 매우 객관적입니다(0에 가까움).
이러한 점수를 활용하면 데이터를 깔끔하게 분할할 수 있습니다. 사람들이 제품의 어떤 것을 좋아했는지, 싫어했는지에 관한 객관적인 요소를 알고 싶다면, 주관성 점수가 낮고 VADER 복합 점수가 각각 1과 -1에 가까운 리뷰를 검토해 보면 됩니다.
반면에 사람들이 제품에 어떻게 감정적으로 반응했는지 알고 싶다면 주관성 점수가 높으면서 VADER 복합 점수는 높거나 낮은 리뷰를 살펴보면 됩니다.
고려해야 할 사항
자연어 처리의 문제와 마찬가지로 감정 분석을 할 때도 유의해야 할 점이 여러 가지 있습니다.
고려 사항 중 매우 중요한 것 중 하나는 분석하고자 하는 텍스트의 언어입니다. 사전 기반의 방법은 대다수가 소수의 언어만 지원하기 때문에 이러한 사전이 지원되지 않는 언어로 작업하는 경우에는 세부 조정된 LLM을 사용하거나 고유한 모델을 트레이닝하는 등 다른 방식을 사용해야 할 수 있습니다.
텍스트 복잡도가 올라가면 사전 기반의 분석기나 단어 가방 기반의 모델이 정확하게 감정을 탐지하기가 어려울 수 있습니다. 비꼬기나 좀 더 미묘한 컨텍스트를 내포하는 어휘는 간단한 모델로는 탐지하기 어려우며, 이러한 텍스트의 감정을 정확하게 분류하지 못할 수 있습니다. LLM은 복잡한 텍스트를 처리할 수 있지만, 여러 모델로 실험할 필요가 있습니다.
마지막으로 감정 분석을 할 때는 머신러닝 문제를 다룰 때와 마찬가지로 똑같은 문제가 발생할 수 있습니다. 모델의 성능은 사용된 트레이닝 데이터에 따라 결정됩니다. 해결하고자 하는 문제의 분야에 맞는 고품질 트레이닝 및 테스트용 데이터세트를 확보할 수 없다면, 타깃 고객의 감정을 정확하게 예측하지 못할 수 있습니다.
또한, 목적이 비즈니스 문제 해결에 적합한지도 확인해야 합니다. 제품을 사용하는 고객이 ‘슬픈지’, ‘화가 났는지’ 또는 ‘질색하는지’ 알려주는 모델이 매력적일 수 있겠지만 제품 개선을 위해 결정을 내릴 때 도움이 되지 않는다면 문제가 해결되지 않는다는 의미입니다.
마무리
이 블로그 글에서는 Python 감정 분야라는 매력적인 영역을 깊이 탐구해 보고 다양하고 강력한 패키지를 활용하여 이 복잡한 분야에 더 쉽게 접근하는 방법을 보여 드렸습니다.
잠재적으로 감정 분석을 활용할 수 있는 분야와 여러 가지의 감정 평가, 텍스트에서 감정을 추출하는 주요 방법을 논의했습니다. 또한, 더 간단하고 빠르게 모델로 작업하고 결과를 해석할 수 있도록 도와주는 유용한 PyCharm 기능도 확인했습니다.
자연어 처리 분야는 현재 대형 언어 모델에 매우 집중되어 있지만, 사전 기반의 분석기나 Naive Bayes 분류기를 포함한 기존의 머신러닝 모델처럼 오래된 방식도 여전히 감정 분석에서 활용될 수 있습니다. 이러한 기술은 간단한 텍스트를 분석할 때나 속도, 예측 또는 배포 용이성이 우선 순위일 때 유용합니다. LLM은 더 복잡하고 뉘앙스가 있는 텍스트에 가장 적절합니다.
이제 기본을 익히셨으니 튜토리얼을 통해 LLM으로 감정 분석하는 방법을 배워 보실 수 있습니다. 이 단계별 가이드에서는 작업에 맞는 모델을 선택하는 방법, 감정 분석에 활용하는 방법과 자신에게 맞게 세밀하게 조정하는 방법을 찾을 수 있습니다.
이 블로그 글을 다 읽으신 후 자연어 처리나 머신러닝에 관해서 더 광범위하게 알고 싶으시다면 아래의 리소스를 참고하세요.
오늘 PyCharm으로 감정 분석을 시작하세요
고유한 감정 분석 프로젝트를 시작할 준비가 되셨다면, PyCharm 3개월 무료 구독을 이용해 보세요. 아래의 링크를 클릭한 다음 프로모션 코드 PCSA24를 입력하세요. 그러면 이메일로 활성화 코드를 받으실 수 있습니다.