Python NLTK와 WordCloud로 문학 작품 시각화하기

텍스트 데이터 분석은 자연어 처리(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()

이 코드는 다음과 같은 추가 기능을 포함합니다:

  1. 불용어(stopwords) 제거: ‘the’, ‘a’, ‘is’와 같은 일반적인 단어들을 제외하고, 문맥에 의미 있는 단어들만 표시합니다.
  2. 배경색 설정: background_color='white'로 배경을 하얀색으로 설정합니다.
  3. 최대 단어 수 제한: max_words=200으로 워드 클라우드에 표시할 단어 수를 제한합니다.
  4. 워드 클라우드 크기 조정: width=800, height=400으로 워드 클라우드의 크기를 조정합니다.
  5. 색상 맵 변경: 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()

이 코드는 다음과 같은 전처리 과정을 포함합니다:

  1. 토큰화(Tokenization): 텍스트를 개별 단어로 분리합니다.
  2. 소문자 변환: 모든 텍스트를 소문자로 변환하여 대소문자 구분 없이 처리합니다.
  3. 불용어 및 구두점 제거: 자주 사용되는 일반적인 단어들과 구두점을 제거합니다.
  4. 표제어 추출(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는 단순한 워드 클라우드 생성을 넘어 복잡한 텍스트 분석을 위한 다양한 기능을 제공합니다. 이를 활용하여 텍스트 데이터의 숨겨진 패턴과 인사이트를 발견해보세요!

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다