An Analysis and Visualization of a Holiday Classic: Grey's Anatomy Season 2
数据挖掘视角下的《实习医生格蕾》:第二季剧本分析
大年初一,合家团聚。耳边传来小岳岳欢快的歌声,手下敲打着键盘,想着花点时间将这个酝酿已久的“坑”填上。
在数据挖掘领域,文本挖掘 (Text Mining) 一直是我觉得极具魅力的主题。受 David Robinson 对圣诞爱情电影《真爱至上》(Love Actually) 分析的启发,我决定将目光投向当年我最爱的医学美剧——《实习医生格蕾》(Grey’s Anatomy)。
背景介绍
《实习医生格蕾》是一部由美国广播公司(ABC)出品的医疗题材电视剧,由珊达·莱梅斯 (Shonda Rhimes) 编剧并制作,艾伦·旁派 (Ellen Pompeo) 领衔主演。剧集描写了一群年轻的实习医生之间的情感纠葛,以及他们在事业上的前进与磨练。在高强度的外科训练之余,剧中掺杂了大量的喜剧和爱情元素,剧情幽默中略带纠结。
截至 2016 年 5 月,全剧已播完第十二季。本次分析聚焦于第二季,这是主角团从青涩学生向成熟医生转变的关键一年。

1. 数据获取与理解 (Data Understanding)
我在网上找到了第二季的完整剧本数据。在第二季中,Meredith, Izzie, Alex, George 和 Cristina 昨天还是医学生,今天已正式成为西雅图恩典医院 (Seattle Grace Hospital) 的外科住院医。
这里有着最艰苦的实习程序,是医务新人最残酷的训练场。摆在他们面前的,不仅是七年炼狱般的实习培训,还有复杂的人际关系和情感难关。
数据集概况:
- 文件大小:约 2.4 MB
- 包含信息:剧集名、编剧、角色名、台词内容、场景描述(旁白)。
- 格式:非结构化文本,通过冒号
:分隔来源和内容。
2. 数据清洗与预处理 (Data Cleaning)
原始数据中,冒号分隔了“来源”和“内容”。来源包括角色名、集数标识或编剧信息。为了便于分析,我们需要进行标准化处理:
- 分离列:将文本拆分为
form(来源) 和content(内容)。 - 清洗脏数据:去除空行和非对话内容。
- 场景标记:识别集数标记(如 “2x01”),并为每一集分配唯一的
sceneID。 - 角色归一化:统一大小写,过滤掉非角色行(如动作描述)。
R 代码实现
library(tidyverse)
library(tidytext)
# 假设 raw 是读取原始文本行的向量
text <- data_frame(raw = raw) %>%
filter(raw != "", !is.na(raw)) %>%
# 按冒号分割,fill='left' 处理没有冒号的行(如场景描述)
separate(raw, c("form", "content"), sep = ": ", fill = "left") %>%
mutate(form = ifelse(is.na(form), "others", form)) %>%
mutate(form = str_to_lower(form),
# 检测是否为新的一集 (例如 "2x01")
is_scene = str_detect(form, "2x"),
scene = cumsum(is_scene)) %>%
filter(form != 'others', scene > 0) %>%
select(-is_scene)
# 提取所有唯一的角色名 (假设角色名只包含字母)
characters <- text %>%
filter(str_detect(form, '^[a-zA-Z]+$')) %>%
mutate(form = str_to_lower(form)) %>%
select(form) %>%
distinct() %>%
rename(character = form)
# 构建对话数据框
dialogue <- text %>%
inner_join(characters, by = c("form" = "character")) %>%
rename(line = content)
head(dialogue)
输出示例:
# A tibble: 6 x 3
character line
1 mvo "To be a good surgeon, you have to think like a surgeon..."
2 joe "You look familiar. You been here before?"
3 meredith "\"Once. That worked out really well. \""
4 joe "I know that look. It'll be one of two things..."
5 meredith "\"Both. \""
6 mvo "But sometimes, you're faced with a cut that won't heal..."
清洗结果说明:
通过正则匹配、大小写归一化和去噪,我们将原始的 1349 个标签清洗为 167 个有效角色(包含主要医生、病人及客串人物)。其中 mvo (Main Voice Over) 代表主角 Meredith 的旁白。我们还添加了 scene 列,用于后续分析人物在各集中的出场关系。
3. 编剧与剧集结构分析
3.1 谁是幕后操盘手?
首先,让我们看看第二季的编剧分布。Shonda Rhimes 是否包揽了所有剧本?
text %>%
filter(form == 'written by') %>%
rename(writer = content) %>%
# 处理联合编剧情况 (如 "Writer A & Writer B")
separate_rows(writer, sep = " & |, ") %>%
select(scene, writer) %>%
ggplot(aes(x = reorder(writer, ..count..), fill = "skyblue")) +
geom_bar() +
coord_flip() +
labs(title = "Writers Count in Season 2", x = "Writer", y = "Episodes Written") +
theme_minimal() +
theme(legend.position = "none")

