在文学研究和创作领域,如何量化分析小说的情感变化和人物关系一直是个有趣的技术挑战。传统的人工分析方法效率低下且难以发现深层次模式。本文将介绍一个基于ResNet深度学习模型的小说分析系统,它通过创新的文本可视化方法,将小说转化为视觉表示,再利用计算机视觉技术进行模式识别。
这个系统的核心思路是:将非结构化的文本信息转化为结构化的视觉表示(情感矩阵和人物关系矩阵),然后利用预训练的ResNet模型提取特征并进行分类。这种方法巧妙避开了直接处理文本的复杂性,转而利用成熟的视觉模型来解决文学分析问题。
系统的工作流程分为三个主要阶段:
文本预处理与可视化阶段:
深度学习分析阶段:
可视化与报告生成:
选择ResNet作为核心模型主要基于以下考虑:
提示:在实际应用中,如果分析更复杂的小说模式,可以考虑使用更大的ResNet变体(如ResNet50),但需要权衡计算成本。
情感矩阵的生成过程如下:
python复制def create_sentiment_matrix(self, window_size=10):
chapters = self.segment_chapters()
sentiments = []
for chapter in chapters:
paragraphs = chapter.split('\n')
for para in paragraphs:
if para.strip():
sentiment = self.analyze_sentiment(para)
sentiments.append(sentiment)
# 滑动窗口平滑
if len(sentiments) > window_size:
smoothed = []
for i in range(len(sentiments) - window_size + 1):
window = sentiments[i:i+window_size]
smoothed.append(sum(window) / len(window))
sentiments = smoothed
# 填充为方阵
size = int(np.ceil(np.sqrt(len(sentiments))))
matrix = np.zeros((size, size))
for i, sent in enumerate(sentiments):
row = i // size
col = i % size
if row < size and col < size:
matrix[row, col] = sent
return matrix
人物关系分析的关键步骤:
python复制def create_character_relation_matrix(self, top_characters=8):
chapters = self.segment_chapters()
all_text = ' '.join(chapters[:5])
main_characters = self.extract_characters(all_text, top_characters)
for chapter in chapters[:10]:
paragraphs = chapter.split('\n')
for para in paragraphs:
for char1 in main_characters:
if char1 in para:
for char2 in main_characters:
if char1 != char2 and char2 in para:
self.character_relations[char1][char2] += 1
n = len(main_characters)
relation_matrix = np.zeros((n, n))
for i, char1 in enumerate(main_characters):
for j, char2 in enumerate(main_characters):
if i == j:
relation_matrix[i][j] = 1
else:
relation_matrix[i][j] = min(
self.character_relations[char1][char2] / 10, 1.0
)
return relation_matrix
我们对标准ResNet18做了以下修改:
python复制class NovelResNetAnalyzer:
def __init__(self, num_classes=3, use_pretrained=True):
self.model = models.resnet18(pretrained=use_pretrained)
# 修改最后一层
num_features = self.model.fc.in_features
self.model.fc = nn.Sequential(
nn.Linear(num_features, 128),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(128, num_classes)
)
# 图像预处理
self.transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
self.model = self.model.to(self.device)
将数值矩阵转换为模型可接受的图像格式:
python复制def matrix_to_image(self, matrix):
# 归一化
if matrix.max() > matrix.min():
normalized = (matrix - matrix.min()) / (matrix.max() - matrix.min()) * 255
else:
normalized = matrix * 255
normalized = normalized.astype(np.uint8)
# 应用colormap
cmap = cm.get_cmap('viridis')
colored = cmap(normalized / 255.0)
# 转换为PIL图像
image = Image.fromarray((colored[:, :, :3] * 255).astype(np.uint8))
return image
系统生成三种情感可视化图表:
python复制def visualize_sentiment_matrix(self, matrix, save_path='sentiment_matrix.png'):
plt.figure(figsize=(12, 4))
# 情感矩阵热图
plt.subplot(131)
plt.imshow(matrix, cmap='RdYlBu', aspect='auto')
plt.colorbar(label='情感值')
plt.title('情感矩阵热图')
# 情感曲线
plt.subplot(132)
sentiments_flat = matrix.flatten()
sentiments_flat = sentiments_flat[sentiments_flat != 0]
plt.plot(sentiments_flat[:100])
plt.axhline(y=0, color='r', linestyle='--', alpha=0.5)
plt.xlabel('文本段落')
plt.ylabel('情感值')
plt.title('情感变化曲线')
# 情感分布直方图
plt.subplot(133)
plt.hist(sentiments_flat, bins=20, alpha=0.7)
plt.xlabel('情感值')
plt.ylabel('频次')
plt.title('情感值分布')
plt.tight_layout()
plt.savefig(save_path, dpi=150)
plt.show()
人物关系分析提供两种视图:
python复制def visualize_character_network(self, matrix, characters, save_path='character_network.png'):
G = nx.Graph()
# 添加节点和边
for i, char in enumerate(characters):
G.add_node(char, size=matrix[i].sum()*10)
threshold = 0.1
for i, char1 in enumerate(characters):
for j, char2 in enumerate(characters[i+1:], i+1):
weight = matrix[i][j]
if weight > threshold:
G.add_edge(char1, char2, weight=weight*5)
# 绘制网络图
plt.figure(figsize=(10, 8))
pos = nx.spring_layout(G, k=2, iterations=50)
node_sizes = [G.nodes[node]['size'] for node in G.nodes()]
nx.draw_networkx_nodes(G, pos, node_size=node_sizes, node_color='lightblue')
edge_weights = [G[u][v]['weight'] for u, v in G.edges()]
nx.draw_networkx_edges(G, pos, width=edge_weights, alpha=0.5)
nx.draw_networkx_labels(G, pos, font_size=10, font_weight='bold')
plt.axis('off')
plt.savefig(save_path, dpi=150)
plt.show()
# 关系矩阵热图
plt.figure(figsize=(8, 6))
mask = np.zeros_like(matrix)
mask[np.triu_indices_from(mask)] = True
sns.heatmap(matrix, xticklabels=characters, yticklabels=characters,
cmap='YlOrRd', square=True, mask=mask, linewidths=0.5)
plt.title('人物关系强度矩阵')
plt.tight_layout()
plt.savefig('character_matrix.png', dpi=150)
plt.show()
文本预处理加速:
模型优化:
内存管理:
情感分析不准确:
人物识别遗漏:
ResNet分类效果差:
当前系统主要关注情感和人物关系两个维度,还可以扩展:
情节节奏分析:
场景转换检测:
风格特征分析:
改进文本可视化:
增强模型架构:
交互式分析:
在实际使用中,我发现调整矩阵生成策略对最终分析结果影响很大。特别是对于情感矩阵,采用非均匀分段(根据情节转折点而非固定长度)往往能得到更有意义的模式。此外,在人物关系分析中,除了简单的共现统计,加入对话轮次和情感极性等维度可以显著提升关系质量评估的准确性。