
Data-Science-For-Beginners 实战作业指南用 Python 完成 COVID-19 疫情建模与论文共现分析【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners本篇技术指南基于开源课程 Data-Science-For-Beginners 第 2 部分第 07 课的课后作业 assignment.md系统讲解如何延续课程挑战中已开始的分析代码完成COVID-19 疫情传播建模与COVID-19 科研论文文本分析两大实战任务。读完本文你将掌握 Pandas 时间序列处理diff、rolling、apply、有效再生数 R_t 的滑动窗口估算、死亡率随时间变化的滞后分析以及基于文本的共现矩阵构建、热力图可视化和正则表达式剂量提取等完整技能并能直接对照仓库中的 notebook-covidspread.ipynb 与 notebook-papers.ipynb 动手实践。作业背景与总体结构本作业要求你在课程两大战役Challenge已启动的代码基础上继续深入拓展共分两部分COVID-19 疫情传播建模Spread Modelling基于约翰斯·霍普金斯大学 CSSE 提供的时间序列数据绘制各国 R_t 曲线、研究感染/死亡/康复的相关关系、推断典型病程长度、计算随时间变化的死亡率COVID-19 论文分析Papers Analysis基于 CORD-19 论文数据集的摘要文本构建药物共现矩阵并用热力图可视化另有弦图Chord Diagram与正则表达式剂量提取两个加分目标。作业配套的完整可运行示例代码位于 notebook-covidspread.ipynb 和 notebook-papers.ipynb本课程的整体背景可参考 07-python/README.md。第一部分COVID-19 疫情传播建模1.1 数据准备加载并聚合全球时间序列课程笔记本 notebook-covidspread.ipynb 展示了数据的标准加载方式可直接从网络拉取最新数据也可使用仓库data/COVID/目录下的本地副本。仓库已提供三份本地时间序列数据data/COVID/time_series_covid19_confirmed_global.csv各国每日累计确诊data/COVID/time_series_covid19_deaths_global.csv各国每日累计死亡data/COVID/time_series_covid19_recovered_global.csv各国每日累计康复import numpy as np import pandas as pd import matplotlib.pyplot as plt plt.rcParams[figure.figsize] (10,3) # 放大图像 base_url ../../data/COVID/ # 从仓库本地加载也可换成在线 URL infected pd.read_csv(base_url time_series_covid19_confirmed_global.csv) deaths pd.read_csv(base_url time_series_covid19_deaths_global.csv) recovered pd.read_csv(base_url time_series_covid19_recovered_global.csv)原始表每行是一个「国家/地区 省份」组合日期作为列名如1/22/20、8/29/21。澳大利亚、中国等国家存在多省细分行因此后续分析前必须按Country/Region汇总infected infected.groupby(Country/Region).sum() deaths deaths.groupby(Country/Region).sum() recovered recovered.groupby(Country/Region).sum() # 丢弃非日期元数据列 infected.drop(columns[Lat,Long,Province/State], inplaceTrue) # deaths、recovered 同理汇总后 DataFrame 以Country/Region为索引即可用infected.loc[US]按国家取数。笔记本中还用[3:]切片去掉前三个非日期列两者效果等价。1.2 核心指标构造每日新增与滚动平滑疫情分析的关键是从「累计值」推导「每日新增」。累计确诊序列的一阶差分即为每日新增感染数df[ninfected] df[infected].diff()由于各国报告的波动很大存在明显的周内周期波动直接绘图难以看出趋势因此笔记本用 7 日滚动均值做平滑df[ninfav] df[ninfected].rolling(window7).mean()完成本部分作业时可仿照上述模式为deaths、recovered同样构造差分列ndeaths、nrecovered为后续相关性分析做准备。1.3 计算有效再生数 R_t课程笔记本给出了疫情传播力的核心概念基本再生数 R_0表示一个感染者平均再感染的人数当 R_0 1 时疫情倾向于扩散。而随时间变化的有效再生数 R_t可粗略估算为取 8 天窗口用前 4 天与后 4 天新增感染之和的比值$$R_t\frac{I_{t-7}I_{t-6}I_{t-5}I_{t-4}}{I_{t-3}I_{t-2}I_{t-1}I_t}$$其中 I_t 为第 t 天的新增感染数。Pandas 的rolling(8)配合apply可直接实现df[Rt] df[ninfected].rolling(8).apply(lambda x: x[4:].sum()/x[:4].sum())绘图时需要注意数据质量问题窗口宽度不足会得到NaN分母为 0 会产生inf。笔记本给出的清理方案是先用replace将inf转为NaN再用fillna向前填充随后限定纵轴并叠加参考线ax df[df.index 2020-05-01][Rt].replace(np.inf, np.nan).fillna(methodpad).plot(figsize(10,3)) ax.set_ylim([0, 6]) ax.axhline(1, linestyle--, colorred) # R_t 1 为疫情扩散与否的分界线1.4 作业任务一绘制 56 个国家的 R_t 对比图将 1.11.3 的流水线封装成函数输入国家名输出以日期为索引、含Rt列的 DataFrame再对 56 个不同国家循环调用。既可以把多条Rt曲线绘制在同一张图内直接对比也可以使用plt.subplots生成并排子图countries [US,India,Brazil,UK,Russia,Italy] fig, axes plt.subplots(2, 3, figsize(15, 6), shareyTrue) for ax, c in zip(axes.flat, countries): dfc compute_rt(c) # 自定义函数加载数据→groupby→diff→rolling(8).apply ax.plot(dfc[Rt]) ax.axhline(1, linestyle--, colorred, linewidth0.8) ax.set_title(c) plt.tight_layout(); plt.show()注意不同国家疫情起始时间不同直接对齐日期轴可能使早期噪声分母为 0 的inf淹没真实趋势建议按国家裁剪疫情爆发前的时间段后再对比这也是作业要求「可能需要在多个国家间查看以得出结论」的原因之一。1.5 作业任务二死亡、康复与感染的相关性在 1.2 构造的ndeaths、nrecovered与ninfected基础上可通过三种途径分析直接对比曲线将三个新增序列绘制在同一坐标轴观察峰值的先后次序与幅度关系相关性系数使用df[[ninfected,ndeaths,nrecovered]].corr()计算皮尔逊相关系数矩阵量化两两关系分国家对比同一国家内死亡与感染的相关强度会随医疗资源、检测能力不同而差异明显跨国家比较更能说明问题。需要特别注意的是康复与死亡相对于感染存在时间滞后患者从感染到康复/死亡通常要经过若干天因此「当天感染 vs 当天死亡」的直接相关会低估真实关联。这就自然引出任务三。1.6 作业任务三推断典型病程持续时间作业要求通过视觉上关联感染率与死亡率曲线并寻找异常来推断典型病程长度。核心思路是对ndeaths序列整体平移若干天即引入滞后寻找使死亡曲线与感染曲线对齐最佳的滞后天数该天数即可作为病程长度的粗略估计。for lag in range(0, 30, 2): shifted df[ndeaths].shift(lag) # 将死亡序列向后平移 lag 天 corr df[ninfected].corr(shifted) print(flag{lag}天, 相关系数{corr:.3f})绘图时可将df[ndeaths].shift(lag)与df[ninfected]或各自的 7 日平滑值叠加直观观察哪一滞后下两条曲线峰值重合。同时应排查异常例如某些国家报告口径突变、死亡统计延迟等会造成曲线出现离群段需要跨多国数据交叉验证后再下结论。1.7 作业任务四计算死亡率及其随时间的变化最基本的形式是累计死亡率deaths / infected。但作业特别强调在进行计算之前可能需要把某一时间序列平移数天。这是因为感染到死亡之间存在病程滞后直接用同一天的累计死亡除以累计确诊会因分母「还没有走完病程」而低估真实致死风险。实现建议# 用滞后 N 天的确诊作分母抵消感染→死亡的平均延迟 N 14 df[fatality_rate_lag] df[deaths] / df[infected].shift(N) # 或使用新增值口径的时变死亡率 df[daily_fatality] df[ndeaths] / df[ninfected].shift(N)绘图观察死亡率随时间的演化趋势通常疫情初期检测不足、分母偏小会导致死亡率虚高随后逐步回落并趋于稳定这一模式本身也值得在报告中解释。笔记本还展示了「新增病例的日差」即二阶差分df[ninfected].diff()作为疫情加速/减速的指示指标可用其辅助判断死亡率变化与疫情阶段的关系。第二部分COVID-19 论文分析2.1 数据集说明本部分使用的CORD-19 论文数据集截至写作时含 7000 篇 COVID 相关论文并未随仓库附带。作业要求你自行下载其metadata.csv元数据文件包含论文标题、摘要abstract与发布时间publish_time等字段。下载后在 notebook-papers.ipynb 中通过pd.read_csv载入即可。若不想注册下载全部全文也可只使用元数据文件。2.2 基于关键词计数的药物/诊断列构造笔记本采用最朴素的做法手工维护「可能用于治疗 COVID 的药物」与「诊断」两个关键词列表然后在每篇论文的摘要中统计各词出现次数生成新的布尔/计数列medications [hydroxychloroquine,chloroquine,tocilizumab,remdesivir, azithromycin,lopinavir,ritonavir,dexamethasone, heparin,favipiravir,methylprednisolone] diagnosis [covid,sars,pneumonia,infection,diabetes,coronavirus,death] for m in medications: df[m] df[abstract].apply(lambda x: str(x).lower().count( m)) for m in diagnosis: df[m] df[abstract].apply(lambda x: str(x).lower().count( m))这里有两个重要的工程细节笔记本以警示形式强调关键词前必须加空格 m否则chloroquine会被错误匹配进hydroxychloroquine的子串导致计数失真必须用str(x)强制转换摘要列可能含NaN直接调用.lower()会抛异常——尝试删掉str()观察报错即可验证。随后可以取出仅含药物计数的子帧dfm df[medications]累加各列得到累计出现次数从而识别「最常被研究的药物」。2.3 作业任务一构建药物共现矩阵共现矩阵Co-occurrence Matrix是一个二维矩阵第 (i, j) 个元素表示同一篇摘要中同时出现第 i 个药物与第 j 个药物的论文篇数。笔记本为「药物×诊断」矩阵给出的代码骨架如下作业要求将其改造为「药物×药物」矩阵m np.zeros((len(medications), len(medications))) for a in df[abstract]: present [str(a).lower().count( me) 0 for me in medications] for i in range(len(medications)): for j in range(len(medications)): if present[i] and present[j]: m[i, j] 1理解该代码的关键外层循环遍历所有摘要内层先统计当前摘要中出现了哪些药物布尔向量present再对出现药物两两组合在矩阵对应位置累加 1。改造为「药物×药物」后矩阵对角线的意义是「药物自身出现的论文数」通常大于非对角线非对角线元素越大说明两个药越常被联合研究——例如chloroquine与hydroxychloroquine、lopinavir与ritonavir常联用通常会有较高的共现值。2.4 作业任务二用热力图可视化共现矩阵构建完矩阵后作业要求用**热力图Heatmap**呈现。笔记本可视化「药物×诊断」矩阵的参考做法import matplotlib.pyplot as plt fig, ax plt.subplots(figsize(10, 8)) im ax.imshow(m) # m 为共现矩阵numpy 数组 ax.set_yticks(range(len(medications))) ax.set_yticklabels(medications) ax.set_xticks(range(len(medications))) ax.set_xticklabels(medications, rotation90) plt.colorbar(im) plt.tight_layout(); plt.show()关键点medications列表的顺序必须与矩阵的行/列顺序严格一致矩阵在构造时即按该列表枚举否则标签与数据会错位。可结合dfm.sum().sort_values(ascendingFalse)先对药物按总频次排序再同步重排矩阵行列使高共现的药物聚在热力图一角更易阅读。2.5 加分目标一弦图Chord Diagram可视化药物共现作业的进阶挑战是使用弦图呈现药物共现关系弦图在圆周上排列各药物节点节点间的弦越粗表示共现频次越高。笔记本身实现了通用的sankey函数接收源类别列表、目标类别列表与共现矩阵并支持阈值参数以省略过弱的连接同一套「矩阵驱动可视化」的思路同样适用于弦图。参考实现时注意将共现矩阵转换为「节点 连边权重」的边列表对每一对药物输出源、目标、权重可设置阈值只保留权重较大的连边避免图形过于复杂与 sankey 函数的 threshold 参数思想一致若矩阵对称通常只绘制上三角以避免重复弦。2.6 加分目标二用正则表达式提取药物剂量第二个加分挑战是提取不同药物的剂量例如从句子take 400mg of chloroquine daily中提取400mg。作业给出的核心提示是考虑出现在药物名称附近文本位置的数值。结合笔记本的代码模式可行方案如下import re def extract_dosage(abstract, medication): # 匹配药物名附近前后各 80 字符内的“数字单位”模式如 400mg、5 mg、1000 mg/day pattern r([\d.,]\s*(?:mg|g|mcg|µg|iu|ml))\b text str(abstract).lower() # 先定位药物出现位置再在其邻域内搜索剂量 results [] for match in re.finditer(medication, text): start max(0, match.start() - 80) end min(len(text), match.end() 80) results re.findall(pattern, text[start:end]) return results dosage_rows [] for _, row in df.iterrows(): for me in medications: for d in extract_dosage(row[abstract], me): dosage_rows.append({medication: me, dosage: d}) dosage_df pd.DataFrame(dosage_rows)该方案的要点正则模式([\d.,]\s*(?:mg|g|mcg|µg|iu|ml))匹配「数值 单位」组合\b防止mg误匹配mgt之类的子串邻域窗口示例取前后 80 字符体现「数值需在药物名称的附近文本中出现」这一要求避免把整篇摘要中无关的数字剂量与药物错误关联最终用pd.DataFrame汇总得到「药物 × 剂量」表可进一步按药物分组、统计出现最多的剂量值。评价标准Rubric作业官方评价标准如下完成时可对照自查优秀Exemplary合格Adequate待改进Needs Improvement所有任务均已完成、图形化展示并加以解释且至少完成两个加分目标中的一个完成超过 5 项任务未尝试加分目标或结果不清晰完成任务少于 5 项但多于 3 项可视化未能帮助说明要点环境与运行建议运行两份笔记本需要 Python 环境及 Pandas、NumPy、Matplotlib 等库文本分析部分还建议准备正则相关标准库re及可选的chord绘图库疫情时间序列部分可直接使用仓库 data/COVID/ 下的本地数据无需联网论文部分需自行获取 CORD-19 的metadata.csv建议按「数据加载 → 指标构造 → 绘图 → 结论解释」的顺序逐任务推进并将每个任务的代码、输出图与文字结论对应记录以满足评价标准中「图形化展示并解释」的要求。通过完成本作业你将把课程中 Series/DataFrame、diff、rolling、groupby、apply、文本关键词计数与矩阵可视化等知识串联成一条完整的数据科学实践链路具备独立完成「时间序列流行病学分析」与「科研文本共现挖掘」两类典型任务的能力。【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考