返回课程总览

实验 06 · MATLAB 过渡

MATLAB 数据处理入门

在熟悉的数据集上复现 Python 计算、结果表和可视化,学习 MATLAB 的脚本、向量、索引和逐元素运算。

完整讲义

Lab 06:MATLAB 数据处理入门

Lab 5 已经用 Python 处理数据集 [2, 4, 5, 7, 11, 13],并得到一组可以手算核对的结果。 本实验使用同一数据集、同一组统计量和同一种三分面可视化,只改变编程语言,不改变数学问题。 这样遇到差异时,可以先检查 MATLAB 写法,而不必同时猜测新的数学模型。

开始前复用 Lab 4 的 Git 检查点流程:用 git status 确认工作区干净;完成 Python 与 MATLAB 的结果对照后,按相同方法提交 Lab 6 检查点。

学习目标

  • 区分 MATLAB 的 Command Window、脚本、工作区和磁盘文件。
  • 用行向量保存一组数据,并理解 MATLAB 从 1 开始的数组索引。
  • 区分矩阵乘法与逐元素乘法,正确计算中心化值和平方偏差。
  • 由一个脚本生成 CSV、图像和可复查的实验记录。
  • 使用已知答案和 OpenCode 审计检查程序,而不是让工具替代数学判断。

从 Python 数据项目过渡到 MATLAB

MATLAB 打开后,最常用的三个部分承担不同职责:

部分 适合做什么 是否会自动保留
Command Window 试算一两条表达式、查看变量、调用脚本 输入历史可能保留,但不是项目源文件
.m 脚本 按固定顺序记录完整计算过程 保存在磁盘上,可以重复运行
工作区 保存当前 MATLAB 会话中的变量 clear 或关闭 MATLAB 后消失

Command Window 类似此前使用 Python 交互命令时的临时试算区,脚本则对应项目中的 .py 文件。可复现实验应以脚本为准:即使清空工作区,重新运行脚本也应得到相同的 CSV 和图像。

先在 Command Window 输入:

values = [2, 4, 5, 7, 11, 13];
values(1)
mean(values)

values 是包含六个元素的行向量。values(1) 得到 2:Python 从 0 开始计数, MATLAB 从 1 开始计数。圆括号用于访问数组元素,方括号用于构造数组。

Python MATLAB 含义
values[0] values(1) 第一个元素
len(values) numel(values) 元素个数
sum(values) sum(values) 元素总和
sum(values) / len(values) mean(values) 算术平均值
[x - mean_value for x in values] values - valueMean 每个元素减去同一标量
[x**2 for x in centered] centeredValues .^ 2 每个元素分别平方

最后两行体现 MATLAB 对数组运算的直接支持。这里的“向量化”不是改变数学问题,而是用一个 数组表达式描述对全部元素执行的同一种运算。

目录结构

在现有课程项目中创建如下结构。只从 Starter 压缩包复制 .m 源文件;results/figures/ 中的文件应由脚本生成。

labs/lab06/
  matlab_data_summary.m
  results/
    matlab-summary.csv
  figures/
    matlab-data-summary.png
  notes.md

可以从课程总览下载 Starter 文件,只把 starters/lab06/matlab_data_summary.m 复制到当前实验目录。

小知识:MATLAB 原本是 Matrix Laboratory

MATLAB 的名字来自 “matrix laboratory”。它最初是为了让矩阵计算更容易使用,因此数组和 线性代数运算直接进入了语言设计。这个背景也解释了为什么 * 默认表示矩阵乘法,而逐元素 运算需要写成 .*./.^

已知结果与 MATLAB 表达式

记六个数据为 \(v_1,\ldots,v_6\),其平均值为

\[ \bar v=\frac{1}{6}\sum_{i=1}^{6}v_i. \]

中心化值和平方偏差分别定义为

\[ c_i=v_i-\bar v,\qquad d_i=c_i^2. \]

Lab 5 已经给出本实验的检查答案:

  • 个数是 6,总和是 42,平均值是 7
  • 最小值是 2,最大值是 13
  • 中心化值是 [-5, -3, -2, 0, 4, 6]
  • 平方偏差是 [25, 9, 4, 0, 16, 36]
  • 平方偏差和是 90
  • 平均平方偏差是 15

平均平方偏差在本实验中定义为

\[ \frac{1}{6}\sum_{i=1}^{6}(v_i-\bar v)^2. \]

这里除以数据个数 6,不是除以 5。它是这组有限数据的平均平方偏差,不是在估计统计学 中的无偏样本方差。

公式到代码

Starter 已经定义原始数据和基本统计量:

values = [2, 4, 5, 7, 11, 13];

valueCount = numel(values);
valueTotal = sum(values);
valueMean = mean(values);
valueMinimum = min(values);
valueMaximum = max(values);

需要完成的两条核心表达式是:

centeredValues = values - valueMean;
squaredDeviations = centeredValues .^ 2;

