3. MATLAB调用Python机器学习模型进行预测
任务拆解与互操作链路
本案例要打通一条“Python 训练 → 模型落盘 → MATLAB 加载 → 新样本预测”的最小闭环。关键约束有三点:第一,模型必须保存为 MATLAB 能直接读取的格式,最稳妥的选择是 .mat(通过 SciPy 的 savemat 写出),避免依赖 MATLAB 对 pickle 或 joblib 的间接支持;第二,MATLAB 侧只负责“加载参数 + 前向计算”,不重新训练,从而真正验证互操作而非重复建模;第三,输入特征顺序、标准化参数、系数排列必须在两侧严格一致,否则预测值会静默偏移。
Python 侧:训练并导出为 .mat
用 numpy 生成可复现的合成数据,训练标准化 + 线性回归,然后把四个数值数组写入 .mat。注意 savemat 默认按列优先存储,MATLAB 读入后是列向量,后续前向计算要按列向量处理。
# train_export.py
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from scipy.io import savemat
rng = np.random.default_rng(42)
X = rng.normal(size=(80, 3))
y = 2.5*X[:,0] - 1.2*X[:,1] + 0.8*X[:,2] + 4.0 + rng.normal(scale=0.1, size=80)
scaler = StandardScaler().fit(X)
Xs = scaler.transform(X)
model = LinearRegression().fit(Xs, y)
savemat("model.mat", {
"coef": model.coef_.reshape(-1, 1), # 3×1
"intercept": np.array([[model.intercept_]]),
"mean": scaler.mean_.reshape(-1, 1), # 3×1
"scale": scaler.scale_.reshape(-1, 1), # 3×1
})
# 留一份参考预测,供 MATLAB 侧比对
Xnew = np.array([[0.5, -1.0, 2.0],
[-0.3, 0.8, -1.5]])
yhat_py = model.predict(scaler.transform(Xnew))
np.savetxt("yhat_py.txt", yhat_py)
print("coef =", model.coef_)
print("intercept =", model.intercept_)
print("yhat_py =", yhat_py)
运行后应得到 model.mat 与 yhat_py.txt。示例数据下 coef 约为 [2.49, -1.19, 0.79],intercept 约为 4.00,具体数值以实际运行输出为准。
MATLAB 侧:加载参数并做前向计算
MATLAB 不重新训练,只复现“标准化 + 线性组合”两步。由于 coef、mean、scale 读入后是 3×1 列向量,用 Xnew * coef 即可得到 2×1 的预测列向量。
% predict_matlab.m
clear; clc;
S = load('model.mat');
coef = S.coef; intercept = S.intercept;
mu = S.mean; sd = S.scale;
Xnew = [0.5, -1.0, 2.0;
-0.3, 0.8, -1.5];
Z = (Xnew - mu') ./ sd'; % 按列广播标准化
yhat = Z * coef + intercept; % 2×1
yhat_py = readmatrix('yhat_py.txt');
diff = abs(yhat - yhat_py);
fprintf('MATLAB 预测: %.6f, %.6f\n', yhat(1), yhat(2));
fprintf('Python 预测: %.6f, %.6f\n', yhat_py(1), yhat_py(2));
fprintf('最大绝对偏差: %.3e\n', max(diff));
assert(max(diff) < 1e-10, '互操作校验失败');
若 MATLAB 侧报“矩阵维度不一致”,优先检查
mu、sd 是否为列向量。用 mu' 转成行向量再与 Xnew 相减,可避免隐式扩展方向错误。结果判读与常见偏差
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 预测值整体偏移一个常数 | intercept 未加或加了两次 | 确认公式为 Z*coef + intercept |
| 偏差随特征量级放大 | 标准化参数方向或顺序错位 | 核对 mean/scale 与特征列一一对应 |
| 偏差约 1e-2 量级 | MATLAB 侧误用了未标准化输入 | 先做 (Xnew-mu')./sd' 再乘系数 |
load 后变量名不符 | savemat 键名与 MATLAB 变量名不一致 | 统一使用 coef/intercept/mean/scale |
通过条件是两侧预测的最大绝对偏差小于 1e-10。该阈值对双精度浮点运算足够严格,能有效暴露参数错位、漏加截距或标准化遗漏等问题,同时不会因正常舍入误差误报。