在人工智能和数据科学的快速发展中,社会网络分析(SNA)成为了研究人与人之间关系的重要工具。通过分析这些连接,研究人员可以揭示出深层次的社交模式和结构,帮助我们更好地理解各种社会动态和人际关系。本文将介绍如何从Sybren Valkema(一位荷兰玻璃艺术家和教育家)的通信档案中构建和分析社交网络,并通过具体的代码案例来阐释其中的核心概念和算法。
什么是社会网络分析?
社会网络分析是一种分析框架,用于揭示个体之间的联系和互动模式。一个社交网络通常由“节点”(人或组织)和“边”(他们之间的连接,如信息交流)组成。在当今的社交媒体环境中,构建社交网络相对简单,但从历史档案中提取这些连接却面临诸多挑战。例如,历史数据往往包含多种文档类型、不同的语言以及各种保存状态,这使得网络构建过程变得复杂。
研究背景
Sybren Valkema(1916-1996)是欧洲“工作室玻璃运动”的先驱之一,他的通信档案包含了大量的通信记录、书籍、绘图等文档。这些档案不仅有打字稿,还有手写文件,涉及多种语言,包含了来自玻璃艺术家、学生、收藏家等多方面的信息。通过对这些档案进行分析,可以构建出一个详细的社交网络,揭示Valkema与其他人在玻璃艺术领域的互动和联系。
数据集介绍
我们使用的主要数据集是Sybren Valkema的数字化通信档案。为了提取相关的通信记录,我们通过元数据筛选出包含“信件”或“通信”的文档。这些文档被扫描成数字化页面,包含了多种语言和不同的书写形式。下表展示了数据集的基本统计信息:
文档类型 | 数量 |
---|---|
打字稿信件 | 150 |
手写信件 | 200 |
其他文档 | 50 |
![]() |
方法论
为了从这些扫描的信件中构建社交网络,我们开发了一个自动化的流水线方法,主要包括以下几个步骤:
- 文本识别(OCR)
- 命名实体识别(NER)
- 记录链接(Record Linkage)
- 实体链接(Entity Linking)
- 社交网络构建
我们将逐步通过代码示例来展示这些步骤。
1. 文本识别(OCR)
首先,我们需要将扫描的图像转换为可编辑的文本。对于打字稿和手写文件,需要分别处理。
import pytesseract
from PIL import Image
# 处理打字稿
typed_image = Image.open('typed_letter.png')
typed_text = pytesseract.image_to_string(typed_image, lang='eng')
# 处理手写稿
handwritten_image = Image.open('handwritten_letter.png')
handwritten_text = pytesseract.image_to_string(handwritten_image, lang='eng+nl') # 可能包含多语言
注意,手写文本的识别难度较大,因此准确率可能较低,这是我们方法中的一个主要挑战。
2. 命名实体识别(NER)
识别出文本中的人名,以便后续构建社交网络。
import spacy
# 加载多语言模型
nlp = spacy.load("en_core_web_sm")
def extract_names(text):
doc = nlp(text)
names = [ent.text for ent in doc.ents if ent.label_ == 'PERSON']
return names
typed_names = extract_names(typed_text)
handwritten_names = extract_names(handwritten_text)
3. 记录链接(Record Linkage)
消除识别出的重复名字,确保每个人在网络中只作为一个节点。
from collections import defaultdict
def deduplicate(names_list):
name_counts = defaultdict(int)
for name in names_list:
name_counts[name.lower()] += 1
# 简单去重,可以根据需要进行更复杂的匹配
unique_names = list(name_counts.keys())
return unique_names
unique_typed_names = deduplicate(typed_names)
unique_handwritten_names = deduplicate(handwritten_names)
4. 实体链接(Entity Linking)
将识别出的名字分类,例如艺术家、学生、收藏家等。
# 假设我们有一个预定义的分类字典
entity_categories = {
'artist': ['Artist A', 'Artist B'],
'student': ['Student A', 'Student B'],
'collector': ['Collector A']
}
def classify_entities(names, categories):
classified = defaultdict(list)
for name in names:
for category, name_list in categories.items():
if name.title() in name_list:
classified[category].append(name)
break
return classified
classified_typed = classify_entities(unique_typed_names, entity_categories)
classified_handwritten = classify_entities(unique_handwritten_names, entity_categories)
5. 社交网络构建
使用NetworkX库将实体及其关系构建成社交网络。
import networkx as nx
G = nx.Graph()
# 添加节点
for category, names in classified_typed.items():
for name in names:
G.add_node(name, category=category)
for category, names in classified_handwritten.items():
for name in names:
G.add_node(name, category=category)
# 添加边(假设在同一封信中提到的人之间有联系)
def add_edges(text):
names = extract_names(text)
for i in range(len(names)):
for j in range(i+1, len(names)):
G.add_edge(names[i], names[j])
add_edges(typed_text)
add_edges(handwritten_text)
# 可选:根据边的出现频率设置权重
for u, v in G.edges():
G[u][v]['weight'] = G[u][v].get('weight', 0) + 1
评估与结果
为了评估我们的自动化方法,我们将其与由领域专家手动构建的发送者-接收者网络进行比较。结果显示,自动化方法在发现发送者-接收者连接方面表现出色,同时还能发现一些额外的有意义的连接。然而,文字识别的准确性仍然是一个主要挑战,尤其是在处理手写文本时。
缺失连接
由于OCR识别的不完全,某些发送者或接收者可能被遗漏,导致网络中出现缺失的连接。
额外连接
自动化方法不仅发现了预期的发送者-接收者连接,还揭示了一些隐藏的关系,这为进一步的艺术历史研究提供了新的视角。
结论与未来工作
本文介绍了一种从异构档案数据中构建社交网络的流水线方法,以Sybren Valkema的通信档案为案例进行了验证。结果表明,尽管OCR识别仍是一个挑战,但自动化方法在构建社交网络方面表现出强大的潜力。未来的工作可以集中在提高手写文本的识别准确性,以及进一步优化实体链接和网络构建的算法,以揭示更多隐藏的社交关系。
此外,本研究强调了跨学科合作的重要性。与艺术史专家和自然语言处理专家的合作,使得研究不仅在技术上可行,也在艺术历史的背景下具有深远的意义。
通过这样的研究方法,我们不仅能够更好地理解历史人物之间的互动,还能为数字人文领域提供强有力的技术支持,推动更多有意义的研究成果。