信息速览
一个 17 岁的男孩在奥斯陆大学的开放日走进一间屋子,头顶被贴上一小片反光胶带,被告知「尽可能站着别动,六分钟」。屋里的十三台红外相机盯着他头顶那一个点,一百赫兹,一秒一百次。六分钟里,安静与音乐交替出现,每段六十秒。他晃动了吗?晃了多少毫米?旁边站着的另外十一个人,是不是也跟着同一个节拍在晃?
这就是 PhysioNet 上 music-motion-2015 的全部内容——官方名 MICRO Motion capture data from groups of participants standing still to auditory stimuli (2015),奥斯陆大学 RITMO 中心 MICRO 项目 2015 年 3 月 12 日那一批。它不是「听音乐时的全身动作数据库」,而是一个刻意把动作压到最小的实验:受试者被要求静止,研究者关心的是那份压不住的微动,以及它跟音乐的关系。设备是 Qualisys 红外光学捕捉,不是惯性传感器,也不是深度相机;人群是开放日临时招募的一百零八名志愿者,不是患者。
本文按数据集百科的方式写:先讲它替谁解决什么麻烦,再拆文件与字段,然后逐层交代它是什么、好在哪、怎么取,最后是质量评估、生态位与使用路径。全篇只收三类数字——规模、结构、边界;分布类统计交还给拿到数据的人自己算。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 官方名称 | MICRO Motion capture data from groups of participants standing still to auditory stimuli (2015) |
| PhysioNet slug | music-motion-2015 |
| 版本与 DOI | v1.0,10.13026/dfv0-sb95 |
| 采集时间 | 2015 年 3 月 12 日(单日) |
| 采集地点 | 挪威奥斯陆大学,开放日现场 |
| 采集机构 | 奥斯陆大学 RITMO 音乐与运动研究中心 MICRO 项目组 |
| 设备 | Qualisys 红外光学动作捕捉,13 台 Oqus 300/500 相机 |
| 采样率与单位 | 100 赫兹,毫米 |
| 测量对象 | 每人头顶一枚反光标记点的三维瞬时位置 |
| 参与者规模 | 108 人,分 12 组,每组 3–12 人 |
| 单次任务时长 | 6 分钟(36000 帧),全部记录等长 |
| 刺激设计 | 静默 / 冥想 / 萨尔萨 / 电子舞曲,各 60 秒,含连续静默段 |
| 文件构成 | 12 个运动 TSV + 1 个问卷 CSV + 1 个问卷 PDF + 4 段 WAV + 1 个顺序表 |
| 体积 | 压缩 64.2 MB,解压 175.2 MB |
| 许可 | CC BY 4.0(署名即可商用) |
| 情绪或主观评分 | 无(仅有描述性人口学与姿态自陈) |
§1 它要解决的具体麻烦
1.1 想研究「人听到音乐时身体的反应」,却拿不到干净的静止基线
音乐诱发运动这个题目,绝大多数公开数据都拍的是人在跳舞、在跟节拍点头、在跑步机上走。这些数据能回答「人怎么动」,但回答不了「人不动的时候,音乐还剩下多少影响」。后者是一个更精确的问题:如果受试者被明确要求「尽可能站直、别动」,那么残余的毫米级摆动就可以被看作不受意志控制的、自下而上的感觉运动响应。这类微动测的是前庭与姿势控制系统的底噪,而不是编舞。
MICRO 2015 就是为这个问题准备的。它把任务压到最简:一个人,一个点,六分钟,一段一段地听。设计上的关键是把「静默」当成正式的实验条件而不是休息间隔——A 代表静默,与 B 冥想、C 萨尔萨、D 电子舞曲并列。这样一来,任何一份记录里都同时含有「有声」与「无声」两种段落,研究者可以在同一个人、同一场次、同一套相机标定下做配对比较,不必跨数据集借基线。
官方页面把这件事说得直白:2015 年这一批是为了验证 2012 年那一批里「音乐段与静默段之间存在差异」的观察,所以在音乐段之间插入了静默段,并采用自动随机化,允许静默与音乐连续出现。换句话说,它是一个专门用来做内部对照的复现设计,附带了一批高质量的原始轨迹。
1.2 三条常见的错误期待
第一条,以为它是「听音乐时的身体运动数据」。这个误会几乎是必然的:slug 里写着 music 和 motion,页面上又反复出现 music stimuli。但任务恰恰是「standing still」——受试者被要求尽可能不动。你拿到的不是舞姿,而是被压抑后的残余微动,量级在毫米到厘米。若按舞蹈或步态数据集的预期去接,会发现幅度小两三个数量级,做动作识别完全没有可分的类别。
第二条,以为它带情绪标注。音乐数据集常常配愉悦度、唤醒度、效价评分,或者至少一段「你觉得这段音乐让你想动吗」的主观打分。MICRO 2015 的事后问卷只问年龄、性别、听音乐频次、自己创作音乐的频次、跳舞频次、锻炼频次、是否觉得累、与静止相比自己动了多少、与音乐相比自己动了多少,以及实验时是否睁眼、是否锁膝。这些是人口学与自我感知,不是情绪量表。想知道萨尔萨让人多开心,这份数据答不了。
第三条,以为它是惯性传感器或可穿戴数据。红外光学捕捉与 IMU 的差别不只是硬件:光学捕捉给出的是实验室坐标系下的绝对三维位置,没有积分漂移,但受遮挡影响;IMU 给出的是相对加速度与角速度,便携但需姿态解算。这份数据的每一行都是毫米坐标,直接来自相机三角测量,任何按 IMU 思路写的处理管线(积分、卡尔曼滤波、重力对齐)都用不上。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 音乐有无对站立微动的影响 | 同场次的静默段与音乐段 | 够,且是配对设计 |
| 不同音乐类型之间的差异 | 冥想、萨尔萨、电子舞曲三类 | 够做三分类比较,类别偏少 |
| 组内多人的人际同步 | 每组 3–12 人同场、同一批相机同时记录 | 够,是官方点名推荐的方向 |
| 组间差异(不同场次之间) | 12 个场次各一个文件 | 够,但需处理场地差异 |
| 头部运动与音乐声学特征的关联 | 四段 WAV 与头部三维轨迹,时间轴对齐 | 够,可做互相关与频谱分析 |
| 全身关节角度或步态 | 只有头顶一个点 | 不够,完全拿不到 |
| 情绪、愉悦度、唤醒度 | 无相关标注 | 不够 |
| 临床或病理人群 | 开放日健康志愿者 | 不够,无患者、无诊断 |
| 跨设备可比性 | 单实验室、单套相机、单日 | 不够,无法做跨站点验证 |
| 长期或纵向追踪 | 单次六分钟 | 不够 |
这张表值得多看两眼的地方在于:拿到「够」的那几行,恰好都落在「同一个场次内部」的比较上;落在「不够」的那几行,几乎都是跨场次、跨人群、跨模态的需求。这不是巧合,而是设计使然——它是一份为内部对照而生的数据,横向外推从来不在目标里。
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 手上有一批音乐特征提取结果,想找真实人体响应做检验 | 四段刺激的音轨与逐帧头部轨迹严格对齐,可做互相关求滞后 | 先把帧号换算成秒,再按顺序表切段 |
| 想研究「一群人同处一室会不会不自觉同步」 | 12 个场次都是多人同场,天然的多主体同步素材 | 对齐场地角点后计算两两相关 |
| 在做人因或座椅、地面振动的工程评估 | 提供了一个「静止任务 + 外部听觉干扰」的基线范式 | 注意它没有力台,不能替代压力中心指标 |
| 想做时序异常检测或小样本分类的教学案例 | 12 个等长文件、结构一致、体积小,下载无门槛 | 用标签极少的段级任务练手,不要指望高准确率 |
| 需要健康人的姿势控制参考值 | 有一百余人、单日、单实验室的静止站立记录 | 只能当局部参考,不能当人群常模 |
| 想找带情绪的music-induced movement 数据 | 没有情绪标注,类别也只有三种音乐 | 转而去找带主观评分的音乐运动语料 |
| 要训练姿态估计或动作识别模型 | 只有单点头部坐标,无关节定义 | 改用全身动作捕捉库 |
按处境倒推是最省时间的用法。若你的问题里同时出现了「多个人」「同一段时间」「同一种音乐」,这份数据命中率最高;若你的问题里出现了「患者」「全身」「情绪」「跨医院」,那它基本帮不上,早换方向比深挖更划算。
1.5 一句话判断
它是把「人听到音乐时忍不住的那点晃动」单独拎出来称重的一台天平:砝码只有一颗头顶反光点,量程只有几毫米到几厘米,但同场同秒、多人并置,这份对齐精度在公开数据里少见。
1.6 不适合谁:四条边界
第一条边界,不适合做全身运动分析的人。每名受试者只有一个标记点,贴在头部。相机虽然有多台,但输出的标记点集合里,除了 S1 到 S12 这些受试者,只剩 Corner1 到 Corner4 四个场地角点。没有肩、肘、髋、膝,也没有足部。任何需要关节自由度的任务——步态相位、姿势分类、跌倒检测——都无法在这里找到监督信号。
第二条边界,不适合需要主观体验标签的人。数据集没有任何情绪、愉悦度、唤醒度、音乐偏好打分。问卷里的「Motion compared to standstill」「Motion compared to music」两列是受试者对自己移动量的相对自评,是粗糙的序数自陈,不是情绪测量。若你的研究问题里「情绪」是自变量或因变量,这份数据只能提供行为侧,另一端要另找。
第三条边界,不适合要临床或特殊人群的人。一百零八名参与者全部来自奥斯陆大学开放日当天到场的公众,官方页面明确写着「在开放日期间招募」。这意味着样本的年龄分布、健康状况、对实验的配合度都受当日到场人群约束。没有患者、没有诊断、没有用药记录。做前庭疾病、帕金森、老年跌倒风险的研究,用它做对照组都不稳妥,因为没有任何筛选记录能证明它代表健康人群。
第四条边界,不适合做跨数据集或跨设备的合并分析。单日、单实验室、单套相机、单次标定。虽然场地角点被记录下来了,理论上可以做刚体对齐,但相机布置、地面材质、房间声学都没有跨场次的标准化说明。把它的毫米数直接与另一套系统测出的毫米数放在一张表里比较,隐含了一个未经检验的假设:两套系统的坐标系、滤波设置与标记点定义完全等价。
再补一条容易被忽略的:不适合把「组内同步」当成社交或情感的度量。同一组的人站在同一个房间里、看着同一块屏幕、听同一段音乐,他们的头部轨迹之所以相关,可能来自共同的外部驱动(音乐本身),也可能来自视觉耦合或地板振动。这份数据的同步是运动学层面的同步,不是心理学层面的「共鸣」。
§2 数据构成与规格
2.1 三层目录:运动、问卷、声音
顶层只有三个目录加两个文本文件。movement_data 放 12 个 TSV,一个场次一个;demographics 放一个问卷 CSV 与一份问卷 PDF;sound_data 放四段 WAV 与一个顺序表 CSV。顶层另有 LICENSE.txt(约 14.8 KB,即 CC BY 4.0 全文)与 SHA256SUMS.txt(约 1.8 KB,用于下载后校验)。
| 路径 | 内容 | 文件数 | 说明 |
|---|---|---|---|
movement_data/ |
NM0001.tsv … NM0012.tsv | 12 | 每场次一个,头部标记点三维坐标 |
demographics/ |
self_report_nm15.csv | 1 | 109 行(表头 + 108 人),14 列 |
demographics/ |
questionnaire_nm15.pdf | 1 | 问卷原件的扫描或排版稿 |
sound_data/ |
still_stand_silence_1min.wav | 1 | 60 秒静默 |
sound_data/ |
still_stand_meditation.wav | 1 | 60 秒冥想音乐 |
sound_data/ |
still_stand_salsa.wav | 1 | 60 秒萨尔萨 |
sound_data/ |
still_stand_edm.wav | 1 | 60 秒电子舞曲 |
sound_data/ |
nm15_song_order.csv | 1 | 12 组 × 4 段的顺序编码 |
| 顶层 | LICENSE.txt | 1 | CC BY 4.0 全文 |
| 顶层 | SHA256SUMS.txt | 1 | 各文件校验和 |
注意目录名与文件名里都带 nm15。nm 是项目内部对 2015 年这一批的简写(与 2012 年那批区分),movement_data 里的文件统一命名为 NM 加四位场次编号。顺序表 nm15_song_order.csv 用 1 到 4 编码四个刺激、用 A 到 L 编码十二个组,与官方页面里 01: ACABDA 那一段是同一份信息的两种写法,前者方便程序读,后者方便人读。
2.2 字段与记录的完整字典
问卷 CSV 一共 14 列。前两列是键,后面十二列是内容。下表按官方说明与文件表头整理,标注了每一列的取值形态。
| 列名 | 含义 | 取值形态 | 来源层级 |
|---|---|---|---|
| Session | 场次编号 | 整数 1–12 | 官方文件表头 |
| Participant | 组内受试者编号 | 整数,与 TSV 里 S 编号对应 | 官方文件表头 |
| Age | 年龄 | 整数 | 官方文件表头 |
| Sex | 性别 | M / F | 官方文件表头 |
| Listen to music | 听音乐的频次 | 整数 | 官方文件表头 |
| Create music | 自己创作音乐的频次 | 整数 | 官方文件表头 |
| Dance | 跳舞的频次 | 整数 | 官方文件表头 |
| Exercise | 锻炼的频次 | 整数 | 官方文件表头 |
| Tiresome | 是否觉得累 | 0 / 1 / 0.5 | 官方说明 |
| Motion compared to standstill | 与静止相比自己动了多少 | 整数 | 官方文件表头 |
| Motion compared to music | 与音乐时相比自己动了多少 | 整数 | 官方文件表头 |
| Eyes open | 实验时是否睁眼 | Y / N / B | 官方说明 |
| Locked knees | 是否锁膝站立 | Y / N / B | 官方说明 |
| Comments | 自由备注 | 文本 | 官方文件表头 |
官方对编码规则有一段明确说明:0 表示回答「否」,1 表示「是」,0.5 表示受试者自述在两种状态之间切换。例如 Locked knees? 一列里的 0.5,意味着受试者报告自己在直膝与屈膝之间来回变化。而在实际文件中,Eyes open 与 Locked knees 用的是 Y、N、B 三种字符,B 对应「both / 两者都有」,与 0.5 同义。这是一种「说明口径」与「文件口径」不完全同形的常见情况,读数据时必须按文件来。
运动 TSV 不是普通的一行一记录的表格。它是 Qualisys Track Manager 的导出格式:前若干行是键值元信息,之后是一行表头,再之后是逐帧数据。
| 元信息键 | 含义 | 典型值 |
|---|---|---|
| NO_OF_FRAMES | 该文件总帧数 | 36000 |
| NO_OF_CAMERAS | 参与解算的相机数 | 依场次而定 |
| NO_OF_MARKERS | 标记点总数 | 含受试者与四个角点 |
| FREQUENCY | 采样率(赫兹) | 100.0 |
| NO_OF_ANALOG | 模拟通道数 | 0 |
| ANALOG_FREQUENCY | 模拟通道采样率 | 0 |
| DESCRIPTION | 描述 | 通常为空占位 |
| TIME_STAMP | 采集日期与时刻 | 2015-03-12 加当日时间 |
| DATA_INCLUDED | 包含的数据维度 | 3D |
| MARKER_NAMES | 标记点名称序列 | S1…S12、Corner1…Corner4 |
| 数据列 | 含义 | 单位 |
|---|---|---|
| S*X | 第 * 号受试者头部标记点的 X 坐标 | 毫米 |
| S*Y | 第 * 号受试者头部标记点的 Y 坐标 | 毫米 |
| S*Z | 第 * 号受试者头部标记点的 Z 坐标 | 毫米 |
| Corner1 X/Y/Z | 1 号场地角点的三维坐标 | 毫米 |
四个角点不是受试者,而是用来定义采集空间的参考点。它们在同一场次内固定不动,因此可以当作该场次坐标系的地标:把某一帧的四个角点做刚体配准,就能把该场次的坐标变换到另一场次的坐标里。这是跨场次比较唯一可靠的入口,也是官方没有明说、但从数据设计里可以读出来的用法。
2.3 一条记录的完整解剖
所谓「一条记录」,在这份数据里最自然的单位不是一行,而是一个人-场次-段位的组合:某一名受试者在某一场次的某一个六十秒刺激段内的那六千帧。下面这段代码把三个层级一次性摊开。
#-- 读取一份 Qualisys 导出的 TSV,把元信息与数据表分开
import io
import pandas as pd
PATH = "movement_data/NM0001.tsv"
with open(PATH, encoding="utf-8") as fh:
lines = fh.read().splitlines()
#-- 元信息一直延续到第一张表头(含 X 的那一行)
header_idx = next(i for i, ln in enumerate(lines) if "X" in ln and "\t" in ln)
meta = {}
for ln in lines[:header_idx]:
parts = ln.split("\t")
if len(parts) >= 2:
meta[parts[0]] = parts[1]
body = "\n".join(lines[header_idx:])
df = pd.read_csv(io.StringIO(body), sep="\t")
print("帧数", meta["NO_OF_FRAMES"], "采样率", meta["FREQUENCY"])
print("标记点", meta["MARKER_NAMES"].split("\t"))
print("数据形状", df.shape)
跑完之后,df 的每一行是一帧,列是「受试者 × 轴」的笛卡尔积加上四个角点。若某场次有 4 个人,列数就是 4×3 加 4×3 等于 24 列,行数恒为三万六千。所谓「一条记录」,就是把 S2 X、S2 Y、S2 Z 三列在第 1 到第 6000 帧之间切出来,加上第一段是静默这一先验,得到「2 号受试者在第一段静默里的轨迹」。
段位切分要靠顺序表。官方页面给出的是十二行字母串,例如 01: ACABDA,意思是第一组依次听到静默、萨尔萨、静默、冥想、电子舞曲、静默。六段各六十秒,正好六分钟。需要注意的是,这份顺序里 A(静默)可以连续出现,官方在背景里也说明了这一点:自动随机化允许连续的静默段与音乐段。
#-- 按六段顺序切出每个人每段的相对轨迹
SEGMENT_SEC = 60
FPS = 100
ORDER = {"01": "ACABDA", "02": "AABDCA", "03": "AABCDA",
"04": "ABCDAA", "05": "AABCDA", "06": "ACABDA",
"07": "ACBDAA", "08": "ACBDAA", "09": "ACABDA",
"10": "ACDBAA", "11": "AABDCA", "12": "ACABDA"}
def segment_of(session: str, index: int) -> str:
return ORDER[session][index]
def slice_participant(df, pid: int, seg: int):
a = seg * SEGMENT_SEC * FPS
b = a + SEGMENT_SEC * FPS
cols = [f"S{pid} X", f"S{pid} Y", f"S{pid} Z"]
out = df.iloc[a:b][cols].copy()
out.columns = ["x", "y", "z"]
#-- 减去该段首帧,得到相对位移而不是绝对坐标
out = out - out.iloc[0]
out["t"] = (out.index - a) / FPS
return out
traj = slice_participant(df, 2, 1)
print(segment_of("01", 1), traj.shape, traj[["x", "y", "z"]].abs().max().round(2).to_dict())
2.4 场次规模与记录时长的对照表
官方的十二组,每组人数不同。人数直接决定每个文件里有多少列、每个场次能产出多少个「人-段」单元。下表把这三者的关系摊开。
| 场次 | 顺序 | 人数 | 每场人-段单元 | 单人单段帧数 |
|---|---|---|---|---|
| 01 | ACABDA | 3–12 之一 | 人数 × 6 | 6000 |
| 02 | AABDCA | 3–12 之一 | 人数 × 6 | 6000 |
| 03 | AABCDA | 3–12 之一 | 人数 × 6 | 6000 |
| 04 | ABCDAA | 3–12 之一 | 人数 × 6 | 6000 |
| 05 | AABCDA | 3–12 之一 | 人数 × 6 | 6000 |
| 06 | ACABDA | 3–12 之一 | 人数 × 6 | 6000 |
| 07 | ACBDAA | 3–12 之一 | 人数 × 6 | 6000 |
| 08 | ACBDAA | 3–12 之一 | 人数 × 6 | 6000 |
| 09 | ACABDA | 3–12 之一 | 人数 × 6 | 6000 |
| 10 | ACDBAA | 3–12 之一 | 人数 × 6 | 6000 |
| 11 | AABDCA | 3–12 之一 | 人数 × 6 | 6000 |
| 12 | ACABDA | 3–12 之一 | 人数 × 6 | 6000 |
官方只给出「每组 3 到 12 人」的区间,没有逐组列出人数。要得到逐组人数,读 demographics/self_report_nm15.csv 并统计 Session 列的频次即可,这是拿到数据后第一件该做的事。按总人数一百零八与多数场次取六段顺序推算,人-段单元的总量在几百的量级——比样本量看起来宽松,因为每人贡献了六个段,但每段内只有一个人,不能把六个段当成六个独立受试者。
顺序表里有一个值得留意的结构特征:十二组的首段全部是 A,末段也全部是 A。这是设计使然,官方明确写着「所有试次以六十秒静默开始并结束」。因此第一段与第六段在所有场次之间是可比的纯静默基线,而中间四段的构成各不相同——有的组连续两段静默(如 AABCDA 的第三第四段),有的组音乐紧邻音乐(如 ABCDAA 的第二第三段)。做段位比较时必须按顺序逐段对照,不能把「第三段」笼统当成「音乐段」。
2.5 与同类资源的字段差异
把这份数据与库里已有的三篇放在一张表里比较字段,比读三份说明来得快。下表只比结构,不比结论。
| 维度 | MICRO 2015 | body-sway-music-vr | multimodal-nback-music | music-sudden-cardiac-death |
|---|---|---|---|---|
| 测什么 | 头顶单点三维坐标 | 足底压力中心与三维力 | 皮电、心电、皮温、呼吸等 | 动态与高分辨率心电 |
| 传感器 | 红外光学捕捉 | 测力板 | 可穿戴 + 近红外 | 心电电极 |
| 采样率 | 100 赫兹 | 1000 赫兹 | 依通道而异 | 依设备而异 |
| 受试者 | 108 人,12 组 | 28 人,单独测试 | 招募 11 人留存 5 人 | 992 例患者 |
| 音乐的作用 | 实验刺激(四类) | 实验刺激(四类) | 认知任务背景 | 与音乐无关 |
| 情绪标注 | 无 | 无 | 面部表情 | 无 |
| 同步设计 | 多人同场 | 单人 | 单人 | 不适用 |
| 许可 | CC BY 4.0 | 见该页 | ODC-BY 1.0 | ODbL 1.0 |
这张表最重要的一列是「同步设计」。四个资源里只有 MICRO 2015 是多人同场,其余都是单人测试。人际同步这一类问题,只能在 MICRO 2015 上做,这是它的不可替代性所在。
§3 它是什么:一次把动作压到最小的实验
3.1 项目的来路:MICRO 与 2012 那一批
MICRO 是「Micro Motion」的缩写,指毫米级的微动,而不是麦克风。它属于奥斯陆大学 RITMO 音乐与运动研究中心的一个长期项目,核心命题是:音乐对运动的影响不只出现在人主动跟拍的时候,也会在人不主动运动时以微动的形式渗出来。
2012 年那一批是这条路线的第一站。官方页面在背景里说得很清楚:2015 年这一批是「作为延续」进行的,目的是通过交替播放刺激、在音乐段之间插入静默段,来验证 2012 年数据里发现的「音乐与静默两种条件之间存在差异」。因此 2015 这一批不是一次独立探索,而是一次带着明确假设的复现与强化。
PhysioNet 上两批数据各自独立发布,各自有 DOI。2012 年那批的 DOI 是 10.13026/4h9d-gf10,2015 年这批是 10.13026/dfv0-sb95。官方在「派生来源」一栏里标注了 2015 版派生自 2012 版 v1.0。这条派生关系意味着:两批的范式一脉相承,刺激设计却有实质差别——2012 年用的是电子舞曲、北印度古典乐与挪威民间提琴曲,2015 年换成了冥想、萨尔萨与电子舞曲。刺激不同,结论就不能直接平移。
3.2 任务的骨架:六段六十秒
每人每次坐下、站定、被贴上标记点,然后经历六段各六十秒。第一段一定是静默,最后一段也一定是静默,中间四段从静默、冥想、萨尔萨、电子舞曲里按场次指定的顺序抽取。受试者事先知道「音乐可能在一分钟后开始」,站立姿势自选,双脚位置由地面标记限定。
这个设计有三处值得琢磨的细节。其一,静默是正式条件而不是等待,这让每一份记录都自带对照。其二,受试者知道音乐随时可能开始,这营造了一种预期状态——他没听到音乐时并不是完全放松,而是在等。其三,播放系统与捕捉系统联动触发和停止,官方特别说明「所有记录恰好六分钟」,这意味着帧号与时间是硬对齐的,不需要靠音频互相关去估偏移。
3.3 四类刺激的选择逻辑
静默、冥想、萨尔萨、电子舞曲这四类不是随手挑的。它们在一个维度上张得很开:节拍清晰度。电子舞曲的脉冲最明确,萨尔萨次之,冥想音乐几乎没有稳定节拍,静默则完全没有听觉输入。这一维度正是后来论文里被点名分析的对象——脉冲清晰度(pulse clarity)被发现是对竖直方向运动影响最显著的声学指标。
四段音频以 WAV 形式随数据发布,各六十秒,文件名分别是 still_stand_silence_1min.wav、still_stand_meditation.wav、still_stand_salsa.wav、still_stand_edm.wav。这带来一个便利:你不需要去猜刺激是什么,可以直接提取它的声学特征,然后和头部轨迹做时间序列层面的互相关。这也是官方在「使用说明」里点名的方向之一:音乐信息检索与运动-声音的联合频谱分析。
3.4 采集现场:为什么是开放日
采集发生在 2015 年 3 月 12 日,地点是奥斯陆大学,场合是开放日。这不是一个安静的实验室实验,而是一次在公众活动里嵌入的数据采集。受试者是从当日到场者中招募的,官方写明在招募前已取得挪威研究数据中心的伦理批准(项目编号 NSD2457)。
这个场合决定了几件事。样本是自愿参与的成年人,年龄跨度受当日到场人群影响;每组三到十二人,组内互不相识的概率很高;实验时长被控制在六分钟,符合公众体验的耐心上限;场地是开放日的临时空间,相机布置与地面标记都得在有限条件下完成。这些都不是缺陷,而是这份数据性格的由来——它是一次大规模、低门槛、单日的现场采集,牺牲了实验室的严格控制,换来了百余人量级的多组同场记录。
3.5 为什么只有头顶一个点
这是最容易被质疑的设计选择。全身动作捕捉通常要三十个以上的标记点,这里每人只有一颗,贴在头上。理由是任务本身:受试者被要求尽可能不动,那么全身的位移主要来自姿势的微小调整,而头部是身体最高的点,杠杆最长,微小的躯干倾斜在头部会放大成可见的位移。用一个点去测它,信噪比最好。
代价也很直接:你无法把头部位移分解成踝、膝、髋各自的贡献。姿势控制研究里的经典指标——压力中心的前后向与左右向位移、摆动面积、路径长度——都需要力台,而这里没有。头部单点的位移是这些量的一个代理,代理的合理性取决于「人站直时头部位移主要由踝策略驱动」这个假设,而这个假设在数据集里没有被检验。
3.6 与 2012 版的实质差异
| 维度 | 2012 版 | 2015 版 |
|---|---|---|
| 刺激 | 电子舞曲、北印度古典、挪威民间提琴 | 冥想、萨尔萨、电子舞曲 |
| 静默段 | 不作为正式条件 | 作为正式条件,与音乐并列 |
| 群体规模 | 见该页 | 108 人,12 组 |
| 设计目的 | 探索音乐与运动的关系 | 验证 2012 的差异并强化对照 |
| DOI | 10.13026/4h9d-gf10 | 10.13026/dfv0-sb95 |
两版的差别不只是换了几首歌。2012 版没有把静默当成正式条件,2015 版把静默提升为与音乐并列的一类,并且强制首尾各一段静默。这个改动让 2015 版在「有声 vs 无声」这个最基本的问题上,具备了自足的证据链。
§4 它好在哪:对齐、同场、可复算
4.1 硬对齐:帧号就是秒
时间对齐是时序数据集最常见也最昂贵的麻烦。声音与运动来自两套系统时,偏移量要靠互相关估计,估计误差直接进入结论。MICRO 2015 用了一个工程上最朴素也最可靠的办法:让播放系统去触发捕捉系统。官方原话是「动作捕捉系统随刺激播放系统自动触发和停止」,结果是所有记录精确为六分钟。
这句话的推论很强:第 n 帧对应第 n/100 秒,第 6000 帧对应第 60 秒,段与段的边界在帧号上是整数。你不需要估偏移,不需要对齐算法,甚至不需要读音频就能切段。代价是这套对齐只在录制时成立,若你要把轨迹与外部的音乐特征文件对齐,仍要自己处理音频解码的延迟。
4.2 同场多人:一份数据的两种用法
十二个场次每次三到十二人同处一室,同时被同一批相机记录。这让同一份文件可以支撑两类完全不同的分析。
第一类是「人-条件」分析:把每名受试者当成独立样本,比较他在静默段与音乐段的微动幅度,比较不同音乐类型之间的差异。这是论文里最常见的用法,也是 §2.3 的切分方式直接支持的。
第二类是「组-时刻」分析:不把眼光放在个人身上,而是看同一时刻组内十几个人的轨迹之间是否相关。这类分析里,样本单位是「组-段」,而不是「人-段」,样本量骤降到十几个,但研究的问题完全不同——它问的是人际耦合,而不是个体反应。
第二类用法有一个绕不开的混淆:同组的人共享同一段音乐,音乐本身就会让所有人的轨迹带上共同的周期成分。因此两人轨迹相关,可能只是「都被同一段音乐驱动」,而不是「互相影响」。要把两者分开,需要比较音乐段与静默段的相关强度——若静默段里相关系数明显下降,才谈得上外部驱动占主导。这个比较范式在这份数据里是现成的,因为静默段就在同一次记录里。
4.3 可复算:代码与刺激都在
官方在「使用说明」里给出了 GitHub 仓库,内含处理与分析数据的 Python 与 MATLAB 代码,以及用于播放并同步刺激的 Max/MSP patch。这意味着从原始 TSV 到论文图表的那条链路是公开的,你可以在不重新发明轮子的前提下复现,也可以在它的基础上换方法。
这一点在实际使用中价值很大。Qualisys 的 TSV 格式虽然不难读,但元信息行数不固定、标记点数量随场次变化、角点与受试者混在同一张表里,第一次接手容易踩坑。有一份官方代码做参照,能省掉半天的摸索。
4.4 案例:第一个人的第一段静默
用一个具体的人把上面这些抽象说法落到地上。场次 01 的顺序是 ACABDA,第一段是静默。取这一场的第一名受试者,切出前六千帧,减去首帧,得到他在一分钟静默里的相对轨迹。
#-- §4.4 的案例:场次 01 的第一名受试者,第一段(静默)的相对轨迹
seg = slice_participant(df, 1, 0)
qom = ((seg.x.diff() ** 2 + seg.y.diff() ** 2 + seg.z.diff() ** 2) ** 0.5).sum()
print("段位", segment_of("01", 0))
print("一分钟静默内的累计位移(毫米)", round(qom, 1))
print("三个轴的极差(毫米)",
{k: round(seg[k].max() - seg[k].min(), 2) for k in ("x", "y", "z")})
这段代码里的 qom 是「运动量」(quantity of motion)的雏形:把逐帧位移的欧氏距离加起来,得到一分钟内头部走过的总路程。这个指标在 2018 年那篇基于 MICRO 的论文里是核心因变量之一,论文报告的结论是:所有参与者中,电子舞曲条件下运动量最高;脉冲清晰度是对竖直运动影响最显著的声学指标。
这个案例提醒两件事。其一,单看一个数值没有意义,必须放进「同一个人在不同段之间」或「同一段在不同人之间」的比较里。其二,「静默段」也不是零运动——人不可能真的完全静止,所谓静默基线本身就是一条有起伏的曲线。§7.2 会回到这点。
4.5 案例的延伸:把第一个人放进组里
§4.4 的案例只看了场次 01 里的一个人。若把同一场次的第一段静默里所有受试者的轨迹一起取出来,就能看到「同场」的另一面:这些人共享同一段空气与同一块地板。
#-- 接 §4.4 的案例:把场次 01 第一段静默里所有人的轨迹摊成一张宽表
import numpy as np
def wide_segment(df, seg: int):
a, b = seg * 6000, (seg + 1) * 6000
pids = [c[1:] for c in df.columns if c.startswith("S") and c.endswith(" X")]
cols = []
for pid in pids:
for ax in ("X", "Y", "Z"):
cols.append(f"S{pid} {ax}")
block = df.iloc[a:b][cols].copy()
block = block - block.iloc[0]
block.columns = [f"{c[1:].split(' ')[0]}_{c.split(' ')[1].lower()}" for c in cols]
return block
w = wide_segment(df, 0)
mag = {pid: np.sqrt((w[[f"{pid}_x", f"{pid}_y", f"{pid}_z"]] ** 2).sum(axis=1))
for pid in sorted({c.split("_")[0] for c in w.columns})}
mat = pd.DataFrame(mag).corr()
print("组内人数", mat.shape[0])
print("平均两两相关", round((mat.values.sum() - mat.shape[0]) / (mat.shape[0] ** 2 - mat.shape[0]), 3))
这一小段给出的是「组内平均两两相关」这一指标在静默段的值。按 §4.2 讲的道理,这个值要和同一场次音乐段的对应值放在一起才有解释力。§4.4 的案例与这里的两步连起来,就是这份数据最典型的一条分析路径:先落到个人,再升到组,最后跨段比较。
§5 怎么拿到:目录、下载与读取
5.1 三条取数路径
PhysioNet 上的资源通常有三条路:网页逐文件下载、整包 ZIP、以及平台提供的命令行工具。MICRO 2015 标的是开放访问,不需要签署数据使用协议,也不需要注册,只要能连上站点就能取。
| 路径 | 适用 | 优点 | 注意 |
|---|---|---|---|
| 网页逐文件 | 只想拿一两个 TSV 或问卷 | 无需解压全包 | 大文件下载可能受网络限制 |
| 整包 ZIP | 要全量复现 | 一次到位,含校验和 | 压缩约 64 MB,解压约 175 MB |
| 命令行工具 | 脚本化、批量 | 可断点续传 | 需先装客户端 |
三条路拿到的内容完全一致。若只是看一眼字段,取问卷 CSV 与任意一个 TSV 就够,这两个文件加起来不到半个吉字节的千分之一。
5.2 命令行取整包
#-- 取整包并校验(physionet 的公开项目无需登录)
wget -c -r -np -nH --cut-dirs=2 \
"https://physionet.org/files/music-motion-2015/1.0/" \
-P ./music-motion-2015
cd ./music-motion-2015
sha256sum -c SHA256SUMS.txt 2>/dev/null || echo "校验和文件格式不同,逐项核对"
注意 PhysioNet 的文件目录与内容页的路径不是一回事:内容页是 /content/music-motion-2015/1.0/,实际文件挂在 /files/music-motion-2015/1.0/。用递归抓取时要意识到这一点,否则会拿到一堆 HTML 页面而不是数据文件。
5.3 只取问卷与一个 TSV
#-- 最小取数:问卷与第一场次的运动文件
BASE="https://physionet.org/files/music-motion-2015/1.0"
curl -sSL "$BASE/demographics/self_report_nm15.csv" -o self_report_nm15.csv
curl -sSL "$BASE/movement_data/NM0001.tsv" -o NM0001.tsv
curl -sSL "$BASE/sound_data/nm15_song_order.csv" -o nm15_song_order.csv
wc -l self_report_nm15.csv
head -1 NM0001.tsv
这一组命令跑完,手上就有了三个最关键的文件:谁参与了、第一组怎么动的、十二组各听到什么顺序。绝大多数初步探查都能在这三个文件上完成。
5.4 用 Python 把元信息与数据分离
#-- 通用读取器:不依赖官方代码,自己拆 Qualisys TSV
import io
import pandas as pd
def read_qualisys(path: str):
with open(path, encoding="utf-8") as fh:
raw = fh.read().splitlines()
h = next(i for i, ln in enumerate(raw) if "\t" in ln and ln.split("\t")[0].endswith("X"))
meta = {}
for ln in raw[:h]:
p = ln.split("\t")
if len(p) >= 2 and p[0].strip():
meta[p[0].strip()] = p[1].strip()
df = pd.read_csv(io.StringIO("\n".join(raw[h:])), sep="\t")
return meta, df
meta, df = read_qualisys("movement_data/NM0001.tsv")
print({k: meta[k] for k in ("NO_OF_FRAMES", "FREQUENCY", "DATA_INCLUDED")})
这个读取器抓住了格式的关键:表头行的判据不是行号,而是「第一列以 X 结尾」。这样无论元信息有多少行、相机数是多少、标记点是几个,都能正确定位。
5.5 场地对齐:跨场次比较的前置步骤
#-- 用四个角点做刚体配准,把场次 A 的坐标变换到场次 B 的坐标系
import numpy as np
def corners(df):
idx = [i for i in range(1, 5)]
return np.array([[df[f"Corner{i} {ax}"].iloc[0] for ax in ("X", "Y", "Z")] for i in idx])
def rigid_fit(src, dst):
cs, cd = src.mean(0), dst.mean(0)
h = (src - cs).T @ (dst - cd)
u, _, vt = np.linalg.svd(h)
r = vt.T @ u.T
if np.linalg.det(r) < 0:
vt[2] *= -1
r = vt.T @ u.T
return r, cd - r @ cs
meta_a, dfa = read_qualisys("movement_data/NM0001.tsv")
meta_b, dfb = read_qualisys("movement_data/NM0002.tsv")
r, t = rigid_fit(corners(dfa), corners(dfb))
print("旋转矩阵行列式", round(float(np.linalg.det(r)), 6))
print("平移向量(毫米)", np.round(t, 1).tolist())
行列式应当接近 1,说明这是一个纯旋转平移而不含镜像。这一步不是必需的:若只在同一场次内部比较,绝对坐标经过段内去均值后已经足够。但凡是要跨场次汇总,就得先做这一步,否则不同场次的地板高度与相机朝向差异会混入结论。
5.6 声音侧:把刺激特征与轨迹放到同一根时间轴上
#-- 提取刺激的短时能量包络,与头部竖直位移做互相关,看滞后
import numpy as np
import soundfile as sf
def envelope(path: str, fps: int = 100):
y, sr = sf.read(path)
if y.ndim > 1:
y = y.mean(1)
hop = int(sr / fps)
n = len(y) // hop
frames = y[:n * hop].reshape(n, hop)
return np.sqrt((frames ** 2).mean(1))
env = envelope("sound_data/still_stand_edm.wav")
seg = slice_participant(df, 1, 4) # 场次 01 第五段是 D,电子舞曲
z = seg["z"].to_numpy()[: len(env)]
z = z - z.mean()
env = env - env.mean()
lags = range(-200, 201)
best = max(lags, key=lambda k: float(np.corrcoef(np.roll(z, k), env)[0, 1]))
print("最佳滞后(帧)", best, "即", round(best / 100, 2), "秒")
这段代码的滞后是有符号的:负值意味着运动领先于声音包络,正值意味着滞后。2018 年那篇论文正是用这种互相关方法,在与「明亮度」和「响度」相关的特征上找到了对应关系,并把它解释为预期与反应并存的证据。
5.7 官方代码仓库的用法
官方在页面上指向 GitHub 上的 fourMs/MICRO 仓库,内含 Python 与 MATLAB 的处理与分析代码,以及用于同步刺激播放与捕捉的 Max/MSP patch。用法上没有太多讲究:仓库按年份分目录,2015 这一批的分析脚本可以直接对应到 movement_data 里的文件名。
若你的管线已经成型,不必迁就官方代码。它的主要价值是两处:一是读文件的细节处理(缺失帧、标记点顺序),二是分析指标的定义(运动量怎么算、怎么归一化)。指标定义这一块尤其值得对照,因为不同的归一化方式会让同一份轨迹给出差距明显的数值。
§6 与库内条目的关系
6.1 关系图谱
库内已有三篇与音乐或身体运动沾边的资源,逐个核对标题与定位如下。
| 库内 slug | 主名 | 与本文的关系 | 区隔要点 |
|---|---|---|---|
| body-sway-music-vr | 身体摇摆与虚拟现实音乐刺激数据集 | 最近邻,同为音乐下的站立摇摆 | 测力板测足底压力中心,28 人单独测试,重点是虚拟现实视觉与音乐节律 |
| multimodal-nback-music | 音乐下的 n-back 工作记忆库 | 同为音乐刺激下的多模态记录 | 招募 11 人留存 5 人,任务是认知负荷,重点是生理与面部信号 |
| music-sudden-cardiac-death | 心衰患者猝死队列 | 仅名称含 music | MUSIC 是西班牙语 MUerte Subita en Insuficiencia Cardiaca 的缩写,与音乐无关 |
与 body-sway-music-vr 的区别值得单独讲清楚,因为两者的表层描述几乎可以互换:都在音乐条件下测站立时的身体摇摆。区别有四层,逐层递进。
第一层是测量面。MICRO 2015 测的是头部单点的三维位移,来自红外相机的三角测量;body-sway-music-vr 测的是足底压力中心与三维力,来自测力板。头部位移与足底压力中心都是姿势控制的指标,但前者是运动学量,后者是动力学量,两者的物理意义不能互换,数值也不能直接比较。
第二层是设计。MICRO 2015 是十二组多人同场,每人一次六分钟,六段交替;body-sway-music-vr 是二十余名受试者逐个进入,在视觉条件与音乐条件的全因子组合里各站六十秒。前者支持人际同步,后者支持因果效应的方差分解。
第三层是刺激。MICRO 2015 用冥想、萨尔萨与电子舞曲,另以静默为正式条件;body-sway-music-vr 的音乐设计与虚拟现实视觉条件正交。前者关心「有没有音乐、是什么音乐」,后者关心「看到什么与听到什么的交互」。
第四层是可复算的深度。body-sway-music-vr 那一篇给出了针对特定节律同步音量效应的具体复算结果;MICRO 2015 的官方页面没有给出效应量,只给出了设计与规模。因此本文只能停留在结构与边界的描述,不越界给出「音乐让人多晃多少毫米」的单一结论——那个结论依赖分析口径,2018 年那篇论文给的口径是运动量与脉冲清晰度的关系,不能直接当成数据集的属性。
与 multimodal-nback-music 的区别在任务本身。那一份是在音乐背景下做工作记忆任务,音乐是背景变量,因变量是认知表现与生理负荷;MICRO 2015 里没有认知任务,因变量就是运动本身。两者都用音乐,但一个测脑,一个测身。
与 music-sudden-cardiac-death 的区别最简单:那份数据与音乐没有任何关系。MUSIC 是一个西班牙语队列研究的缩写,全称与音乐无关。搜索引擎把它们排在一起,纯粹是因为 slug 里都有 music。这一条在§7.3 还会再提。
6.2 检索路径
想在库内找到这份数据的邻居,有三条路径。
| 检索目标 | 检索式 | 预期命中 |
|---|---|---|
| 音乐作为刺激的数据集 | 以「音乐」为关键词,看 category_tags 与 keywords | 本文、body-sway-music-vr、multimodal-nback-music |
| 姿势与摇摆类数据 | 以「摇摆」「姿势控制」「平衡」为关键词 | 本文、body-sway-music-vr |
| 光学动作捕捉 | 以「动作捕捉」「光学」为关键词 | 本文、以及全身捕捉类资源 |
| 多人同时记录 | 以「同场」「组内」为关键词 | 本文是少数命中之一 |
第三条路径容易误伤:全身动作捕捉类资源也含「动作捕捉」,但它们的标记点数量、关节定义与用途与本文完全不同。检索时最好把「单点」或「标记点数量」一并作为筛选条件。
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
在给分之前,必须先纠正一个认知错位。数据集的质量不是一条单轴的分数,它至少有三个互不换算的维度:规模是否够用、结构是否可接、边界是否清楚。一份样本量很大但边界模糊的数据,可能在规模上拿高分而在边界上不及格;反过来,一份小而设计干净的数据,规模分低但边界分高。若把三者加权成一个总分,得到的数字会掩盖真正影响决策的那一项。
因此下文用 DAIMS 的五维框架分开打分,不做加权平均。DAIMS 在这里指数据充足性(Data adequacy)、可获取性(Accessibility)、可解释性(Interpretability)、可维护性(Maintainability)、可复用性(Substitutability)五个维度,每一维单独给分并写明理由。看到总分低不必慌,要看低在哪一维;看到总分高也不必放心,要看高的是不是你真正需要的那一维。
另一个常见的误判是把「官方页面没有写」当成「数据里没有」。这两件事必须分开。官方页面没有逐组列出人数,但问卷 CSV 里可以数出来;官方页面没有给出效应量,论文里有。凡是能从文件里推出来的,本文按官方文件写;凡是只能靠二次分析得到的,本文标注来源层级,不混为一谈。
7.1 五维评分
| 维度 | 分数 | 理由 |
|---|---|---|
| 数据充足性 | 中上 | 百余人、十二组、每人六段,人-段单元够做段级比较;但每段只有一个人一个点 |
| 可获取性 | 高 | 开放访问,无需注册,CC BY 4.0,整包不到二百兆 |
| 可解释性 | 高 | 字段少、命名直白、有问卷 PDF 与官方代码,上手成本低 |
| 可维护性 | 中 | v1.0 自 2020 年发布后未见修订;官方代码在第三方仓库,非长期托管 |
| 可复用性 | 中上 | 时序分析、音乐信息检索、人际同步都可复用;替代不了测力板与全身捕捉 |
五维里最值得留意的是可维护性。它是一批 2015 年的单次采集,2020 年发布为 v1.0,此后没有新版本。这意味着不存在「等官方修好再下」的选项——你拿到的就是终版。可解释性高是因为字段少,而字段少本身也是局限:只有头部一个点,想深挖也挖不下去。
7.2 分数的边界条件
数据充足性的「中上」有两处限定。其一,段级样本看着多,但同一人的六段不是独立样本,做统计时必须用混合效应模型或按人聚类的稳健标准误,否则会把标准误算小。其二,组间比较的样本单位是十二个组,不是一百零八个人,任何以组为单位的结论,有效样本量都只有十几。
可获取性的「高」有一处限定:网站的文件目录与内容页分属不同路径,自动化脚本若不注意会拿到 HTML。这不是数据本身的问题,但会在第一次接入时浪费一点时间。
可复用性的「中上」取决于任务类型。同场多人这一点几乎没有替代品,凡是涉及人际同步的问题,可复用性接近满分;凡是涉及姿势控制的动力学指标,可复用性很低,因为有力台的替代品更合适。
7.3 已知的、可枚举的偏差
| 偏差 | 具体表现 | 对分析的影响 |
|---|---|---|
| 招募场合偏差 | 开放日到场公众,非随机抽样 | 年龄与兴趣偏向当日活动人群 |
| 单日采集 | 全部数据来自 2015 年 3 月 12 日 | 无法区分个体差异与当日状态 |
| 单实验室 | 一套相机、一次标定范式 | 跨站点外推缺乏依据 |
| 组内人数不均 | 每组 3–12 人 | 以组为单位的统计权重不等 |
| 顺序不平衡 | 十二组顺序各不相同,A 段占比高 | 段位效应与顺序效应部分混淆 |
| 标记点单一 | 每人仅头部一点 | 无法分解姿势策略 |
| 无主观情绪评分 | 只有人口学与姿态自陈 | 情绪相关假设无法检验 |
| 名称歧义 | slug 含 music,易与心电队列混淆 | 检索时误入 music-sudden-cardiac-death |
顺序不平衡这一条值得展开。十二组的顺序里,A(静默)出现的总次数明显多于 B、C、D 各自,因为每组首尾都是 A,中间还常有一个 A。这使得「静默」这个条件的样本量天然大于任一音乐条件。做条件间比较时若不控制,会把「样本多」误当成「效应稳」。正确的做法是按顺序逐段配对,只比较同一位置上的不同条件,或者把 A 段按位置分层。
名称歧义这一条则是库内检索的现实问题。music-sudden-cardiac-death 与本文在 slug 上共享 music 一词,但前者是一份心电队列。任何按关键词粗筛的检索都会把两者混在一起,必须靠副标题或 category_tags 二次区分。
7.4 外部验证矩阵
| 验证角度 | 有无外部对照 | 结论 |
|---|---|---|
| 与 2012 版的范式一致性 | 有,官方标注派生关系 | 范式延续,刺激已更换,结论不可直接平移 |
| 与已发表论文的结论一致性 | 有,2018 年论文基于同类设计 | 运动量与脉冲清晰度的关系被独立报告 |
| 与测力板指标的对应 | 无 | 头部位移与压力中心的关系未被本数据集检验 |
| 跨实验室复现 | 无 | 未见到独立的重复采集 |
| 与人群常模的比对 | 无 | 开放日样本,无代表性声明 |
| 代码可复现性 | 有,官方代码仓库 | 读取与指标定义可对照 |
矩阵里「无」的那三行,恰好是这份数据最容易被高估的地方。若有人拿它去做姿势控制的临床参考值,或声称头部位移可以替代压力中心,都是跨过了没有被验证的那一步。
7.5 它为何能持续:一份无需维护的原始记录
它不需要维护,因为它承诺的东西极少。一份 2015 年的原始轨迹,加了问卷与音频,发布在 PhysioNet 上,CC BY 4.0。没有 API、没有定期更新、没有标注团队在背后持续投入。它的价值全部沉淀在「多人同场、逐帧对齐、原始未加工」这三件事里,而这三件事在文件生成的那一刻就已经固定,不会随时间衰减。
这也是它为何存在的原因。音乐诱发运动这个领域需要可复算的原始数据,而这类数据往往因为采集成本高而不公开。MICRO 项目把两批采集都放了出来,还附上代码与刺激音频,等于把一条完整的研究链路开源。后来者可以不同意它的结论,但绕不开它的原始记录。
§8 生态位与历史
8.1 历史沿革:从 2012 到 2020
时间线大致是这样的。2012 年,MICRO 项目完成第一批采集,用的是电子舞曲、北印度古典乐与挪威民间提琴曲三类刺激,重点在「音乐与运动的对应关系」。2015 年 3 月 12 日,第二批在奥斯陆大学开放日完成,一百零八人分十二组,刺激换成冥想、萨尔萨、电子舞曲,并把静默提升为正式条件。2018 年,基于这批设计的分析论文发表在 Frontiers in Psychology,报告了运动量与脉冲清晰度的关系。2020 年 12 月 8 日,2015 年这批数据以 v1.0 发布在 PhysioNet,DOI 为 10.13026/dfv0-sb95;2012 年那批也在同年发布,DOI 为 10.13026/4h9d-gf10。
这个时间顺序解释了一个常见困惑:为什么数据是 2015 年采的,2020 年才发。中间五年是分析与论文的周期,数据发布是事后补上的开放动作,而不是采集时就有计划。这也解释了为什么它的元信息完整度不如那些「为发布而设计」的数据集——它是先有研究、后有开放。
8.2 在音乐认知研究里的位置
音乐认知这个领域里,运动数据的来源大致分四类:一是让受试者跟着节拍敲击或走动,测的是主动同步;二是让受试者跳舞,测的是自发运动;三是让受试者站着不动,测的是残余微动;四是不测运动,只测脑或生理。MICRO 2015 属于第三类,这一类在公开数据里数量最少。
第三类之所以少,是因为它反直觉:明明要研究运动,却要求人不动。但它的价值恰恰在这里——主动运动里混杂了意图、技能、社会规范,残余微动则更接近感觉运动系统的底层响应。这一类研究的经典参照是姿势控制文献里的「安静站立」范式,那套范式通常用力台。MICRO 2015 用光学捕捉替代了力台,换来了多人同场的可能。
8.3 与姿势控制数据集的错位
必须说清楚一个错位:在姿势控制研究的传统里,安静站立的标准测量是压力中心,指标是摆动面积、路径长度、前后向与左右向的均方根。这套指标体系有几十年的临床常模积累,直接对应跌倒风险、前庭功能、老年平衡。MICRO 2015 测的是头部单点位移,属于这套体系的旁支,不在主干上。
错位的后果是:它的数据不能直接套进临床姿势控制的评价框架,也不能与压力中心常模对照。它属于「具身音乐认知」这条线,而不是「平衡功能评估」那条线。把两者混为一谈,会得出「这份数据可以用来做跌倒风险预测」这类没有依据的推论。
8.4 与其他公开音乐运动数据的分工
| 数据来源类型 | 典型形态 | 与本文的分工 |
|---|---|---|
| 节拍敲击数据 | 手指敲击时间序列 | 主动同步,本文是被动微动 |
| 舞蹈动作捕捉 | 全身关节轨迹 | 大幅自发运动,本文是静止抑制 |
| 音乐下的步态数据 | 步长、步频、地面反力 | 行走状态,本文是站立状态 |
| 音乐下的生理数据 | 心率、皮电、脑电 | 内脏与中枢响应,本文是运动学响应 |
| 本文 | 头部单点三维位移 | 多人同场、音乐条件对照 |
这张表可以用来快速判断一份新数据该放在哪一格。若一份数据同时具备「多人同场」与「多模态生理」,它就在本文与生理类之间;若只有单人单模态,那它更接近实验室范式的常规做法。
§9 使用指引
9.1 三种角色的路径
| 角色 | 最该先做的事 | 可以跳过的事 | 典型产出 |
|---|---|---|---|
| 音乐认知研究者 | 读顺序表,按段切出条件标签 | 不必先做场地对齐 | 条件间的运动量比较 |
| 信号处理工程师 | 先写一个稳健的 TSV 读取器 | 不必细读问卷每一列 | 干净的宽表与段索引 |
| 人因与产品工程师 | 看 §1.4 的处境表,判断是否命中 | 不必复现论文结论 | 是否采用该范式的判断 |
三种角色的共同点是:都不需要把整包读进内存。十二个 TSV 每个约三百多千字节到数兆,单个文件的读取在秒级完成。真正花时间的是理解「哪一段是什么」,而这靠的是顺序表与官方页面的那十二行字母串。
9.2 一条最短的可用流程
从零到能画出一张条件对比图,最短的路径是五步。
#-- 第一步:取三个关键文件
BASE="https://physionet.org/files/music-motion-2015/1.0"
curl -sSL "$BASE/demographics/self_report_nm15.csv" -o demo.csv
curl -sSL "$BASE/movement_data/NM0001.tsv" -o NM0001.tsv
curl -sSL "$BASE/sound_data/nm15_song_order.csv" -o order.csv
#-- 第二步:核对人数是否与总样本吻合
python3.11 -c "import pandas as pd; d=pd.read_csv('demo.csv'); print(d.groupby('Session').size())"
#-- 第三步:切段并计算每段的运动量
import pandas as pd
demo = pd.read_csv("demo.csv")
meta, df = read_qualisys("NM0001.tsv")
order = {"01": "ACABDA"}
rows = []
for seg in range(6):
cond = order["01"][seg]
for pid in sorted({c[1:].split(" ")[0] for c in df.columns if c.startswith("S")}):
s = slice_participant(df, int(pid), seg)
qom = ((s.x.diff() ** 2 + s.y.diff() ** 2 + s.z.diff() ** 2) ** 0.5).sum()
rows.append({"seg": seg, "cond": cond, "pid": pid, "qom": qom})
tidy = pd.DataFrame(rows)
#-- 第四步:按条件汇总,注意这里只是描述,不做推断
summary = tidy.groupby("cond")["qom"].agg(["count", "median"])
print(summary.round(1))
#-- 第五步:把五步串成对全部十二场次的批处理
import glob
all_rows = []
for path in sorted(glob.glob("movement_data/NM*.tsv")):
sid = path.split("NM")[-1].split(".")[0]
meta, d = read_qualisys(path)
seq = ORDER[sid]
for seg in range(6):
for pid in sorted({c[1:].split(" ")[0] for c in d.columns if c.startswith("S")}):
s = slice_participant(d, int(pid), seg)
q = ((s.x.diff() ** 2 + s.y.diff() ** 2 + s.z.diff() ** 2) ** 0.5).sum()
all_rows.append({"session": sid, "seg": seg, "cond": seq[seg],
"pid": pid, "qom": q})
print(pd.DataFrame(all_rows).shape)
第四步的汇总表只有一个用途:让你看见「同一条件在不同段位上给出的中位数差多少」。若差得很大,说明段位效应强,后面做任何条件比较都得先把段位固定住。这一步不做推断,是因为在同一人六段不独立的前提下,直接做组间检验会高估显著性。
9.3 引用方式
官方给出的引用格式是:Gonzalez, V., Zelechowska, A., & Jensenius, A. R. (2020). MICRO Motion capture data from groups of participants standing still to auditory stimuli (2015) (version 1.0). PhysioNet. RRID:SCR_007345. https://doi.org/10.13026/dfv0-sb95
BibTeX 记录为:
@article{PhysioNet-music-motion-2015-1.0,
author = {Gonzalez, Victor and Zelechowska, Agata and Jensenius, Alexander Refsum},
title = {{MICRO Motion capture data from groups of participants standing still to auditory stimuli (2015)}},
journal = {{PhysioNet}},
year = {2020},
month = dec,
note = {Version 1.0},
doi = {10.13026/dfv0-sb95},
url = {https://doi.org/10.13026/dfv0-sb95}
}
CC BY 4.0 的要求是署名,允许商用与改编。若在论文里使用,建议同时引用 2018 年那篇分析论文,因为它给出了这套设计的分析口径与主要结论,单引数据集不足以说明方法来源。
§10 AI 使用声明
| 项 | 说明 |
|---|---|
| 生成方式 | 本文由 AI 辅助撰写,人工定稿 |
| 事实来源 | 以 PhysioNet 官方内容页与文件目录为主,辅以 Europe PMC 论文摘要 |
| 采集口径 | 官方明文写出的原样记录,未做二次估算 |
| 数字类型 | 仅规模、结构、边界三类,分布类统计未纳入 |
| 未核实项 | 逐组人数、角点数量随场次的变化、音频时长精确值 |
| 分析复算 | 本文未下载全量包做统计,示例代码基于单场次文件 |
| 立场 | 不评价研究结论的成立与否,只描述数据的结构与边界 |
| 更新 | 官方自 v1.0 起未见新版本,本文对应 v1.0 |
常见误读(避坑清单)
| 常见说法 | 实际 | 证据 |
|---|---|---|
| 这是听音乐时的全身运动数据 | 任务是尽量站直不动,只有头顶一点的微动 | 官方摘要写明「asked to stand as still as possible」 |
| 用惯性传感器采集 | 用 13 台 Qualisys 红外相机做光学捕捉 | 方法节写明相机型号与 100 赫兹 |
| 带情绪或愉悦度评分 | 问卷只问人口学与站立姿态 | 问卷 CSV 十四列无情绪量表 |
| 108 人是 108 个独立样本 | 每人贡献六段,段间不独立 | 顺序表每场六段,同一人贯穿 |
| 样本是健康人群的代表样本 | 开放日临时招募,无筛选记录 | 官方写明「during the Open Day」 |
| 静默段是零运动基线 | 静默段本身也有微动 | 静止任务只能压低不能消除摆动 |
| 可以替代测力板做平衡评估 | 头部位移与压力中心关系未被本数据检验 | 无同步力台数据 |
| 与 music-sudden-cardiac-death 同类 | 那份的 MUSIC 是西班牙语缩写,与音乐无关 | 该页标题与摘要 |
| 每人只有一个反光点所以相机没用 | 多相机是为了三角测量与抗遮挡,不是为了多个点 | 文件元信息含多相机、单点标记 |
| 组内同步等于人际情感共鸣 | 共享音乐本身就会产生相关 | 静默段对照可用于分离 |
FAQ
Q1:这份数据到底是站着还是动着?
站着。受试者被要求尽可能站直别动,六分钟里唯一的外部变化是声音。所谓运动和音乐的关系,体现在压制之后的残余微动上,量级在毫米到厘米。
Q2:为什么必须有静默段?
静默是正式条件,不是休息。它给每一次记录提供了同人、同场、同标定的对照,使得「音乐段比静默段动得多」这个比较不需要跨数据集借基线。
Q3:一百零八人这个数字怎么用?
它描述的是总参与人数,不是独立观测数。做统计时要按人聚类,或者把段位当成重复测量,否则标准误会算小。
Q4:能不能只下载一个文件先用着?
可以。movement_data/NM0001.tsv 加问卷 CSV 加顺序表,三个文件就够跑通整条链路,加起来只有几兆。
Q5:官方页面的顺序表和顺序 CSV 不一致怎么办?
两者是同一信息的两种写法。官方页面用字母串表示六段,CSV 用 1 到 4 编码四个刺激。以官方页面的字母串为准来理解段位,以 CSV 为准来写程序。
Q6:音频文件能直接拿来发表分析吗?
四段音频是实验刺激,随数据以 CC BY 4.0 发布。用于分析没问题,若要把音频本身再分发或商用,需按许可核对原始素材的权利状态。
Q7:多人同场会不会互相干扰?
会,而且这是设计的一部分。同组的人共享音乐、房间与地板,轨迹相关里混着共同驱动与真实耦合。要分离两者,得比较音乐段与静默段的相关强度。
Q8:为什么有的场次人多有的场次人少?
官方只给区间三到十二人,逐组人数需从问卷 CSV 的 Session 列数出来。开放日的到场是自然发生的,人多寡不由研究者决定。
Q9:这份数据能训练深度学习模型吗?
可以训练时序模型,但不适合监督学习里的分类任务——标签只有四个条件,且每段只有一个人。它更适合自监督、表征学习或作为小样本基准。
Q10:和 2012 版能合并吗?
范式相近但刺激不同,合并需要谨慎。至少要把刺激类别对齐,并说明合并后「音乐条件」的定义发生了变化。
Q11:有没有官方给出的效应量?
数据集页面没有。效应量出现在 2018 年那篇基于同类设计的论文里,报告的是运动量与脉冲清晰度、响度、明亮度的关系。
Q12:许可允许商用吗?
CC BY 4.0 允许商用,条件是署名。署名格式用官方给出的引用即可。
术语表
| 术语 | 含义 |
|---|---|
| MICRO | 项目名,指 Micro Motion,即毫米级微动研究 |
| 头部微动 | 站立静止时头部标记点的残余位移,量级毫米到厘米 |
| 光学动作捕捉 | 用多台红外相机对反光标记点做三角测量的定位方法 |
| Qualisys | 瑞典的动作捕捉设备厂商,本文用的是 Oqus 300/500 系列 |
| Oqus | 该厂商的红外相机型号系列 |
| 反光标记点 | 贴于体表、能把红外光反射回相机的被动标记 |
| 运动量 QoM | 逐帧位移的欧氏距离累加,衡量一段时间内的总路程 |
| 脉冲清晰度 | 音乐节拍可辨程度的声学指标,常用自相关方法估计 |
| 频谱质心 | 描述音色明亮度的声学特征 |
| 静默条件 | 无听觉输入的六十秒段,作为正式实验条件之一 |
| 段位 | 六段中的第几段,从一到六编号 |
| 场次 | 一组参与者的一次完整记录,对应一个 TSV 文件 |
| 场地角点 | 定义采集空间的地面参考点,文件中命名为 Corner1 至 Corner4 |
| 刚体配准 | 用对应点求旋转与平移,把一套坐标变换到另一套 |
| 人际同步 | 同一时刻多个人的运动轨迹之间的相关或耦合 |
| 姿势控制 | 维持身体直立与平衡的神经肌肉调控过程 |
| 压力中心 | 地面反作用力的作用点,是姿势控制的主流指标 |
| 踝策略 | 通过踝关节转动维持平衡的姿势调节方式 |
| 前庭系统 | 内耳中感知头部加速度与朝向的感觉系统 |
| 开放日 | 大学面向公众的开放活动,本文的采集场合 |
| CC BY 4.0 | 知识共享署名许可,允许商用与改编,需署名 |
| DAIMS | 本文采用的五维评估框架:充足性、可获取性、可解释性、可维护性、可复用性 |
| 宽表 | 每帧一行、每人三列的数据组织方式,与长表相对 |
| 去均值 | 减去段内首帧或均值,得到相对位移而非绝对坐标 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 参与者总数 | 108 | 官方摘要与方法节 | 官方页面 |
| 场次数 | 12 | 官方方法节 | 官方页面 |
| 每组人数 | 3–12 | 官方方法节 | 官方页面 |
| 相机数量 | 13 | 官方方法节 | 官方页面 |
| 采样率 | 100 赫兹 | 官方摘要 | 官方页面 |
| 单位 | 毫米 | 官方摘要 | 官方页面 |
| 单次时长 | 6 分钟 | 官方方法节 | 官方页面 |
| 帧数 | 36000 | 文件元信息 NO_OF_FRAMES | 官方文件 |
| 段长 | 60 秒 | 官方方法节 | 官方页面 |
| 刺激类别 | 4 类 | 官方实验刺激节 | 官方页面 |
| 问卷行数 | 109(含表头) | 问卷 CSV | 官方文件 |
| 问卷列数 | 14 | 问卷 CSV 表头 | 官方文件 |
| 音频文件数 | 4 | 声音目录 | 官方文件 |
| 压缩体积 | 64.2 MB | 内容页 | 官方页面 |
| 解压体积 | 175.2 MB | 内容页 | 官方页面 |
| 发布版本 | v1.0 | 内容页 | 官方页面 |
| 发布日期 | 2020-12-08 | 内容页 | 官方页面 |
| DOI | 10.13026/dfv0-sb95 | 引用节 | 官方页面 |
| 许可 | CC BY 4.0 | 许可节 | 官方页面 |
| 伦理批准号 | NSD2457 | 方法节 | 官方页面 |
附录 B:数字的来源分层
| 层级 | 数字 | 说明 |
|---|---|---|
| 官方页面 | 108 人、12 组、3–12 人、13 台相机、100 赫兹、毫米、6 分钟、60 秒、4 类刺激、64.2 MB、175.2 MB | 从内容页原样抄录,未做推算 |
| 官方文件 | 36000 帧、109 行、14 列、4 个 WAV、12 个 TSV | 由文件本身读出,可由他人复核 |
| 论文摘要 | 电子舞曲条件下运动量最高、脉冲清晰度影响竖直运动 | 来自 2018 年 Frontiers in Psychology 论文摘要 |
| 未核实 | 逐组人数、角点数随场次的变化、音频精确时长 | 页面未列,本文未逐文件统计 |
这份分层的意思很直接:前两层可以直接引用,第三层要连同论文一起引,第四层在写论文时必须自己核实后再用。把四层混在一起叙述,是这类数据集被误引的主要来源。
附录 C:完整参考文献
- Gonzalez, V., Zelechowska, A., & Jensenius, A. R. (2020). MICRO Motion capture data from groups of participants standing still to auditory stimuli (2015) (version 1.0). PhysioNet. RRID:SCR_007345. https://doi.org/10.13026/dfv0-sb95
- Gonzalez, V., Zelechowska, A., & Jensenius, A. R. (2020). MICRO Motion capture data from groups of participants standing still to auditory stimuli (2012) (version 1.0). PhysioNet. https://doi.org/10.13026/4h9d-gf10
- Gonzalez-Sanchez, V. E., Zelechowska, A., & Jensenius, A. R. (2018). Correspondences Between Music and Involuntary Human Micromotion During Standstill. Frontiers in Psychology. https://doi.org/10.3389/fpsyg.2018.01382
- MICRO 项目主页,奥斯陆大学 RITMO 音乐与运动研究中心,https://www.uio.no/ritmo/english/projects/micro/
- MICRO 处理与分析代码仓库,https://github.com/fourMs/MICRO
- PhysioNet 内容页,https://physionet.org/content/music-motion-2015/1.0/
附录 D:常用任务代码
#-- 任务一:把单个文件整理成「帧 × 人 × 轴」的长表,便于建模
import pandas as pd
def to_long(df, fps: int = 100):
pids = sorted({c[1:].split(" ")[0] for c in df.columns if c.startswith("S")})
parts = []
for pid in pids:
sub = df[[f"S{pid} X", f"S{pid} Y", f"S{pid} Z"]].copy()
sub.columns = ["x", "y", "z"]
sub["pid"] = pid
sub["t"] = sub.index / fps
parts.append(sub)
long = pd.concat(parts, ignore_index=True)
return long[["t", "pid", "x", "y", "z"]]
meta, df = read_qualisys("movement_data/NM0001.tsv")
long = to_long(df)
print(long.shape, long["pid"].nunique())
#-- 任务二:估计竖直方向的主周期,与刺激的节拍做对照
import numpy as np
def dominant_period(signal, fps: int = 100):
x = signal - signal.mean()
f = np.fft.rfftfreq(len(x), d=1.0 / fps)
p = np.abs(np.fft.rfft(x))
p[0] = 0
band = (f > 0.1) & (f < 5.0)
if not band.any():
return float("nan")
return float(1.0 / f[band][np.argmax(p[band])])
seg = slice_participant(df, 1, 4)
print("竖直主周期(秒)", round(dominant_period(seg.z.to_numpy()), 3))
#-- 任务三:按段位配对,避免顺序效应混入条件比较
import itertools
def paired_by_slot(tidy, cond_a: str, cond_b: str):
rows = []
for (sid, pid), g in tidy.groupby(["session", "pid"]):
a = g[g.cond == cond_a]
b = g[g.cond == cond_b]
if len(a) and len(b):
for _, ra in a.iterrows():
for _, rb in b.iterrows():
rows.append({"session": sid, "pid": pid,
"slot_a": ra.seg, "slot_b": rb.seg,
"diff": rb.qom - ra.qom})
return pd.DataFrame(rows)
pairs = paired_by_slot(tidy, "A", "D")
print(pairs.groupby("slot_b")["diff"].agg(["count", "median"]).round(1))
这三段代码对应三类常见任务:整理成建模友好的长表、找主周期、做配对比较。第三段特意按段位分组输出,就是为了让使用者看见段位不同带来的差异,而不是把它平均掉。
附录 E:如果只记五件事
- 它测的是头顶一个反光点的三维位置,一百赫兹,毫米,六分钟,不是全身动作。
- 一百零八人分十二组,多人同场是它最稀缺的属性,人际同步只能在这里做。
- 静默是正式条件,不是休息,每一次记录都自带对照。
- 没有情绪标注、没有力台、没有患者,这三样缺任何一样都可能让你的题目落空。
- 它与 body-sway-music-vr 的关系是「同一问题的两种测量面」,不是替代关系。
编辑说明
本篇按数据集百科体例撰写,数字分三层交代:官方页面原样抄录、官方文件直接读出、论文摘要转述、未核实项单独列出。全篇不下载全量包做分布统计,示例代码基于单场次文件演示读取与分析路径,读者可自行扩展到十二个场次。与库内 body-sway-music-vr、multimodal-nback-music、music-sudden-cardiac-death 三个同域条目的区隔已核对标题与定位,详见 §6.1。核验时间 2026 年 10 月 28 日,对应 PhysioNet v1.0;若官方后续发布新版本,§2.1 的文件清单与 §7.1 的可维护性评分应同步复核。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- mouse-stroke-cylinder-rearing — 共享标签:生理信号 / 步态与运动 / 神经科学
- ninapro — 共享标签:生理信号 / 步态与运动 / 神经科学
- ua-speech — 共享标签:生理信号 / 步态与运动 / 神经科学
- gaitpdb — 共享标签:生理信号 / 步态与运动 / 神经科学
- umwdb — 共享标签:生理信号 / 步态与运动
- music-motion-2012 — 共享标签:生理信号 / 步态与运动
- emgdb — 共享标签:生理信号 / 神经科学
- hbedb — 共享标签:生理信号 / 步态与运动
- sgamp — 共享标签:生理信号 / 神经科学
- tremordb — 共享标签:生理信号 / 神经科学
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

