텍스트 데이터 분석은 자연어 처리(NLP)의 기본적인 영역이며, Python은 이를 위한 강력한 도구들을 제공합니다. 특히 NLTK(Natural Language Toolkit)와 WordCloud 라이브러리를 활용하면 방대한 텍스트 데이터를 시각적으로 분석할 수 있습니다. 이번 포스팅에서는 고전 문학 작품을 워드 클라우드로 시각화하는 간단한 예제를 살펴보겠습니다.
필요한 라이브러리
먼저 필요한 라이브러리를 설치해야 합니다. 터미널 또는 명령 프롬프트에서 다음 명령어를 실행합니다:
pip install nltk
pip install wordcloud
pip install matplotlib
전체 코드
다음은 Jane Austen의 소설 ‘Emma’를 워드 클라우드로 시각화하는 간단한 Python 코드입니다:
import nltk
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# NLTK 데이터 다운로드
nltk.download("book", quiet=False)
# 구텐베르크 프로젝트의 텍스트 파일 목록 확인
nltk.corpus.gutenberg.fileids()
# 'Emma' 소설 텍스트 가져오기
emma_raw = nltk.corpus.gutenberg.raw("austen-emma.txt")
# 워드 클라우드 생성
cw = WordCloud(max_font_size=100).generate(emma_raw)
# 워드 클라우드 시각화
plt.imshow(cw, interpolation="mitchell")
plt.axis('off') # 축 제거
plt.show()
코드 분석
위 코드를 단계별로 살펴보겠습니다:
1. 라이브러리 임포트
import nltk
from wordcloud import WordCloud
import matplotlib.pyplot as plt
nltk
: 자연어 처리를 위한 대표적인 Python 라이브러리입니다.WordCloud
: 텍스트 데이터를 시각적인 워드 클라우드로 변환해주는 라이브러리입니다.matplotlib.pyplot
: 시각화를 위한 라이브러리입니다.
2. NLTK 데이터 다운로드
nltk.download("book", quiet=False)
NLTK는 다양한 텍스트 데이터와 언어 자원을 제공합니다. "book"
데이터셋에는 다양한 영문 문학 작품들이 포함되어 있습니다. quiet=False
파라미터를 통해 다운로드 과정을 상세히 볼 수 있습니다.
3. 사용 가능한 텍스트 파일 확인
nltk.corpus.gutenberg.fileids()
이 명령어는 구텐베르크 프로젝트에서 제공하는 텍스트 파일의 목록을 반환합니다. 다음과 같은 결과가 출력됩니다:
['austen-emma.txt', 'austen-persuasion.txt', 'austen-sense.txt', 'bible-kjv.txt', 'blake-poems.txt', 'bryant-stories.txt', 'burgess-busterbrown.txt', 'carroll-alice.txt', 'chesterton-ball.txt', 'chesterton-brown.txt', 'chesterton-thursday.txt', 'edgeworth-parents.txt', 'melville-moby_dick.txt', 'milton-paradise.txt', 'shakespeare-caesar.txt', 'shakespeare-hamlet.txt', 'shakespeare-macbeth.txt', 'whitman-leaves.txt']
4. 텍스트 데이터 가져오기
emma_raw = nltk.corpus.gutenberg.raw("austen-emma.txt")
Jane Austen의 소설 ‘Emma’의 전체 텍스트를 문자열로 가져옵니다. raw()
함수는 텍스트를 가공하지 않은 원본 상태로 반환합니다.
5. 워드 클라우드 생성
cw = WordCloud(max_font_size=100).generate(emma_raw)
WordCloud
클래스를 이용해 워드 클라우드 객체를 생성합니다. max_font_size=100
은 워드 클라우드에 표시되는 단어의 최대 글꼴 크기를 100으로 제한합니다. generate()
메소드는 입력된 텍스트를 분석하여 워드 클라우드 데이터를 생성합니다.
6. 워드 클라우드 시각화
plt.imshow(cw, interpolation="mitchell")
plt.axis('off') # 축 제거
plt.show()
matplotlib.pyplot
을 이용해 워드 클라우드를 시각화합니다. interpolation="mitchell"
은 이미지의 보간 방식을 지정하는 파라미터로, 워드 클라우드의 외관에 영향을 줍니다. plt.axis('off')
는 그래프의 축을 제거하여 워드 클라우드만 깔끔하게 표시합니다.
워드 클라우드 커스터마이징
기본 워드 클라우드에서 더 나아가, 다양한 옵션을 통해 커스터마이징할 수 있습니다:
# 불용어(stopwords) 제거 및 커스터마이징된 워드 클라우드
from nltk.corpus import stopwords
# 불용어 다운로드
nltk.download('stopwords')
# 영어 불용어 목록에 추가 단어 포함
stop_words = set(stopwords.words('english'))
stop_words.update(['Mr', 'Mrs', 'Miss', 'said', 'would', 'could'])
# 커스텀 워드 클라우드 생성
custom_wc = WordCloud(
background_color='white',
max_words=200,
max_font_size=100,
min_font_size=10,
width=800,
height=400,
stopwords=stop_words,
colormap='viridis'
).generate(emma_raw)
# 워드 클라우드 시각화
plt.figure(figsize=(10, 6))
plt.imshow(custom_wc, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud for Jane Austen\'s Emma (Customized)')
plt.tight_layout()
plt.show()
이 코드는 다음과 같은 추가 기능을 포함합니다:
- 불용어(stopwords) 제거: ‘the’, ‘a’, ‘is’와 같은 일반적인 단어들을 제외하고, 문맥에 의미 있는 단어들만 표시합니다.
- 배경색 설정:
background_color='white'
로 배경을 하얀색으로 설정합니다. - 최대 단어 수 제한:
max_words=200
으로 워드 클라우드에 표시할 단어 수를 제한합니다. - 워드 클라우드 크기 조정:
width=800, height=400
으로 워드 클라우드의 크기를 조정합니다. - 색상 맵 변경:
colormap='viridis'
로 워드 클라우드의 색상 테마를 변경합니다.
텍스트 전처리 과정 추가하기
더 정확한 워드 클라우드를 위해 텍스트 전처리 과정을 추가할 수 있습니다:
import nltk
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import string
# 필요한 NLTK 데이터 다운로드
nltk.download('punkt')
nltk.download('wordnet')
nltk.download('stopwords')
# 'Emma' 소설 텍스트 가져오기
emma_raw = nltk.corpus.gutenberg.raw("austen-emma.txt")
# 토큰화
tokens = word_tokenize(emma_raw.lower())
# 불용어 및 구두점 제거
stop_words = set(stopwords.words('english'))
stop_words.update(['mr', 'mrs', 'miss', 'said', 'would', 'could'])
tokens = [token for token in tokens if token not in stop_words and token not in string.punctuation]
# 표제어 추출(Lemmatization)
lemmatizer = WordNetLemmatizer()
lemmatized_tokens = [lemmatizer.lemmatize(token) for token in tokens]
# 텍스트로 다시 합치기
processed_text = ' '.join(lemmatized_tokens)
# 워드 클라우드 생성
wc = WordCloud(
background_color='white',
max_words=150,
max_font_size=100,
width=800,
height=400,
colormap='plasma'
).generate(processed_text)
# 워드 클라우드 시각화
plt.figure(figsize=(10, 6))
plt.imshow(wc, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud for Jane Austen\'s Emma (Processed Text)')
plt.tight_layout()
plt.show()
이 코드는 다음과 같은 전처리 과정을 포함합니다:
- 토큰화(Tokenization): 텍스트를 개별 단어로 분리합니다.
- 소문자 변환: 모든 텍스트를 소문자로 변환하여 대소문자 구분 없이 처리합니다.
- 불용어 및 구두점 제거: 자주 사용되는 일반적인 단어들과 구두점을 제거합니다.
- 표제어 추출(Lemmatization): 단어의 형태를 기본형으로 변환합니다(예: “running” → “run”).
다른 작품과 비교 분석
여러 작품의 워드 클라우드를 생성하여 작가의 어휘 사용 패턴을 비교해볼 수 있습니다:
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
# 전처리 함수 정의
def preprocess_text(text):
tokens = word_tokenize(text.lower())
tokens = [token for token in tokens if token not in stop_words and token not in string.punctuation]
lemmatized_tokens = [lemmatizer.lemmatize(token) for token in tokens]
return ' '.join(lemmatized_tokens)
# 여러 작품 가져오기
emma = nltk.corpus.gutenberg.raw("austen-emma.txt")
persuasion = nltk.corpus.gutenberg.raw("austen-persuasion.txt")
sense = nltk.corpus.gutenberg.raw("austen-sense.txt")
moby = nltk.corpus.gutenberg.raw("melville-moby_dick.txt")
# 텍스트 전처리
emma_processed = preprocess_text(emma)
persuasion_processed = preprocess_text(persuasion)
sense_processed = preprocess_text(sense)
moby_processed = preprocess_text(moby)
# 워드 클라우드 생성 함수
def create_wordcloud(text, title):
wc = WordCloud(
background_color='white',
max_words=100,
max_font_size=80,
width=400,
height=300,
colormap='viridis'
).generate(text)
return wc, title
# 워드 클라우드 생성
wc1, title1 = create_wordcloud(emma_processed, "Emma")
wc2, title2 = create_wordcloud(persuasion_processed, "Persuasion")
wc3, title3 = create_wordcloud(sense_processed, "Sense and Sensibility")
wc4, title4 = create_wordcloud(moby_processed, "Moby Dick")
# 2x2 그리드로 시각화
fig = plt.figure(figsize=(12, 10))
gs = GridSpec(2, 2, figure=fig)
ax1 = fig.add_subplot(gs[0, 0])
ax1.imshow(wc1, interpolation='bilinear')
ax1.set_title(title1)
ax1.axis('off')
ax2 = fig.add_subplot(gs[0, 1])
ax2.imshow(wc2, interpolation='bilinear')
ax2.set_title(title2)
ax2.axis('off')
ax3 = fig.add_subplot(gs[1, 0])
ax3.imshow(wc3, interpolation='bilinear')
ax3.set_title(title3)
ax3.axis('off')
ax4 = fig.add_subplot(gs[1, 1])
ax4.imshow(wc4, interpolation='bilinear')
ax4.set_title(title4)
ax4.axis('off')
plt.tight_layout()
plt.show()
이 코드는 Jane Austen의 세 작품과 Herman Melville의 ‘Moby Dick’을 비교 분석하여 각 작가의 어휘 사용 패턴의 차이를 시각적으로 보여줍니다.
결론
NLTK와 WordCloud 라이브러리를 활용하면 방대한 텍스트 데이터를 시각적으로 분석하는 강력한 도구를 손쉽게 구현할 수 있습니다. 이번 포스팅에서 살펴본 기본 예제를 시작점으로, 다양한 텍스트 분석 프로젝트에 활용해보세요.
가능한 확장 아이디어:
- 여러 작가의 작품을 비교 분석하여 작가별 특징적인 어휘 패턴 찾기
- 시대별 문학 작품을 분석하여 언어 사용의 변화 추적하기
- 특정 장르(예: 로맨스, 추리, SF)의 작품들을 분석하여 장르별 특징적인 어휘 패턴 찾기
NLTK와 WordCloud는 단순한 워드 클라우드 생성을 넘어 복잡한 텍스트 분석을 위한 다양한 기능을 제공합니다. 이를 활용하여 텍스트 데이터의 숨겨진 패턴과 인사이트를 발견해보세요!