当前位置: 首页 > news >正文

MATLAB数学建模核心技能:从数据预处理到模型求解的完整指南

1. 项目概述:当数学建模遇上MATLAB

如果你正在准备数学建模竞赛,或者你的课程、科研项目里涉及到需要将现实问题转化为数学模型并求解,那么“MATLAB在数学建模中的应用”这个话题,对你来说绝对是个绕不开的坎。我自己从学生时代参加国赛、美赛,到后来带学生团队,MATLAB几乎是我处理所有建模、仿真和数据分析问题的“瑞士军刀”。很多人觉得MATLAB就是个高级计算器,画图工具,但真正深入数学建模这个领域,你会发现它的价值远不止于此——它是一个完整的、从问题抽象到结果可视化的解决方案环境。

这篇内容,我们就聚焦在“常规方法”上。什么叫常规方法?它不是指那些高深莫测的最前沿算法,而是指在绝大多数数学建模问题中,你最可能用到、最应该优先掌握的MATLAB核心技能。比如,你拿到一个数据集要分析趋势,遇到一个方程要求解,或者建好模型后需要直观地展示结果,这些环节都需要扎实的常规操作打底。掌握了这些,你才能高效地把脑海里的模型“翻译”成计算机能执行的代码,而不是在语法和函数调用上卡半天。说白了,这就是数学建模的“硬通货”,是让你从“有想法”到“出结果”的关键桥梁。无论你是刚入门的新手,还是想梳理知识体系的进阶者,这些内容都能帮你构建一个坚实可靠的工具箱。

2. 数学建模流程与MATLAB工具箱定位

在深入具体函数之前,我们必须先建立起一个宏观的认知:MATLAB是如何嵌入到整个数学建模流程中的。一个完整的数学建模周期,通常包括问题理解与抽象、模型假设与建立、模型求解与分析、结果验证与报告这几个阶段。MATLAB的威力在于,它为几乎每个阶段都提供了强大的支持。

2.1 从问题到代码的思维转换

很多新手最大的障碍不是不会写代码,而是不知道如何把一个问题描述转化成一行行MATLAB命令。比如,问题说“预测未来三年的销量”,你的思维应该立刻拆解:这可能需要数据拟合(Curve Fitting)时间序列分析(Time Series)。问题提到“寻找最优的物资分配方案”,这指向了优化(Optimization)问题。问题涉及“几个因素之间相互影响的关系”,这很可能需要回归分析(Regression)系统仿真(Simulation)

MATLAB的优势就在于,它将这些常见的数学建模任务封装成了直观的函数或工具箱。你不需要从零开始编写最小二乘法的迭代代码,只需要调用fitpolyfit函数;你也不需要手动实现复杂的优化算法,fminconlinprog这些求解器已经为你准备好了。你的核心任务,是正确地定义问题(例如,目标函数是什么,约束条件有哪些),然后选择合适的MATLAB工具来求解。这种“问题-工具”的映射能力,是数学建模的核心素养之一。

2.2 核心工具箱巡礼

MATLAB拥有数十个面向不同领域的工具箱,对于数学建模,以下几个是重中之重:

  1. 统计和机器学习工具箱(Statistics and Machine Learning Toolbox):这是数据分析的基石。包含描述性统计、假设检验(如t检验、方差分析)、回归分析、聚类、分类等。你提到的ttestttest2就来自这里。
  2. 优化工具箱(Optimization Toolbox):解决线性规划、非线性规划、整数规划、最小二乘等各类优化问题的利器。无论是资源分配、路径规划还是参数估计,都离不开它。
  3. 曲线拟合工具箱(Curve Fitting Toolbox):提供图形化界面和丰富的函数库,用于进行数据拟合、插值、平滑处理,帮助你找到数据背后的函数关系。
  4. 全局优化工具箱(Global Optimization Toolbox):当你的优化问题可能存在多个局部最优解时,这个工具箱提供了遗传算法、模拟退火、粒子群等全局搜索算法。
  5. 符号数学工具箱(Symbolic Math Toolbox):可以进行公式推导、符号计算、求导、积分、解方程等。在模型建立阶段进行理论推导时非常有用。

