用Python和NLP拆解《奥米勒斯城出走的人》:文本分析下的‘幸福’与‘苦难’关键词
当厄修拉·勒古恩笔下的奥米勒斯城在夏庆节的钟声中苏醒时,这座虚构城市的每个细节都暗藏着一个哲学命题:集体幸福是否能够建立在个体苦难之上?作为技术爱好者,我们不妨用Python和自然语言处理技术,从数据视角重新审视这个经典文本。本文将带你用代码量化文学中的情感张力,通过词频统计、情感分析和主题建模,揭示文字背后隐藏的叙事结构。
1. 环境准备与文本预处理
在开始分析之前,我们需要搭建一个适合文本分析的工作环境。推荐使用Jupyter Notebook进行交互式编程,它能够直观地展示分析过程和结果。
首先安装必要的Python库:
pip install nltk spacy pandas matplotlib seaborn textblob gensim接着下载NLTK的语料库和spaCy的语言模型:
import nltk nltk.download('punkt') nltk.download('stopwords') nltk.download('wordnet') nltk.download('averaged_perceptron_tagger') !python -m spacy download en_core_web_sm文本预处理是NLP分析的关键步骤。我们需要将原始文本转换为适合分析的格式:
import re from nltk.tokenize import word_tokenize from nltk.corpus import stopwords from nltk.stem import WordNetLemmatizer def preprocess_text(text): # 转换为小写并移除标点 text = re.sub(r'[^\w\s]', '', text.lower()) # 分词 tokens = word_tokenize(text) # 移除停用词 stop_words = set(stopwords.words('english')) tokens = [word for word in tokens if word not in stop_words] # 词形还原 lemmatizer = WordNetLemmatizer() tokens = [lemmatizer.lemmatize(word) for word in tokens] return tokens提示:预处理步骤可以根据具体分析需求调整,例如保留某些标点符号用于句子分割,或添加自定义停用词列表。
2. 词频分析与关键词对比
通过对比描述"庆典"和"地窖"场景的词汇分布,我们可以量化文本中的二元对立。首先将原文分割为两个部分:
# 示例代码 - 实际应根据原文结构调整 festival_text = "WITH a clamor of bells that set the swallows soaring..." # 庆典部分文本 cellar_text = "In a basement under one of the beautiful public buildings..." # 地窖部分文本 festival_tokens = preprocess_text(festival_text) cellar_tokens = preprocess_text(cellar_text)然后计算各部分的词频分布:
from collections import Counter def get_top_words(tokens, n=10): return Counter(tokens).most_common(n) festival_top = get_top_words(festival_tokens) cellar_top = get_top_words(cellar_tokens)将结果可视化可以更直观地展示差异:
import matplotlib.pyplot as plt def plot_word_frequencies(festival_data, cellar_data): fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6)) words, counts = zip(*festival_data) ax1.bar(words, counts, color='gold') ax1.set_title('Festival Scene Top Words') words, counts = zip(*cellar_data) ax2.bar(words, counts, color='grey') ax2.set_title('Cellar Scene Top Words') plt.tight_layout() plt.show() plot_word_frequencies(festival_top, cellar_top)典型分析结果可能显示:
| 庆典场景关键词 | 地窖场景关键词 |
|---|---|
| joy (0.12) | child (0.15) |
| music (0.09) | dark (0.11) |
| festival (0.08) | room (0.09) |
| summer (0.07) | door (0.08) |
| horse (0.06) | mop (0.07) |
这个对比清晰地展示了文本中刻意营造的二元对立:明亮与黑暗、欢乐与痛苦、自由与禁锢。
3. 情感分析量化文本情绪
情感分析可以帮助我们量化文本不同部分的情感倾向变化。使用TextBlob进行简单的情感分析:
from textblob import TextBlob def analyze_sentiment(text): analysis = TextBlob(text) return analysis.sentiment.polarity # 示例:分析段落情感 paragraphs = [...] # 将原文分割为段落 sentiment_scores = [analyze_sentiment(p) for p in paragraphs]更精细的情感分析可以使用VADER(Valence Aware Dictionary and sEntiment Reasoner):
from nltk.sentiment.vader import SentimentIntensityAnalyzer nltk.download('vader_lexicon') sia = SentimentIntensityAnalyzer() def detailed_sentiment(text): return sia.polarity_scores(text) # 示例使用 detailed_sentiment("The Festival of Summer came to the city Omelas")情感变化可视化:
import seaborn as sns def plot_sentiment(scores): plt.figure(figsize=(10, 6)) sns.lineplot(x=range(len(scores)), y=scores) plt.axhline(y=0, color='r', linestyle='--') plt.title('Sentiment Polarity Throughout the Text') plt.xlabel('Paragraph Index') plt.ylabel('Sentiment Score') plt.show() plot_sentiment(sentiment_scores)情感分析可能揭示的规律:
- 庆典场景的平均情感得分为+0.65(强烈正面)
- 地窖场景的平均情感得分为-0.82(强烈负面)
- 结尾出走部分的得分为-0.15(轻微负面但趋于中性)
这种情感轨迹反映了作者精心设计的叙事弧线:从极乐到极悲,最后达到一种矛盾的平衡。
4. 主题建模揭示潜在结构
主题建模可以帮助我们发现文本中隐含的叙事结构。使用LDA(Latent Dirichlet Allocation)算法:
from gensim import corpora from gensim.models import LdaModel def perform_lda(texts, num_topics=3): # 创建字典和语料库 dictionary = corpora.Dictionary(texts) corpus = [dictionary.doc2bow(text) for text in texts] # 训练LDA模型 lda_model = LdaModel(corpus=corpus, id2word=dictionary, num_topics=num_topics, random_state=42) return lda_model # 将文本分割为多个文档(如按场景或章节) documents = [...] processed_docs = [preprocess_text(doc) for doc in documents] model = perform_lda(processed_docs)可视化主题模型结果:
import pyLDAvis import pyLDAvis.gensim_models as gensimvis def visualize_topics(lda_model, corpus, dictionary): vis = gensimvis.prepare(lda_model, corpus, dictionary) return pyLDAvis.display(vis) visualize_topics(model, corpus, dictionary)典型的主题建模结果可能包括:
- 庆典与欢乐:包含"festival"、"music"、"joy"等词
- 苦难与道德困境:包含"child"、"misery"、"guilt"等词
- 出走与选择:包含"walk"、"leave"、"mountain"等词
这些主题恰好对应了故事的三个核心部分,验证了作者精心设计的叙事结构。
5. 高级分析:词向量与语义网络
更进一步,我们可以使用词向量分析词语之间的语义关系。spaCy提供了预训练的词向量模型:
import spacy nlp = spacy.load('en_core_web_md') def analyze_semantics(word1, word2): token1 = nlp(word1) token2 = nlp(word2) return token1.similarity(token2) # 示例:比较"joy"和"misery"的相似度 similarity = analyze_semantics("joy", "misery") print(f"Similarity between 'joy' and 'misery': {similarity:.2f}")构建语义网络可以揭示文本中的概念关联:
import networkx as nx def build_semantic_network(keywords): G = nx.Graph() # 添加节点 for word in keywords: G.add_node(word) # 计算相似度并添加边 for i, word1 in enumerate(keywords): for word2 in keywords[i+1:]: similarity = analyze_semantics(word1, word2) if similarity > 0.3: # 设置阈值 G.add_edge(word1, word2, weight=similarity) return G keywords = ['joy', 'festival', 'child', 'misery', 'walk', 'city'] network = build_semantic_network(keywords)可视化语义网络:
def plot_network(graph): pos = nx.spring_layout(graph) weights = [graph[u][v]['weight']*5 for u,v in graph.edges()] nx.draw(graph, pos, with_labels=True, width=weights) plt.show() plot_network(network)这种分析可能显示"joy"和"festival"之间有强关联,而"child"与"misery"形成另一个关联簇,但这两个簇之间几乎没有直接联系,反映了文本中刻意保持的二元对立。
6. 文本风格与作者指纹分析
最后,我们可以分析作者的写作风格特征。计算文本的词汇丰富度:
def lexical_diversity(text): tokens = preprocess_text(text) return len(set(tokens)) / len(tokens) diversity = lexical_diversity(full_text) print(f"Lexical diversity: {diversity:.2f}")分析句子长度分布:
from nltk.tokenize import sent_tokenize def sentence_length_analysis(text): sentences = sent_tokenize(text) lengths = [len(word_tokenize(sent)) for sent in sentences] return lengths lengths = sentence_length_analysis(full_text) plt.hist(lengths, bins=20) plt.title('Sentence Length Distribution') plt.show()关键风格特征可能包括:
- 词汇丰富度:0.72(显示作者使用词汇的多样性)
- 平均句子长度:23.4词(中等长度,适合哲学讨论)
- 长句与短句的交替使用(创造节奏感)
这些技术分析不仅帮助我们理解单个文本,还为比较不同作家的风格提供了量化基础。