如何分析实验数据?¶
⚠️ 正在开发中: 本指南正在积极开发中,将扩展更多详细示例和工作流程。内容可能在未来版本中更新。
目标: 在本指南结束时,您将了解如何将 CANN 分析工具应用于实验神经数据。
预计阅读时间: 10 分钟
介绍¶
前一个指南展示了如何分析模型生成的数据。但如果您有真实的实验记录——神经脉冲列车、行为轨迹或来自训练模型的 RNN 动力学呢?
数据分析器提供工具来应用 CANN 启发的分析到实验数据,帮助您:
检测神经记录中的吸引子样活动模式
将凸起模型拟合到群体活动
对时间序列执行拓扑数据分析 (TDA)
分析 RNN 不动点和缓慢流形
与模型分析的关键差异: 您从观察到的数据开始,而不是模拟输出。工作流从根本上是不同的。
实验数据分析工作流¶
与您可以控制一切的模型模拟不同,分析实验数据遵循这种模式:
加载数据 → 预处理/格式化 → 应用分析 → 可视化结果
让我们通过一个具体的例子来演练这个过程。
示例: 1D 凸起拟合¶
最常见的分析是凸起拟合——检测和跟踪神经群体数据中的局部活动凸起。
第 1 步: 加载示例数据¶
该库通过 canns.data 提供示例数据集:
[ ]:
from canns.data import load_example_data
# 加载示例 1D 神经活动数据
data_dict = load_example_data('bump_1d_example')
print(f"可用键: {data_dict.keys()}")
print(f"活动形状: {data_dict['activity'].shape}")
print(f"时间点: {data_dict['time'].shape}")
预期输出:
可用键: dict_keys(['activity', 'time', 'positions'])
活动形状: (500, 128) # 500 个时间点,128 个神经元
时间点: (500,)
数据结构:
activity: 神经放电率或脉冲计数(时间 × 神经元)time: 每个样本的时间戳positions: 神经元的空间位置(如果可用)
第 2 步: 检查数据¶
在分析之前,可视化原始数据:
[ ]:
import matplotlib.pyplot as plt
import jax.numpy as jnp
# 绘制活动热图
plt.figure(figsize=(10, 4))
plt.imshow(data_dict['activity'].T, aspect='auto', cmap='viridis')
plt.xlabel('时间步')
plt.ylabel('神经元索引')
plt.title('神经群体活动')
plt.colorbar(label='活动')
plt.show()
# 绘制一个时间点的活动
plt.figure(figsize=(8, 3))
plt.plot(data_dict['positions'], data_dict['activity'][100])
plt.xlabel('位置 (rad)')
plt.ylabel('活动')
plt.title('t=100 处的活动快照')
plt.grid(True)
plt.show()
要查找的内容:
您是否看到局部活动凸起?
它们随时间移动吗?
有多个凸起还是只有一个?
第 3 步: 应用凸起拟合¶
现在使用数据分析器来拟合凸起模型:
[ ]:
from canns.analyzer.data import BumpAnalyzer1D
# 创建分析器
analyzer = BumpAnalyzer1D(positions=data_dict['positions'])
# 将凸起拟合到所有时间点
results = analyzer.fit_bumps(data_dict['activity'])
print(f"检测到的凸起中心: {results['centers'][:10]}") # 前 10 个
print(f"凸起宽度: {results['widths'][:10]}")
print(f"凸起振幅: {results['amplitudes'][:10]}")
结果字典包含:
centers: 每个时间点的估计凸起中心位置widths: 凸起宽度(空间展度)amplitudes: 凸起峰值高度fit_quality: R² 或拟合优度指标
第 4 步: 可视化拟合凸起¶
绘制检测到的凸起轨迹:
[ ]:
plt.figure(figsize=(10, 4))
plt.plot(data_dict['time'], results['centers'], linewidth=2)
plt.xlabel('时间 (ms)')
plt.ylabel('凸起位置 (rad)')
plt.title('解码凸起轨迹')
plt.grid(True)
plt.show()
# 绘制凸起宽度随时间的变化
plt.figure(figsize=(10, 4))
plt.plot(data_dict['time'], results['widths'], linewidth=2, color='orange')
plt.xlabel('时间 (ms)')
plt.ylabel('凸起宽度 (rad)')
plt.title('凸起宽度动力学')
plt.grid(True)
plt.show()
解释:
稳定的凸起位置 → 稳定的吸引子状态
光滑轨迹 → 连续跟踪
变化的宽度 → 动态调节或状态转换
第 5 步: 验证拟合¶
检查拟合的质量:
[ ]:
# 绘制拟合质量随时间的变化
plt.figure(figsize=(10, 4))
plt.plot(data_dict['time'], results['fit_quality'], linewidth=2)
plt.axhline(y=0.8, color='r', linestyle='--', label='质量阈值')
plt.xlabel('时间 (ms)')
plt.ylabel('拟合质量 (R²)')
plt.title('凸起拟合质量')
plt.legend()
plt.grid(True)
plt.show()
# 识别低质量拟合
low_quality_indices = jnp.where(results['fit_quality'] < 0.8)[0]
print(f"拟合质量差的时间点: {len(low_quality_indices)} / {len(data_dict['time'])}")
低质量拟合可能表示:
没有清晰的凸起存在
多个重叠的凸起
嘈杂或不可靠的数据
完整工作流示例¶
这是完整的管道:
[ ]:
from canns.data import load_example_data
from canns.analyzer.data import BumpAnalyzer1D
import matplotlib.pyplot as plt
# 1. 加载数据
data = load_example_data('bump_1d_example')
# 2. 创建分析器
analyzer = BumpAnalyzer1D(positions=data['positions'])
# 3. 拟合凸起
results = analyzer.fit_bumps(data['activity'])
# 4. 可视化轨迹
plt.figure(figsize=(12, 6))
# 子图 1: 活动热图及拟合中心叠加
plt.subplot(2, 1, 1)
plt.imshow(data['activity'].T, aspect='auto', cmap='viridis', extent=[0, len(data['time']), data['positions'][0], data['positions'][-1]])
plt.plot(range(len(results['centers'])), results['centers'], 'r-', linewidth=2, label='拟合凸起中心')
plt.ylabel('位置 (rad)')
plt.title('带检测凸起轨迹的神经活动')
plt.legend()
plt.colorbar(label='活动')
# 子图 2: 凸起位置随时间的变化
plt.subplot(2, 1, 2)
plt.plot(data['time'], results['centers'], linewidth=2)
plt.xlabel('时间 (ms)')
plt.ylabel('凸起中心 (rad)')
plt.title('解码位置轨迹')
plt.grid(True)
plt.tight_layout()
plt.savefig('experimental_bump_analysis.png', dpi=150)
plt.show()
print("分析完成!结果已保存。")
其他数据分析工具¶
除了凸起拟合,数据分析器还提供:
拓扑数据分析 (TDA)¶
[ ]:
from canns.analyzer.data import TopologyAnalyzer
# 分析神经动力学中的拓扑特征
tda = TopologyAnalyzer()
persistence = tda.compute_persistence(data['activity'])
用例: 检测高维活动中的环形或环面结构
RNN 动力学分析¶
[ ]:
from canns.analyzer.data import RNNAnalyzer
# 在训练的 RNN 模型中找到不动点和缓慢流形
rnn_analyzer = RNNAnalyzer(model=my_rnn)
fixed_points = rnn_analyzer.find_fixed_points()
用例: 理解训练递归网络的计算结构
关键差异: 模型分析 vs 实验数据分析¶
方面 |
模型分析 |
实验数据分析 |
|---|---|---|
输入 |
模拟输出 |
神经记录,轨迹 |
控制 |
完全控制(参数,输入) |
仅观察 |
目标 |
验证模型行为 |
发现数据中的模式 |
挑战 |
参数调节 |
噪声,缺失数据,伪影 |
工作流 |
模拟 → 分析 |
加载 → 预处理 → 分析 |
何时使用各种方法:
模型分析: 测试假设,探索参数空间,验证实现
数据分析: 解释实验,检测记录中的吸引子,比较模型与生物学
加载您自己的数据¶
要分析您自己的实验数据:
[ ]:
import jax.numpy as jnp
# 从 numpy 数组,CSV 或其他格式加载
my_activity = jnp.load('my_experiment.npy') # 形状: (time, neurons)
my_positions = jnp.linspace(-3.14, 3.14, num_neurons)
# 使用您的神经元位置创建分析器
analyzer = BumpAnalyzer1D(positions=my_positions)
# 分析
results = analyzer.fit_bumps(my_activity)
数据要求:
活动应为
(time_points, num_neurons)形状位置应匹配神经元数量
值应为非负数(放电率或脉冲计数)
常见问题¶
问: 我的数据有缺失值或 NaN
在分析前进行预处理:
[ ]:
import jax.numpy as jnp
# 移除包含 NaN 的行
valid_indices = ~jnp.isnan(activity).any(axis=1)
clean_activity = activity[valid_indices]
问: 结果没有意义
检查这些:
数据单位(放电率是 Hz 还是归一化的?)
位置范围(应匹配神经元布局,例如角度为 -π 到 π)
活动形状(
(time, neurons)而不是(neurons, time))
问: 拟合质量总是很低
可能的原因:
数据中没有清晰的凸起结构
需要调整凸起模型参数
数据太嘈杂(先尝试平滑)
后续步骤¶
现在您可以分析实验数据了!继续学习:
训练脑启发模型 - 学习记忆网络的海布学习
核心概念: 数据分析器 - 深入了解分析方法
完整 API 参考: 数据分析器 - 所有分析工具的完整文档
快速参考:
[ ]:
# 实验数据分析模板
from canns.data import load_example_data
from canns.analyzer.data import BumpAnalyzer1D
# 加载数据
data = load_example_data('bump_1d_example')
# 分析
analyzer = BumpAnalyzer1D(positions=data['positions'])
results = analyzer.fit_bumps(data['activity'])
# 可视化
plt.plot(data['time'], results['centers'])
📝 欢迎反馈: 本指南正在积极完善中。如果您有本指南未涉及的实验数据分析用例,请在 GitHub Discussions 中分享!
有问题?查看*`核心概念: 数据分析器 <link>`__*或*`GitHub Discussions <https://github.com/routhleck/canns/discussions>`__*。