注意:并非所有函数都需要工具箱。像矩阵运算(inv,eig)、基础绘图(plot,scatter)、数值积分(integral)等核心功能,是MATLAB基础版自带的。通常,以大学为单位购买的校园许可证会包含大部分常用工具箱。在动手前,可以用ver命令查看已安装的工具箱列表。

3. 数据预处理与可视化:建模的基石

在建模之前,数据往往是一团乱麻。缺失值、异常值、量纲不统一等问题会严重影响模型质量。同时,可视化是理解数据和呈现结果不可或缺的一步。MATLAB在这两方面提供了极其便捷的操作。

3.1 数据导入与清洗

数据通常来自Excel(.xls,.xlsx)、文本文件(.txt,.csv)或数据库。MATLAB的readtable函数是处理表格数据的首选,它能智能识别数据类型,并将数据存储为便于操作的table变量。

% 导入CSV文件 data = readtable('your_data.csv'); % 查看数据前几行和基本信息 head(data) summary(data)

数据清洗的常见操作包括:

  • 处理缺失值ismissing函数查找缺失值(在MATLAB中通常表示为NaN)。你可以选择删除缺失行(rmmissing),或用均值、中位数填充(fillmissing)。
    % 删除包含缺失值的行 data_clean = rmmissing(data); % 用列均值填充缺失值 data_filled = fillmissing(data, 'constant', mean(data, 'omitnan'));
  • 处理异常值:常用方法是基于标准差或分位数(如IQR)进行识别和剔除。isoutlier函数可以辅助完成。
    % 识别基于分位数的异常值 TF = isoutlier(data.Height, 'quartiles'); % 剔除异常值所在行 data_no_outlier = data(~TF, :);
  • 数据标准化/归一化:当特征量纲差异巨大时(如年龄和收入),必须进行标准化。zscore函数实现Z-score标准化,mapminmax函数(需Deep Learning Toolbox)或手动计算实现最大最小归一化。
    % Z-score标准化 data_standardized = zscore(table2array(data(:, 1:5))); % 对前5列数值型数据标准化

3.2 探索性可视化

“一图胜千言”。在建模前,通过图形探索数据分布、关系和趋势至关重要。

  • 单变量分布:使用直方图(histogram)和箱线图(boxplot)。
    subplot(1,2,1); histogram(data.Height, 'BinWidth', 2); title('身高分布直方图'); xlabel('身高(cm)'); ylabel('频数'); subplot(1,2,2); boxplot(data.Height); title('身高箱线图'); ylabel('身高(cm)');
  • 双变量关系:散点图(scatter)是看相关性的首选。对于分类变量,可以使用分组散点图或gscatter
    scatter(data.Weight, data.Height, 'filled'); xlabel('体重(kg)'); ylabel('身高(cm)'); title('体重与身高关系散点图'); % 添加趋势线 hold on; p = polyfit(data.Weight, data.Height, 1); yfit = polyval(p, data.Weight); plot(data.Weight, yfit, 'r-', 'LineWidth', 2); legend('数据点', '线性趋势线');
  • 多变量关系:散点图矩阵(plotmatrix)可以一次性查看多个变量两两之间的关系。
    % 假设data中有Height, Weight, Age三列 figure; [S,AX,BigAx,H,HAx] = plotmatrix(table2array(data(:,{'Height','Weight','Age'}))); title('散点图矩阵');

实操心得:在竞赛或项目中,我习惯将数据导入、清洗和基础可视化的代码写在一个独立的脚本文件(如data_preprocessing.m)中。这样不仅流程清晰,方便复查,当数据源更新时,只需重新运行这个脚本即可得到干净的数据,极大提高了可重复性和效率。

4. 核心建模方法一:统计分析与假设检验

统计方法是数学建模中用于分析数据、检验假设、建立预测关系的核心手段。这里我们深入两个最常用的场景:t检验和回归分析。

4.1 假设检验实战:ttest与ttest2详解