分析结论: 在总共 27 集的季数中,Shonda Rhimes 亲自操刀了约四分之一(7集),是当之无愧的核心编剧。作为该剧的创造者,她不仅确立了剧集的基调,还制作了《私人诊所》、《丑闻》等多部热门美剧,并于 2007 年入选《时代》周刊全球百大最具影响力人物。
3.2 剧集标题
每一集的标题往往暗示了本集的主题。
episodes <- text %>%
filter(str_detect(form, "2x")) %>%
select(form, content) %>%
rename(episode_no = form, episode_name = content)
你还记得印象最深的一集吗?第一集的标题让人联想到后来那首传唱度极高的歌 “Chasing Cars” (Snow Patrol),歌词 “When the rain is blowing in your eyes…” 完美契合了剧中那种在混乱世界中寻找方向的情感基调。
4. 台词与角色分析 (Dialogue Analysis)
4.1 谁是绝对主角?
我们通过两个维度来衡量角色的重要性:
- 主动出场率:角色说了多少句台词 (
line_count)。 - 被动提及率:角色的名字被其他人提到了多少次 (
mentioned_count)。
# 1. 统计台词数量
character_in_form <- dialogue %>%
group_by(character) %>%
summarise(n = n()) %>%
arrange(desc(n)) %>%
filter(n > 68) %>%
mutate(class = 'lines_spoken')
# 2. 统计被提及次数 (分词后统计人名)
reg <- "([^A-Za-z\\d#@']|'(?![A-Za-z\\d#@]))"
dialogue_words <- dialogue %>%
unnest_tokens(word, line, token = "regex", pattern = reg) %>%
anti_join(stop_words, by = "word") # 去除停用词
# 筛选出也是角色名的单词进行统计
character_in_line <- dialogue_words %>%
count(word, sort = TRUE) %>%
inner_join(characters, by = c("word" = "character")) %>%
filter(n > 55) %>%
mutate(class = 'mentioned_by_others') %>%
rename(character = word)
# 合并绘图
bind_rows(character_in_form, character_in_line) %>%
ggplot(aes(x = reorder(character, n), y = n, fill = class)) +
geom_bar(stat = "identity", position = "dodge") +
coord_flip() +
labs(title = "Character Presence: Lines Spoken vs. Mentioned",
x = "Character", y = "Count") +
scale_fill_manual(values = c("lines_spoken" = "red", "mentioned_by_others" = "blue"))

