← Back to Blog

An Analysis and Visualization of a Holiday Classic: Grey's Anatomy Season 2

Jan 28, 2017 · WeifanD

数据挖掘视角下的《实习医生格蕾》:第二季剧本分析

大年初一,合家团聚。耳边传来小岳岳欢快的歌声,手下敲打着键盘,想着花点时间将这个酝酿已久的“坑”填上。

在数据挖掘领域,文本挖掘 (Text Mining) 一直是我觉得极具魅力的主题。受 David Robinson 对圣诞爱情电影《真爱至上》(Love Actually) 分析的启发,我决定将目光投向当年我最爱的医学美剧——《实习医生格蕾》(Grey’s Anatomy)

背景介绍

《实习医生格蕾》是一部由美国广播公司(ABC)出品的医疗题材电视剧,由珊达·莱梅斯 (Shonda Rhimes) 编剧并制作,艾伦·旁派 (Ellen Pompeo) 领衔主演。剧集描写了一群年轻的实习医生之间的情感纠葛,以及他们在事业上的前进与磨练。在高强度的外科训练之余,剧中掺杂了大量的喜剧和爱情元素,剧情幽默中略带纠结。

截至 2016 年 5 月,全剧已播完第十二季。本次分析聚焦于第二季,这是主角团从青涩学生向成熟医生转变的关键一年。

Grey’s Anatomy Poster

1. 数据获取与理解 (Data Understanding)

我在网上找到了第二季的完整剧本数据。在第二季中,Meredith, Izzie, Alex, George 和 Cristina 昨天还是医学生,今天已正式成为西雅图恩典医院 (Seattle Grace Hospital) 的外科住院医。

这里有着最艰苦的实习程序,是医务新人最残酷的训练场。摆在他们面前的,不仅是七年炼狱般的实习培训,还有复杂的人际关系和情感难关。

数据集概况:

  • 文件大小:约 2.4 MB
  • 包含信息:剧集名、编剧、角色名、台词内容、场景描述(旁白)。
  • 格式:非结构化文本,通过冒号 : 分隔来源和内容。

2. 数据清洗与预处理 (Data Cleaning)

原始数据中,冒号分隔了“来源”和“内容”。来源包括角色名、集数标识或编剧信息。为了便于分析,我们需要进行标准化处理:

  1. 分离列:将文本拆分为 form (来源) 和 content (内容)。
  2. 清洗脏数据:去除空行和非对话内容。
  3. 场景标记:识别集数标记(如 “2x01”),并为每一集分配唯一的 scene ID。
  4. 角色归一化:统一大小写,过滤掉非角色行(如动作描述)。

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")

Writers Distribution

分析结论: 在总共 27 集的季数中,Shonda Rhimes 亲自操刀了约四分之一(7集),是当之无愧的核心编剧。作为该剧的创造者,她不仅确立了剧集的基调,还制作了《私人诊所》、《丑闻》等多部热门美剧,并于 2007 年入选《时代》周刊全球百大最具影响力人物。

Shonda Rhimes

3.2 剧集标题

每一集的标题往往暗示了本集的主题。

episodes <- text %>%
  filter(str_detect(form, "2x")) %>% 
  select(form, content) %>% 
  rename(episode_no = form, episode_name = content)

Episode List

你还记得印象最深的一集吗?第一集的标题让人联想到后来那首传唱度极高的歌 “Chasing Cars” (Snow Patrol),歌词 “When the rain is blowing in your eyes…” 完美契合了剧中那种在混乱世界中寻找方向的情感基调。

4. 台词与角色分析 (Dialogue Analysis)

4.1 谁是绝对主角?

我们通过两个维度来衡量角色的重要性:

  1. 主动出场率:角色说了多少句台词 (line_count)。
  2. 被动提及率:角色的名字被其他人提到了多少次 (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"))

Character Stats

分析结论: 综合来看,Meredith Grey 当之无愧是第一主角。无论是主动台词量还是被提及频率,她都高居榜首。

4.2 词云可视化 (Word Clouds)

让我们深入看看主要角色的台词高频词(去除停用词后):

  • Meredith Grey: 她的词云中频繁出现 George,甚至超过了她的男友 Derek。这反映了两人深厚的友谊和室友关系。
  • Cristina Yang: 她的词云中 Burke (她的导师兼男友) 出现频率最高,其次是 surgery。这符合她“手术狂人”的人设,除了医学和 Burke,其他事物很难进入她的视野。
  • George O’Malley: 作为一个温暖的角色,他的词云中充满了情感词汇。他是大家生活中的“蓝颜知己”,毕竟五人组同住一个屋檐下。

Meredith Wordcloud Cristina Wordcloud George Wordcloud

关键发现: 在所有实习生的高频词名单中,Miranda Bailey 的名字赫然在列。这位身材矮小但气场强大的住院总医师,被实习生们私下称为 “The Nazi”(纳粹)。她严厉无情,却在关键时刻给予实习生最多的关怀与指导,是众人成长路上最重要的引路人。

4.3 情感分析与医学词汇

作为一部医疗剧,台词中自然充斥着大量医学术语。我们使用 TF-IDF (Term Frequency-Inverse Document Frequency) 算法来提取具有区分度的关键词。

高频医学词汇 Top 20 (部分):

  1. ablation (消融术)
  2. afebrile (无热的)
  3. amniotic (羊膜的)
  4. appendectomy (阑尾切除术)
  5. arrhythmia (心律失常)
  6. asystolic (心脏停搏)
  7. autopsy (尸检) …

这些词汇不仅增加了剧集的专业度,也构成了独特的语言风格。而在情感词方面,love, lucky, happy 占据了正面情绪的高位,印证了这是一部包裹在白色大衣下的情感剧。

Medical Terms Wordcloud

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)

Clustering Dendrogram

聚类结果解读: 树状图清晰地显示,五大主角 (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()

Appearance Path

有趣发现

  • 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.

#Text Mining #R Language #ggplot2 #Network Analysis #Grey's Anatomy