你搜索的热词中提到了ttestttest2的区别,这确实是一个高频考点和易错点。它们的核心区别在于样本类型

  • ttest(单样本或配对样本t检验)

    • 单样本t检验:检验一组数据的均值是否等于某个理论值。例如,检验一批产品的平均直径是否为10mm。
      data_sample = [10.1, 9.8, 10.2, 9.9, 10.0]; [h, p, ci, stats] = ttest(data_sample, 10); % 检验均值是否为10 % h=0表示不拒绝原假设(均值可能为10),p是p值,ci是置信区间
    • 配对样本t检验:检验两组配对数据的差值均值是否为零。例如,同一组病人服药前和服药后的血压测量值。
      before = [120, 125, 118, 122, 130]; after = [115, 120, 116, 119, 125]; [h, p] = ttest(before, after); % 默认进行配对t检验
  • ttest2(双独立样本t检验)

    • 检验两组独立数据的均值是否相等。例如,检验两种不同教学方法下,两个班级学生的平均成绩是否有显著差异。要求两组数据相互独立,且通常假设方差齐性
      group_a = [78, 85, 92, 88, 76]; group_b = [82, 90, 85, 79, 95, 88]; [h, p, ci, stats] = ttest2(group_a, group_b); % 如果怀疑方差不齐,可以使用 'Vartype', 'unequal' 参数 [h2, p2] = ttest2(group_a, group_b, 'Vartype', 'unequal');

关键决策流程

  1. 你的数据是一组还是两组
  2. 如果是两组,这两组数据是配对的(如同一对象前后测量)还是独立的(如不同班级的学生)?
  3. 根据答案选择ttest(单组或配对)或ttest2(独立双样本)。

4.2 回归分析:从线性到非线性

回归分析用于量化一个或多个自变量(X)与因变量(Y)之间的关系。

  • 线性回归:最基础也最常用。使用fitlm函数。

    % 假设data中有变量Y, X1, X2 mdl = fitlm(data, 'Y ~ X1 + X2'); % 建立Y关于X1和X2的线性模型 disp(mdl); % 查看模型摘要,包括R方、系数估计、p值等 figure; plotResiduals(mdl, 'fitted'); % 绘制残差图,检查模型假设(如异方差性)

    fitlm输出的模型对象mdl包含了极其丰富的信息。mdl.Coefficients给出了每个系数的估计值、标准误、t统计量和p值,这是判断变量是否显著的关键。mdl.Rsquared反映了模型的拟合优度。

  • 多项式回归:当关系非线性但形式已知时,可用polyfitpolyval

    x = data.X; y = data.Y; p = polyfit(x, y, 3); % 进行3次多项式拟合 y_fit = polyval(p, x); % 计算拟合值 plot(x, y, 'o', x, y_fit, '-'); legend('原始数据', '三次多项式拟合');
  • 非线性回归:对于更复杂的非线性关系,可以使用fit函数配合拟合类型,或fitnlm函数(非线性模型拟合)。

    % 使用fit函数,假设是指数衰减模型 y = a*exp(b*x) ft = fittype('a*exp(b*x)', 'independent', 'x', 'dependent', 'y'); [fitresult, gof] = fit(x, y, ft, 'StartPoint', [1, -0.1]); plot(fitresult, x, y);

注意事项:进行回归分析后,务必进行残差分析。残差应该随机分布,不应有任何明显的模式(如弯曲、漏斗形)。如果残差图显示模式,说明模型可能遗漏了重要变量、函数形式错误或存在异方差性,需要改进模型。

5. 核心建模方法二:优化与规划求解

优化问题在数学建模中无处不在,如资源分配、路径规划、参数调优等。MATLAB的优化工具箱提供了统一的框架。

5.1 线性规划与整数规划

线性规划(目标函数和约束均为线性)使用linprog函数。其标准形式是:最小化 f*x,满足 A*x ≤ b, Aeq*x = beq, lb ≤ x ≤ ub

假设一个生产计划问题:生产产品A和B,利润分别为3和5,资源约束如下,求最大利润。

f = [-3; -5]; % 因为linprog默认求最小值,所以最大化要加负号 A = [1, 2; % 资源1消耗 4, 3; % 资源2消耗 2, 1]; % 资源3消耗 b = [10; 24; 12]; lb = [0; 0]; % 产量非负 [x, fval, exitflag] = linprog(f, A, b, [], [], lb); fprintf('最优生产计划:产品A生产 %.2f,产品B生产 %.2f\n', x(1), x(2)); fprintf('最大利润为:%.2f\n', -fval); % 注意取反

exitflag大于0表示求解成功。如果变量需要是整数(整数规划),需使用intlinprog函数,并指定整数变量的索引。

5.2 非线性规划与最小二乘

对于目标函数或约束非线性的问题,使用fmincon函数。这是应用最广泛的非线性局部优化求解器。