点号决定运算作用于整个数组时采用什么规则:

  • A * B 是矩阵乘法,要求内部维数相容;
  • A .* B 是对应位置逐元素乘法,通常要求数组形状相同;
  • A ^ 2 是方阵的矩阵幂;
  • A .^ 2 是每个元素分别平方。

因此平方偏差必须使用 .^ 2。若把行向量写成 centeredValues ^ 2,MATLAB 会报告矩阵 不是方阵;若写成 centeredValues * centeredValues',会得到一个内积标量 90,但会 丢失六个单独的平方偏差。错误信息和“看似正确的单个数值”都需要结合预期数组形状判断。

脚本使用 mfilename("fullpath") 找到自身目录,再用 fullfile 生成输出路径。这样从 MATLAB 的 Run 按钮或 Command Window 调用脚本时,结果都会写到同一位置:

values
  ├─ 基本统计量 ───────────────┐
  ├─ centeredValues            ├─ matlab-summary.csv
  └─ squaredDeviations ────────┘
             │
             └─────────────────── matlab-data-summary.png

MATLAB 实验

  1. 在 MATLAB 的 Files 面板中打开 labs/lab06/,再打开 matlab_data_summary.m
  2. 直接运行一次 Starter,观察尚未完成的 TODO 如何使中心化值和平方偏差暂时成为零。
  3. 在 Command Window 使用 size(values)values(1)values(end) 检查向量形状与边界元素。
  4. 完成 centeredValuessquaredDeviations 两行代码,并重新计算平方偏差和与平均平方偏差。
  5. 运行完整脚本,检查 results/matlab-summary.csv 是否包含全部统计量。
  6. 打开 figures/matlab-data-summary.png,检查三个分面是否分别显示原始值、中心化值和平方偏差。
  7. 执行 clear,再次运行脚本,确认结果不依赖旧工作区变量。

修改代码后不要只查看图像。先检查数组和统计量,再检查表格,最后检查图像;这个顺序能更快 定位错误来自计算、导出还是绘图。

数学验证

至少完成以下检查:

检查 MATLAB 表达式 预期结果
数据形状 size(values) 1 × 6
中心化恒等式 sum(centeredValues) 接近 0
平方偏差非负 all(squaredDeviations >= 0) 逻辑真
平方偏差和 sum(squaredDeviations) 90
平均平方偏差 mean(squaredDeviations) 15

中心化值相加为零来自平均值定义:

\[ \sum_{i=1}^{6}(v_i-\bar v) =\sum_{i=1}^{6}v_i-6\bar v =42-6\times7=0. \]

再把 MATLAB 的 matlab-summary.csv 与 Lab 5 的 results.txt 逐项对照。两种语言得到相同 结果,并不意味着任意程序都正确;它只是在已知数据和已知公式下提供一条可重复的交叉检查。

结果与记录

notes.md 中记录:

  • Command Window、脚本和工作区各自承担什么角色;
  • 为什么本实验使用 .^ 2 而不是 ^ 2
  • CSV 中的统计量是否与 Lab 5 完全一致;
  • 三分面图是否保留了每组量各自的纵轴;
  • 一个实际遇到的 MATLAB 错误,以及你如何根据数组形状定位它。

图注可以写成:

> 同一数据集的原始值、中心化值和平方偏差。MATLAB 统计量与 Lab 5 的 Python 结果一致。

OpenCode 审计

输入 /models,确认当前模型是 DeepSeek V4 Pro。按 Tab 进入 Plan 模式,让 OpenCode 先检查而不修改文件:

请检查 labs/lab06/matlab_data_summary.m。

已知数据是 [2, 4, 5, 7, 11, 13],平均值是 7,平方偏差和是 90。
请完成以下工作:
1. 逐行说明脚本中的数组形状,以及公式如何对应 MATLAB 表达式;
2. 检查中心化和平方偏差是否使用了正确的逐元素运算;
3. 检查 CSV 和三分面图是否完全由脚本生成;
4. 指出一个可能产生“数值看似正确但形状错误”的写法;
5. 只提出必要修改,不改变数据集和输出文件名。

先核对 OpenCode 是否给出正确的预期值和数组形状,再按 Tab 进入 Build 模式实施必要 修改。在 VS Code 的 PowerShell 终端运行 git statusgit diff -- labs\lab06, 逐项判断改动是否保留。

完成标准

  • 清空工作区后,脚本仍能从头生成 CSV 和图像。
  • CSV 中的个数、总和、平均值、极值、平方偏差和与 Lab 5 一致。
  • 能解释 *.*^.^ 的区别。
  • 能说明为什么 values(1) 是第一个元素。
  • notes.md 记录了人工检查和一次 OpenCode 建议取舍。
  • 提交 Lab 6 检查点后,git status 显示工作区干净。

下一实验会保留 MATLAB 脚本、数组形状、结果导出和人工验证工作流,把一组独立数据改为会随 时间递推的二维状态。新的数学问题从 Lab 7 开始引入。