简介SaTScan 中文说明书面向公共卫生、流行病学与空间统计方向的研究人员和学生解决英文文档阅读门槛高、软件上手困难的问题。SaTScan 是一款自由软件通过空间、时间及时空扫描统计用于地理疾病监测、疾病集群检测与统计显著性评估也可应用于考古、生态、犯罪学等领域的聚集性分析。说明书系统梳理了离散与连续扫描数据的处理方式涵盖泊松模型、伯努利模型、时空置换模型、多项式与序模型、指数模型及空间变化时间趋势模型并说明如何调整背景人口、纳入协变量与处理数据缺失。资源包为1个doc文档约485KB内容紧凑便于检索与打印。目前已有2805人学习下载读者可借此快速理解软件原理、模型选择依据与参数含义为疾病早期发现和异常聚集预警提供方法支撑。1. 空间流行病学里的“显微镜”SaTScan 中文说明书能帮你解决什么如果你手头有一份县级或乡镇级的疾病发病数据领导问你“这几个高发区域到底是不是巧合”你大概率需要 SaTScan。它做的事情很具体用空间扫描统计、时间扫描统计或时空扫描统计判断疾病在空间、时间或时空维度上是否存在统计学显著的聚集。换句话说它把“看起来多”变成“显著地多”。这份中文说明书的价值在于它把原本散落在英文帮助文档、示例数据集和统计论文里的操作逻辑整理成了能照着走的流程。适合公共卫生监测人员、流行病学研究者、生态与犯罪学等跨领域分析者以及需要复现空间聚集分析的学生。你不需要先成为统计学家但需要知道自己的数据长什么样、该选哪个概率模型。2. 概率模型怎么选从数据类型反推扫描统计模型SaTScan 的模型选择不是拍脑袋而是由你的数据形态决定的。说明书里把离散扫描和连续扫描分开讲又把离散扫描细分成泊松、伯努利、时空置换、多项式、序、指数、正态等模型。选错模型结果不是“不准”而是根本不可解释。2.1 离散扫描与连续扫描的分界线离散扫描统计假设观测位置是固定的、非随机的。比如你手里有各县的病例数和人口数县的地理位置就是固定的格点你关心的是病例数在格点上的分布是否随机。连续扫描统计则假设观测位置本身是随机的可能出现在研究区域内的任何地方。比如你在一个方形森林样地里记录鸟巢坐标鸟巢可能出现在任何位置你关心的是这些点是否独立随机分布。判断标准很简单如果你的数据已经聚合到行政区划、普查区、邮编区用离散扫描如果你有的是个体级别的精确坐标且研究区域是一个连续的地理范围用连续扫描。说明书里提到的连续泊松模型就是为后者准备的。2.2 泊松、伯努利与时空置换模型的适用场景泊松模型适合“病例数 背景人口”的数据结构。比如某县某年某年龄组的发病人数和对应人口数。零假设下每个区域的预期病例数与该区域人口成正比。说明书里的新墨西哥脑肿瘤数据集就是典型病例文件记录各县各年龄组各性别的病例数人口文件记录对应的人口数坐标文件记录各县的直角坐标。伯努利模型适合 0/1 数据也就是每个观测要么是病例要么是对照。比如儿童白血病研究中病例是确诊儿童对照是随机选取的出生登记儿童。说明书里的亨伯赛德数据集就是纯空间伯努利模型病例文件和对照文件分开坐标文件记录每个位置标识的坐标。时空置换模型只需要病例数据不需要对照或背景人口。它通过置换病例的时空位置来评估聚集显著性。说明书里的纽约市发热急诊数据集就是时空置换模型记录邮编、病例数、日期坐标文件记录邮编对应的经纬度。这个模型会自动调整纯空间和纯时间聚集所以没有纯时间或纯空间版本。2.3 多项式、序、指数与正态模型的特殊要求多项式模型用于分类数据每个病例属于多个类别之一。比如脑膜炎病例按五个不同克隆物分类扫描统计同时寻找任何类别或类别组合的聚集。序模型用于有序分类数据比如乳腺癌早期、中期、晚期。如果只有两个类别序模型等价于伯努利模型。序模型可以搜索高值聚集、低值聚集或同时搜索两者。指数模型用于生存时间数据。每个病例有一个连续变量诊断到死亡或删失的时间和一个 0/1 删失指示变量。说明书特别提醒时空指数模型里有两个时间变量一个是诊断时间扫描窗口扫描的维度另一个是生存时间病例的属性不参与扫描。正态模型用于连续数据比如出生体重。如果每个区域的观测值是基于不同样本量的均值需要用加权正态模型权重可以是样本量或方差的倒数。提示模型选择错误是新手最常见的翻车点。拿到数据先问自己三个问题位置是固定的还是随机的有没有背景人口结果是计数、0/1、分类、有序、生存时间还是连续值答案会直接锁定模型。3. 数据文件准备cas、pop、geo、ctl 四类文件的格式与生成SaTScan 的数据输入靠几个纯文本文件病例文件.cas、人口文件.pop、坐标文件.geo、对照文件.ctl。说明书里给出了每个示例数据集的格式但实际项目中你往往需要自己从 Excel 或数据库导出。这一章把格式规则拆开并给出可复用的 Python 转换脚本。3.1 病例文件与人口文件的列顺序病例文件的格式取决于模型。以离散泊松模型为例说明书里的 nm.cas 格式是县 病例数1 年龄组 性别。注意这里的病例数如果是 1表示该行代表一个病例如果是聚合数据则写实际病例数。人口文件 nm.pop 格式是县 年 人口 年龄组 性别。年份、年龄组、性别这些变量必须与病例文件中的变量一一对应。伯努利模型的病例文件和对照文件分开。nhumberside.cas 格式是位置编号 病例数nhumberside.ctl 格式是位置标识 对照数。坐标文件 nhumberside.geo 格式是位置标识 x y。时空置换模型的 nycfever.cas 格式是邮编 病例数1 日期坐标文件格式是邮编 纬度 经度。注意这里没有人口文件因为模型不需要背景人口。3.2 坐标文件的坐标系与精度坐标文件支持直角坐标和经纬度。说明书里的新墨西哥数据集用直角坐标纽约发热数据集用经纬度。经纬度坐标要注意SaTScan 内部会把经纬度转换为球面距离所以不要自己先投影成平面坐标再输入除非你明确知道自己在做什么。直角坐标则要求 x 和 y 的单位一致比如都是米或都是千米。坐标精度方面说明书里的示例数据精确到县、邮编或具体地点。实际项目中如果你用的是个体坐标注意不要引入隐私泄露风险。常见做法是聚合到普查区或邮编区或者对坐标加随机偏移。3.3 用 Python 把 Excel 转成 SaTScan 输入文件下面这个脚本把一份包含县、年、年龄组、性别、病例数、人口数的 Excel 表拆成 nm.cas、nm.pop、nm.geo 三个文件。假设 Excel 里有county、year、age_group、sex、cases、population、x、y这些列。import pandas as pd # 读取原始数据 df pd.read_excel(raw_data.xlsx) # 病例文件县、病例数、年龄组、性别 cas df[[county, cases, age_group, sex]].copy() cas.columns [county, cases, age_group, sex] cas.to_csv(nm.cas, sep , indexFalse, headerFalse) # 人口文件县、年、人口、年龄组、性别 pop df[[county, year, population, age_group, sex]].copy() pop.columns [county, year, population, age_group, sex] pop.to_csv(nm.pop, sep , indexFalse, headerFalse) # 坐标文件县、x、y每个县只保留一行 geo df[[county, x, y]].drop_duplicates(subset[county]) geo.columns [county, x, y] geo.to_csv(nm.geo, sep , indexFalse, headerFalse) print(文件已生成nm.cas, nm.pop, nm.geo)逻辑说明病例文件保留每个县、每个年龄组、每个性别的病例数人口文件保留对应的人口数坐标文件按县去重因为每个县只有一个地理坐标。参数方面sep 表示用空格分隔headerFalse表示不写列名这是 SaTScan 要求的纯文本格式。如果你的数据里病例数是聚合的cases列直接写总数如果是个体数据每行写 1。注意SaTScan 对空格和制表符敏感。如果生成的文件用逗号分隔导入时会报错。建议用sep 或sep\t并在文本编辑器里确认列对齐。4. 避坑与排查参数文件、时间精度和模型误用的血泪经验这一章记录的是实际跑 SaTScan 时最容易翻车的几个点。说明书里不会把这些写成“常见问题”但每个做过空间聚集分析的人大概都踩过。4.1 参数文件选错导致结果完全不可解释现象打开保存的会话后选了一个参数文件跑出来的聚集区域和预期完全不符。原因参数文件里绑定了模型类型、时间精度、扫描窗口大小等关键设置。如果你用泊松模型的参数文件去跑伯努利数据软件可能不报错但结果没有意义。解决每次新建分析时从“新建会话”开始逐步选择模型、导入数据、设置参数不要直接套用别人的参数文件。如果要用现成的先检查参数文件里的模型类型和你的数据是否匹配。4.2 时间精度设置不当导致扫描窗口错位现象时空分析中聚集的时间范围看起来不对或者软件提示时间单位错误。原因SaTScan 要求指定时间精度比如年、月、日。说明书里的新墨西哥数据集用“年”作为病例时间精度纽约发热数据集用“天”。如果你把日度数据设成年精度软件会把同一天的数据合并扫描窗口也会按年滑动。解决导入数据后在时间精度设置里选择与数据实际粒度一致的单位。如果不确定先看病例文件里的日期列格式是1973还是2001/11/01。4.3 坐标文件与病例文件的位置标识不匹配现象软件提示“位置标识在坐标文件中找不到”或类似错误。原因病例文件里的位置标识如县名、邮编和坐标文件里的标识不一致可能是大小写、空格、编码问题。解决用脚本检查两个文件的标识集合是否完全一致。下面这段代码可以快速比对。import pandas as pd cas pd.read_csv(nm.cas, sep , headerNone, names[county, cases, age, sex]) geo pd.read_csv(nm.geo, sep , headerNone, names[county, x, y]) cas_ids set(cas[county].astype(str).str.strip()) geo_ids set(geo[county].astype(str).str.strip()) print(病例文件有但坐标文件没有, cas_ids - geo_ids) print(坐标文件有但病例文件没有, geo_ids - cas_ids)逻辑说明str.strip()去掉首尾空格astype(str)统一转成字符串再比较。如果输出非空就需要手动修正标识。4.4 时空置换模型用于多年数据导致 P 值有偏现象用时空置换模型分析跨越好几年的数据结果出现大量显著聚集但仔细看是人口增长导致的。原因说明书里明确警告时空置换模型只使用病例数据如果研究期间不同地区的人口增长速率不同病例数的增加可能仅仅是因为人口增加而不是疾病风险增加。解决如果研究期间超过一年尽量用泊松模型并提供逐年人口数据。如果必须用时空置换模型把研究期间限制在一年以内或者在结果解释时格外谨慎。4.5 正态模型未加权导致小样本区域被过度放大现象用正态模型分析各区域的平均出生体重小样本区域出现极端值导致假聚集。原因标准正态模型假设每个观测的方差相同但小样本区域的均值方差更大。说明书里建议用加权正态模型权重设为样本量或方差倒数。解决在输入文件里增加一列权重权重与样本量成正比。如果所有观测权重相同加权模型退化为标准模型。5. 从跑通示例到产出可解释结果一个完整的验证习惯跑通说明书里的示例数据集只是第一步。真正要交付的是可解释、可复现的分析结果。我一般会按下面的顺序走一遍确保每一步都有据可查。5.1 用示例数据验证软件安装与参数理解安装完 SaTScan 后先打开软件点击“打开保存的会话”选择说明书里提到的参数文件比如纳米带宝对应的泊松模型参数文件。跑完后看输出窗口里的聚集列表、对数似然比、P 值。如果这些数字和说明书里的示例结果一致说明软件安装和参数理解没问题。如果结果不一致检查数据文件是否被修改过或者参数文件里的路径是否指向了错误的数据文件。5.2 用敏感性分析确认聚集不是参数偶然确定主分析参数后做几组敏感性分析。比如把最大扫描窗口从 50% 人口改成 30% 或 10%看聚集区域是否稳定。如果聚集区域随窗口大小剧烈变化说明结果不稳健。另一个敏感性分析是换模型泊松模型和时空置换模型都跑一遍看哪些聚集在两个模型下都显著。说明书里提到时空置换模型会自动调整纯空间和纯时间聚集所以它可以作为泊松模型的补充验证。5.3 输出结果的解读与报告写法SaTScan 的输出包括聚集区域的位置标识、半径、病例数、预期病例数、相对风险、对数似然比和 P 值。报告时不要只写“发现了显著聚集”要写清楚在哪个时间范围内、哪个地理区域、聚集了多少病例、预期多少、相对风险多少、P 值多少。如果用了多个模型说明哪个模型是主分析哪个是敏感性分析。如果聚集区域跨越多个行政区用地图可视化会更直观但注意不要泄露个体隐私。5.4 我每次跑 SaTScan 都会强制走一遍的检查清单从那以后我每次跑 SaTScan 都强制走一遍这个清单第一确认病例文件、人口文件、坐标文件的位置标识完全一致第二确认时间精度与数据粒度匹配第三确认模型类型与数据类型匹配第四跑一遍示例数据验证软件状态第五做至少两组敏感性分析第六输出结果里同时保留对数似然比和 P 值不只看 P 值。这套习惯帮我省掉了至少三次返工。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?