假设我们要最小化一个带有约束的非线性函数:

% 定义目标函数(通常写在一个单独的.m文件里) fun = @(x) exp(x(1))*(4*x(1)^2 + 2*x(2)^2 + 4*x(1)*x(2) + 2*x(2) + 1); % 初始点 x0 = [-1, 1]; % 线性不等式约束 A*x <= b A = []; b = []; % 线性等式约束 Aeq*x = beq Aeq = []; beq = []; % 变量上下界 lb = []; ub = []; % 非线性约束(定义在另一个函数中) nonlcon = @mycon; % mycon.m 文件定义了 c(x) <= 0 和 ceq(x) = 0 [x_opt, fval_opt] = fmincon(fun, x0, A, b, Aeq, beq, lb, ub, nonlcon);

非线性最小二乘是一种特殊的优化,目标是最小化误差的平方和,常用lsqnonlinlsqcurvefit。后者专门用于曲线拟合,接口更友好。

% 使用 lsqcurvefit 拟合非线性模型 y = a*sin(b*x+c) x_data = linspace(0, 2*pi, 50); y_data = 2.5*sin(1.8*x_data + 0.5) + 0.1*randn(size(x_data)); model = @(p, x) p(1)*sin(p(2)*x + p(3)); p0 = [1, 1, 0]; % 初始猜测 [p_opt, resnorm] = lsqcurvefit(model, p0, x_data, y_data);

实操心得:优化问题的求解极度依赖初始点。对于非凸问题,fmincon可能陷入局部最优解。一个实用的策略是:从多个随机初始点开始运行优化,选择结果最好的一个。这可以通过一个简单的循环实现。对于复杂问题,可以考虑使用全局优化工具箱中的算法。

6. 核心建模方法三:方程求解与数值计算

许多模型的最终形式归结为求解方程(组)或计算积分/微分。

6.1 方程(组)求解

  • 单变量非线性方程:使用fzero。你需要提供一个初始点或一个包含根的区间。
    fun = @(x) x^3 - 2*x - 5; x_sol = fzero(fun, 2); % 在初始点2附近寻找根 fprintf('方程的解为:%.6f\n', x_sol);
  • 多变量非线性方程组:使用fsolve。你需要提供一个初始点向量。
    % 求解方程组: % x^2 + y^2 = 4 % exp(x) + y = 1 fun_sys = @(z) [z(1)^2 + z(2)^2 - 4; exp(z(1)) + z(2) - 1]; z0 = [1; 1]; % 初始猜测 z_sol = fsolve(fun_sys, z0); fprintf('解为:x=%.6f, y=%.6f\n', z_sol(1), z_sol(2));

6.2 数值微积分

  • 数值积分integral函数是计算一维定积分的首选,它自适应选择步长,精度高。

    fun_int = @(x) sin(x)./x; q = integral(fun_int, 0, 10); fprintf('积分结果:%.10f\n', q);

    对于震荡函数或在无穷区间积分,可以使用integral的特殊选项,或考虑quadgk(高斯-克朗罗德积分)。

  • 数值微分:MATLAB没有直接的数值微分函数,因为数值微分容易受噪声影响而不稳定。通常建议:

    1. 如果函数表达式已知,优先使用符号工具箱求解析导。
    2. 如果只有数据点,可以使用gradient函数计算近似梯度,但要小心噪声。
      x = 0:0.1:2*pi; y = sin(x); dydx = gradient(y, x); % 计算dy/dx的近似值 plot(x, y, 'b-', x, dydx, 'r--'); legend('y = sin(x)', 'dy/dx (数值梯度)');

7. 模型验证、结果呈现与报告生成

模型建好、结果算出,并不等于工作结束。如何验证模型的可靠性,以及如何清晰、专业地呈现结果,同样至关重要。