分析结论: 综合来看,Meredith Grey 当之无愧是第一主角。无论是主动台词量还是被提及频率,她都高居榜首。
4.2 词云可视化 (Word Clouds)
让我们深入看看主要角色的台词高频词(去除停用词后):
- Meredith Grey: 她的词云中频繁出现
George,甚至超过了她的男友Derek。这反映了两人深厚的友谊和室友关系。 - Cristina Yang: 她的词云中
Burke(她的导师兼男友) 出现频率最高,其次是surgery。这符合她“手术狂人”的人设,除了医学和 Burke,其他事物很难进入她的视野。 - George O’Malley: 作为一个温暖的角色,他的词云中充满了情感词汇。他是大家生活中的“蓝颜知己”,毕竟五人组同住一个屋檐下。
关键发现: 在所有实习生的高频词名单中,Miranda Bailey 的名字赫然在列。这位身材矮小但气场强大的住院总医师,被实习生们私下称为 “The Nazi”(纳粹)。她严厉无情,却在关键时刻给予实习生最多的关怀与指导,是众人成长路上最重要的引路人。
4.3 情感分析与医学词汇
作为一部医疗剧,台词中自然充斥着大量医学术语。我们使用 TF-IDF (Term Frequency-Inverse Document Frequency) 算法来提取具有区分度的关键词。
高频医学词汇 Top 20 (部分):
ablation(消融术)afebrile(无热的)amniotic(羊膜的)appendectomy(阑尾切除术)arrhythmia(心律失常)asystolic(心脏停搏)autopsy(尸检) …
这些词汇不仅增加了剧集的专业度,也构成了独特的语言风格。而在情感词方面,love, lucky, happy 占据了正面情绪的高位,印证了这是一部包裹在白色大衣下的情感剧。
5. 人物关系网络与聚类 (Character Relationship Clustering)
为了探究人物之间的互动关系,我们构建了一个 Speaker-by-Scene 矩阵。如果两个角色在同一场景中同时出现(台词数 > 15),则认为他们存在强关联。
# 构建矩阵
by_speaker_scene <- dialogue %>%
count(scene, character) %>%
filter(n > 15)
# 转换为宽表矩阵用于聚类
speaker_scene_matrix <- by_speaker_scene %>%
select(character, scene, n) %>%
spread(key = scene, value = n, fill = 0) %>%
column_to_rownames("character")
# 层次聚类
dist_matrix <- dist(speaker_scene_matrix)
hc <- hclust(dist_matrix)
# 绘制树状图
plot(hc, main = "Character Clustering based on Scene Co-occurrence",
xlab = "", sub = "", cex = 0.9)
rect.hclust(hc, k = 5, border = 2:6)

聚类结果解读:
树状图清晰地显示,五大主角 (Meredith, Cristina, George, Izzie, Alex) 紧密地聚在一起。这完全符合剧情设定:他们不仅工作在一起,还合租房子,生活轨迹高度重叠。而其他角色如 Bailey, Burke, Webber 则根据其在不同剧集中的指导关系形成了不同的分支。
场景热力图
我们还可以用路径图来展示每集的主要人物出场情况:
scenes_summary <- dialogue %>%
count(scene, character) %>%
filter(n > 25) %>%
mutate(scene_num = as.numeric(factor(scene)))
ggplot(scenes_summary, aes(x = scene_num, y = character)) +
geom_point(size = 3, color = "steelblue") +
geom_path(aes(group = scene_num), alpha = 0.3) +
labs(title = "Character Appearance per Episode",
x = "Episode Index", y = "Character") +
theme_minimal()

有趣发现:
- Alex Karev 在第 9 集完全没有出场(台词数未达标),这可能意味着该集他请假了或者剧情未涉及他。
- Mark Sloan (McSteamy) 直到第 18 集才首次登场,这也解释了为什么他在前期的关系网中是孤立的。
6. 总结 (Conclusion)
通过对《实习医生格蕾》第二季剧本的文本挖掘,我们不仅验证了直觉中的主角地位,还量化了角色间的互动关系。
- Meredith 是绝对的核心叙事者。
- Bailey 是连接所有实习生的关键枢纽。
- 五人组 的生活与工作高度绑定,形成了紧密的社群。
- 剧本在专业医学术语与通俗情感表达之间取得了完美的平衡。
文本挖掘让我们能以一种全新的、量化的视角去重温经典。或许,我也该去重新回顾一下第二季,看看当时是否错过了什么细节。
转载请注明出处:Weifan Dai is the original author. Please give credit to the original author when you use it elsewhere. 数据来源:Internet Movie Script Database (IMSDB) & Fan Transcripts.