7.1 模型验证与敏感性分析

  • 交叉验证:对于预测类模型(如回归、分类),防止过拟合的黄金法则是交叉验证。可以使用cvpartitioncrossval函数。
    % 创建一个10折交叉验证分区 cv = cvpartition(height(data), 'KFold', 10); mse_cv = zeros(cv.NumTestSets, 1); for i = 1:cv.NumTestSets trainIdx = training(cv, i); testIdx = test(cv, i); % 在训练集上训练模型 mdl_train = fitlm(data(trainIdx, :), 'Y ~ X1 + X2'); % 在测试集上预测并计算误差 y_pred = predict(mdl_train, data(testIdx, :)); mse_cv(i) = mean((data.Y(testIdx) - y_pred).^2); end fprintf('10折交叉验证平均MSE: %.4f\n', mean(mse_cv));
  • 敏感性分析:考察模型输出如何随输入参数的变化而变化。这有助于识别关键参数。一种简单的方法是进行单参数扰动分析。
    base_value = 10; param_range = linspace(base_value*0.5, base_value*1.5, 20); output = zeros(size(param_range)); for i = 1:length(param_range) % 将模型中的某个参数替换为 param_range(i),重新计算模型输出 % output(i) = your_model_function(param_range(i), ...); end plot(param_range, output, '-o'); xlabel('参数值'); ylabel('模型输出'); title('敏感性分析');

7.2 专业化图表与报告生成

MATLAB的绘图能力极其强大,远超基础plot

  • 多子图与排版:使用tiledlayoutnexttile可以创建复杂的多图布局,比传统的subplot更易控制间距和标题。
    figure; t = tiledlayout(2, 2); % 创建2x2的布局 title(t, '模型结果综合分析'); % 总标题 nexttile; scatter(data.X1, data.Y, 'filled'); title('散点图与拟合线'); % ... 其他绘图命令 nexttile; histogram(mdl.Residuals.Raw); title('残差分布'); % ... 以此类推
  • 三维与特殊图形:对于三维数据,使用plot3,scatter3,mesh,surf。等高线图contourcontourf适合展示二维函数。
  • 导出高质量图片:用于论文或报告的图片需要高分辨率。使用exportgraphics函数。
    fig = gcf; % 获取当前图形窗口 exportgraphics(fig, 'model_result.png', 'Resolution', 300); % 导出为300 DPI的PNG exportgraphics(fig, 'model_result.pdf', 'ContentType', 'vector'); % 导出为矢量PDF,无限清晰
  • 生成报告:MATLAB的publish功能可以将脚本(.m文件)直接发布为HTML、Word、PDF等格式的报告。只需在脚本中使用%%分节,并添加注释和标题,然后运行publish('your_script.m', 'pdf')。这对于快速生成包含代码、结果和图表的标准报告非常高效。

8. 常见问题与调试技巧实录

在实际操作中,你一定会遇到各种报错和意想不到的结果。这里记录几个最典型的问题和我的解决思路。

8.1 维度不匹配错误

这是MATLAB新手(甚至老手)最常见的错误之一。错误信息通常是“Matrix dimensions must agree”或“Inner matrix dimensions must agree”。

  • 原因与排查
    1. 矩阵运算:检查*(矩阵乘)、/\(矩阵左除右除)等操作两边的矩阵维度是否满足数学定义。记住*是矩阵乘法,而.*是元素对应相乘。
    2. 元素级运算:即使使用.*,./,也需要两边矩阵维度完全相同或满足广播规则。对于新手,建议先统一使用size()函数打印关键变量的维度。
    3. 函数输入:许多函数对输入向量的方向有要求。例如,polyfit(x, y, n)要求xy是相同长度的向量(行向量或列向量均可,但要一致)。如果x是行向量而y是列向量,就可能出错。使用x(:)y(:)可以将其强制转换为列向量。

8.2 优化或方程求解失败

fminconfsolve报错,或者exitflag不是正值。

  • 排查清单
    1. 初始点:尝试更换不同的初始点。对于复杂问题,随机生成多组初始点进行尝试是最有效的方法。
    2. 约束可行性:检查你给的初始点x0是否满足所有约束(特别是边界lb,ub和非线性约束)。一个不可行的初始点会导致求解器立即失败。可以编写一个检查函数来验证。
    3. 梯度信息:对于高度非线性或规模较大的问题,提供目标函数和约束的梯度(通过optimoptions设置SpecifyObjectiveGradientSpecifyConstraintGradienttrue)可以极大提高求解速度和稳定性。
    4. 算法选择fmincon有多种内点算法、序列二次规划算法等。通过optimoptions更改算法(如'Algorithm', 'sqp')有时能解决收敛问题。
    5. 容差调整:适当增大最优性容差(OptimalityTolerance)或约束违反容差(ConstraintTolerance)可能帮助收敛,但会牺牲精度。

8.3 绘图混乱或图形不显示

  • 图形窗口被覆盖:在脚本中连续绘图时,如果没有figure命令创建新窗口或hold on/off控制不当,图形可能会画在同一个轴上导致混乱。养成在每个独立图表前加figure;的习惯。
  • 数据包含NaN或Inf:如果绘图数据中包含非有限数,绘图可能会失败或出现空白。绘图前使用any(isnan(y_data))any(isinf(y_data))进行检查和清理。
  • 图形属性设置错误:例如,试图用plot绘制两个长度不同的向量,或者对分类数据错误地使用了连续绘图函数。确认绘图函数的输入数据格式是否正确。

8.4 性能优化技巧

当处理大规模数据或复杂循环时,代码可能运行缓慢。

  • 向量化操作:这是提升MATLAB性能的首要原则。尽量避免使用for循环对数组元素逐个操作,而是利用MATLAB的矩阵运算能力。
    % 慢:循环 n = 1e6; a = rand(n,1); b = zeros(n,1); for i = 1:n b(i) = a(i)^2 + sin(a(i)); end % 快:向量化 b = a.^2 + sin(a);
  • 预分配数组:在循环中增长数组(如b = [b; new_value])会极度耗时。务必在循环前用zerosones预分配好最终大小的数组。
  • 使用分析器:使用MATLAB内置的性能分析工具(在“编辑器”标签页点击“运行并计时”,或使用profile viewer命令)来定位代码中的瓶颈热点。

最后,也是最关键的一点:勤用帮助文档。在命令窗口输入doc 函数名(如doc fmincon),阅读官方文档中的语法、示例、算法说明和选项列表,远比在网上零散搜索要系统、准确得多。文档是学习MATLAB最权威、最全面的教科书。

http://www.cnnetsun.cn/news/4276854.html

相关文章:

  • 双节点上线完整指南:从验收标准到回滚预案
  • 医疗数据交换基石:HL7消息解析原理、实战与演进
  • 滴滴2016研发笔试题解析:高并发与LBS场景下的技术考察
  • Redis Geo 实战:深入探索附近的人、LBS 场景与 Geohash 原理
  • Python爬虫实战:构建商品价格监控系统与反爬策略详解
  • 基于LSTM的地铁AFC客流量预测:数据预处理与特征工程全解析
  • AI提效后时间怎么分配?从量化指标到工程落地的完整指南
  • I2C控制器Busy死锁根因分析与总线恢复机制设计
  • 构建个人C++知识体系:从零散笔记到高效检索与实战应用
  • Java+Spring Boot构建六爻排盘系统:算法、接口与小程序实战
  • 本地部署RAG知识库:用Docker Compose自建个人问答系统
  • STC15单片机USART串口通信:从库函数配置到实战避坑指南
  • 具身智能商业化应用难题与TVA破解之道(11)
  • Minimax H3提示词Skill实战:从分镜描述到稳定出片
  • Python数据处理全链路实战:从Pandas到分布式计算与工程化部署
  • 瑞萨RISC-V语音控制ASSP芯片解析:从架构到开发实践
  • SAC-Auto深度强化学习:激光雷达避障路径规划实战解析
  • Delphi 12.3安装KonopkaControls 8.0实战:避坑指南与核心控件详解
  • C++面向对象编程实战:从类设计到文件操作的图书馆管理系统实现
  • HTML5 Canvas游戏开发实战:从零实现物理小游戏
  • STM32 DAC开发:从标准库到HAL库的对照迁移与实战指南
  • 别让AI画板了!AI辅助电路查错实战指南:网表、BOM与DRC审查
  • 基于LFSR的FPGA伪随机数生成器设计与Verilog实现
  • Python实现RGV动态调度:从离散事件仿真到优化策略实战
  • K-means聚类算法原理与Python实现:从零到实战可视化
  • 智能驾驶变道控制:RL-MPC分层协同架构实战解析
  • Shell脚本工程化:模块化封装mkdir、cp、echo命令实践
  • 让 Agent 真正“记住“项目:从会话记忆到长期记忆
  • C++函数模板实现快速排序:泛型编程与算法优化实践
  • 中文短文本分类的Transformer改进实践:词感知、结构注入与领域蒸馏