Matlab与数学建模
⼀、学习⽬标。
(1)了解Matlab与数学建模竞赛的关系。
(2)掌握Matlab数学建模的第⼀个⼩实例—评估股票价值与风险。
(3)掌握Matlab数学建模的回归算法。
⼆、实例演练。
1、谈谈你对Matlab与数学建模竞赛的了解。
Matlab在数学建模中使⽤⼴泛:MATLAB 是公认的最优秀的数学模型求解⼯具,在数学建模竞赛中超过 95% 的参赛队使⽤ MATLAB 作为求解⼯具,在国家奖队伍中,MATLAB 的使⽤率⼏乎 100%。虽然⽐较知名的数模软件不只 MATLAB。
⼈们喜欢使⽤Matlab去数学建模的原因:
(1)MATLAB 的数学函数全,包含⼈类社会的绝⼤多数数学知识。
(2)MATLAB ⾜够灵活,可以按照问题的需要,⾃主开发程序,解决问题。
(3)MATLAB易上⼿,本⾝很简单,不存在壁垒。掌握正确的 MATLAB 使⽤⽅法和实⽤的⼩技巧,在半⼩时内就可以很快地变成 MATLAB ⾼⼿了。
正确且⾼效的 MATLAB 编程理念就是以问题为中⼼的主动编程。我们传统学习编程的⽅法是学习变量类型、语法结构、算法以及编程的其他知识,因为学习时候是没有⽬标的,也不知道学的知识什么时候能⽤到,收效甚微。⽽以问题为中⼼的主动编程,则是先到问题的解决步骤,然后在 MATLAB 中⼀步⼀步地去实现。在每步实现的过程中,遇到问题,查知识(互联⽹时代查询知识还是很容易的),定位⽅法,再根据⽅法,查询 MATLAB 中的对应函数,学习函数⽤法,回到程序,解决问题。在这个过程中,知识的获取都是为了解决问题的,也就是说每次学习的⽬标都是⾮常明确的,学完之后的应⽤就会强化对知识的理解和掌握,这样即学即⽤的学习⽅式是效率最⾼,也是最有效的⽅式。最重要的是,这种主动的编程⽅式会让学习者体验到学习的成就感的乐趣,有成就感,⾃然就强化对编程的⾃信了。这种内⼼的⾃信和强⼤在建模中会发挥意想不到的⼒量,所为信念的⼒量。
数学建模竞赛中的 MATLAB ⽔平要求:
要想在全国⼤学⽣数学建模竞赛中拿到国奖, MATLAB 技能是必备的。具体的技能⽔平应达到:
1)了解 MATLAB 的基本⽤法,包括⼏个常⽤的命令,如何获取帮助,脚本结构,程序的分节与注释,矩阵的基本操作,快捷绘图⽅式;
2)熟悉 MATLAB 的程序结构,编程模式,能⾃由地创建和引⽤函数(包括匿名函数);
3)熟悉常见模型的求解算法和套路,包括连续模型,规划模型,数据建模类的模型;
4)能够⽤ MALTAB 程序将机理建模的过程模拟出来,就是能够建⽴和求解没有套路的数学模型。
要想达到如上要求,不能按照传统的学习⽅式⼀步⼀步地学习,⽽要结合上述提到的学习理念制定科学的训练计划。
2、已知股票的交易数据:⽇期、开盘价、最⾼价、最低价、收盘价、成交量和换⼿率,试⽤某种⽅法来评价这只股票的价值和风险。如何⽤MATLAB去求解该问题?(交易数据:)
解题步骤:
第⼀阶段:从外部读取数据
Step1.1:把数据⽂件sz000004.xls拖曳进‘当前⽂件夹区’,选中数据⽂件sz000004.xls,右键,将弹出右键列表,很快可发现有个“导⼊数据”菜单,如图 1 所⽰。
图1. 启动导⼊数据引擎⽰意图
Step1.2:单击“导⼊数据”这个按钮,则很快发现起到⼀个导⼊数据引擎,如图 4 所⽰。
图2. 导⼊数据界⾯
Step1.3:观察图 2,在右上⾓有个“导⼊所选内容”按钮,则可直接单击之。马上我们就会发现在 MATLAB 的⼯作区(当前内存中的变量)就会显⽰这些导⼊的数据,并以列向量的⽅式表⽰,因为默认的数据类型就是“列向量”,当然您可以可以选择其他的数据类型,⼤家不妨做⼏个实验,观察⼀下选择不同的数据类型后会结果会有什么不同。⾄此,第⼀步获取数据的⼯作的完成。
第⼆阶段:数据探索和建模
现在重新回到问题,对于该问题,我们的⽬标是能够评估股票的价值和风险,但现在我们还不知道该如何去评估,MATLAB 是⼯具,不能代替我们决策⽤何种⽅法来评估,但是可以辅助我们得到合适的⽅法,这就是数据探索部分的⼯作。下⾯我们就来尝试如何在 MATLAB 中进⾏数据的探索和建模。
Step2.1:查看数据的统计信息,了解我们的数据。具体操作⽅式是双击⼯具区(直接双击这三个字),此时会得到所有变量的详细统计信息。通过查看这些基本的统计信息,有助于快速在第⼀层⾯认识我们所正在研究的数据。当然,只要⼤体浏览即可,除⾮这些统计信息对某个问题都有很重要的意义。数据的统计信息是认识数据的基础,但不够直观,更直观也更容易发现数据规律的⽅式就是数据可视化,也就是以图的形式呈现数据的信息。下⾯我们将尝试⽤ MATLAB 对这些数据进⾏可视化。
由于变量⽐较多,所以还有必要对这些变量进⾏初步的梳理。对于这个问题,我们⼀般关⼼收盘价随时间的变化趋势,这样我们就可以初步选定⽇期(DateNum)和收盘价(Pclose)作为重点研究对象。也就是说下⼀步,要对这这两个变量进⾏可视化。
对于⼀个新⼿,我们还不知道如何绘图。但不要紧,新版 MATLAB 提供了更强⼤的绘图功能——“绘图”⾯板,这⾥提供了⾮常丰富的图形原型,如图 3 所⽰。
图3 MATLAB绘图⾯板中的图例
要注意,需要在⼯作区选中变量后绘图⾯板中的这些图标才会激活。接下来就可以选中⼀个中意的图标进⾏绘图,⼀般都直接先选第⼀个(plot)看⼀下效果,然后再浏览整个⾯板,看看有没有更合适的。下⾯我们进⾏绘图操作。
Step2.2:选中变量 DataNum 和 Pclose,在绘图⾯板中单机 plot 图标,马上可以得到这两个变量的可视化结果,如图 4 所⽰,同时还可以在命令窗⼝区看到绘制此图的命令:>> plot(DateNum,Pclose)
图4 通过 plot 图标绘制的原图
这样我们就知道了,下次再绘制这样的图直接⽤ plot 命令就可以了。⼀般情况下,⽤这种⽅式绘图的图往往不能满⾜我们的要求,⽐如我们希望更改:
(1)曲线的颜⾊、线宽、形状;
(2)坐标轴的线宽、坐标,增加坐标轴描述;
(3)在同个坐标轴中绘制多条曲线。
此时我们就需要了解更多关于命令 plot 的⽤法,这时就可以通过 MATLAB 强⼤的帮助系统来帮助我们实现期望的结果。最直接获取帮助的两个命令是 doc 和 help,对于新⼿来说,推荐使⽤ doc,因为 doc 直接打开的是帮助系统中的某个命令的⽤法说明,不仅全,⽽且有应⽤实例,这样就可以“照猫画虎”,直接参考实例,从⽽将实例快速转化成⾃⼰需要的代码。
接下来我们就要考虑如何评估股票的价值和风险呢?
对于⼀只好的股票,我们希望股票的增幅越⼤越好,体现在数学上,就是曲线的斜率越⼤越好。
对于风险,则可⽤最⼤回撤率来描述更合适,什么是最⼤回撤率?
最⼤回撤率的公式可以这样表达:
D为某⼀天的净值,i为某⼀天,j为i后的某⼀天,Di为第i天的产品净值,Dj则是Di后⾯某⼀天的净值
drawdown=max(Di-Dj)/Di,drawdown就是最⼤回撤率。其实就是对每⼀个净值进⾏回撤率求值,然后出最⼤的。可以使⽤程序实现。最⼤回撤率越⼤,说明该股票的风险越⾼。所以最⼤回撤率越⼩,股票越好。
斜率和最⼤回撤率不妨⼀个⼀个来解决。我们先来看如何计算曲线的斜率。对于这个问题,⽐较简单,由于从数据的可视化结果来看,数据近似成线性,所以不妨⽤多项式拟合的⽅法来拟合该改组数据的⽅程,这样我们就可以得到斜率。
Step2.3:通过polyfit()多项式拟合的命令,并计算股票的价值,具体代码为:
>> p = polyfit(DateNum,Pclose,1); % 多项式拟合
>> value = p(1) % 将斜率赋值给value,作为股票的价值
value =
0.1212
代码分析:%后⾯的内容是注释。polyfit()有三个参数,前两个⼤家都能明⽩是什么意思,那第三个参数是什么意思呢?它表⽰多项式的阶数,也就是最⾼次数。⽐如:在本例中,第三个参数为1,说明其为⼀次项,即⼀次函数。第三个参数为你要拟合的阶数,⼀阶直线拟合,⼆阶抛物线拟合,并⾮阶次越⾼越好,看拟合情况⽽定。polyfit()返回阶数为 n 的多项式 p(x) 的系数,p 中的系数按降幂排列。在本例中的P(1)指的是最⾼项的系数,即斜率。
Step2.4:⽤相似的⽅法,可以很快得到计算最⼤回撤的代码:
>> MaxDD = maxdrawdown(Pclose); % 计算最⼤回撤
>> risk = MaxDD % 将最⼤回撤赋值给risk,作为股票的风险
risk =
0.1155
代码分析:最⼤回撤率当然计算的是每天收盘时的股价。最⼤回撤率越⼤,说明该股票的风险越⾼。所以最⼤回撤率越⼩,股票越好。
到此处,我们已经到了评估股票价值和风险的⽅法,并能⽤ MALTAB 来实现了。但是,我们都是在命
令⾏中实现的,并不能很⽅便地修改代码。⽽ MATLAB 最经典的⼀种⽤法就是脚本,因为脚本不仅能够完整地呈现整个问题的解决⽅法,同时更便于维护、完善、执⾏,优点很多。所以当我们的探索和开发⼯作⽐较成熟后,通常都会将这些有⽤的程序归纳整理起来,形成脚本。现在我们就来看如何快速开发解决该问题的脚本。
Step2.5:像 Step1.1 ⼀样,重新选中数据⽂件,右键并单击“导⼊数据”菜单,待启动导⼊数据引擎后,选择“⽣成脚本”,然后就会得到导⼊数据的脚本,并保存该脚本。
脚本源代码中有些地⽅要注意:
%%在matlab代码中的作⽤是将代码分块,上下两个%%之间的部分作为⼀块,在运⾏代码的时候可以分块运⾏,查看每⼀块代码的运⾏情况。常⽤于调试程序。%%相当于jupyter notebook中的cell。
%后的内容是注释。
每句代码后⾯的分号作⽤为不在命令窗⼝显⽰执⾏结果。
脚本源代码:
%% 预测股票的价值与风险
%% 导⼊数据
clc, clear, close all
% clc:清除命令窗⼝的内容,对⼯作环境中的全部变量⽆任何影响
% clear:清除⼯作空间的所有变量
% close all:关闭所有的Figure窗⼝
% 导⼊数据
[~, ~, raw] = xlsread('sz000004.xlsx', 'Sheet1', 'A2:H7');
% [num,txt,raw],~表⽰省略该部分的返回值
% xlsread('filename','sheet', 'range'),第⼆个参数指数据在sheet1还是其他sheet部分,range表⽰单元格范围
% 创建输出变量
data = reshape([raw{:}],size(raw));
% [raw{:}]指raw⾥的所有数据,size(raw):6 x 8 ,该语句把6x8的cell类型数据转换为6x8 double类型数据
% 将导⼊的数组分配列变量名称
Date = data(:, 1); % 第⼀个参数表⽰从第⼀⾏到最后⼀⾏,第⼆个参数表⽰第⼀列
DateNum = data(:, 2);
数据可视化什么意思Popen = data(:, 3);
Phigh = data(:, 4);
Plow = data(:, 5);
Pclose = data(:, 6);
Volum = data(:, 7); % Volume 表⽰股票成交量的意思,成交量=成交股数*成交价格再加权求和
Turn = data(:, 8); % turn表⽰股票周转率,股票周转率越⾼,意味着该股股性越活泼,也就是投资⼈所谓的热门股
% 清除临时变量data和raw
clearvars data raw;
%% 数据探索
figure % 创建⼀个新的图像窗⼝
plot(DateNum, Pclose, 'k'); % 'k',曲线是⿊⾊的,打印后不失真
datetick('x','mm-dd'); % 更改⽇期显⽰类型。参数x表⽰x轴,mm-dd表⽰⽉份和⽇。yyyy-mm-dd,如2018-10-27
xlabel('⽇期') % x轴
ylabel('收盘价') % y轴
figure
bar(Pclose) % 作为对照图形
%% 股票价值的评估
p = polyfit(DateNum, Pclose, 1); % 多项式拟合
% polyfit()返回阶数为 n 的多项式 p(x) 的系数,p 中的系数按降幂排列
P1 = polyval(p,DateNum); % 得到多项式模型的结果
figure
plot(DateNum,P1,DateNum,Pclose,'*g'); % 模型与原始数据的对照, '*g'表⽰绿⾊的*
value = p(1) % 将斜率赋值给value,作为股票的价值。p(1)最⾼项的次数
%% 股票风险的评估
MaxDD = maxdrawdown(Pclose); % 计算最⼤回撤
risk = MaxDD  % 将最⼤回撤赋值给risk,作为股票的风险
3、回归算法演练。
(1)⼀元线性回归
[ 例1 ] 近 10 年来,某市社会商品零售总额与职⼯⼯资总额(单位:亿元)的数据见表1,请建⽴社会商品零售总额与职⼯⼯资总额数据的回归模型。
该问题是典型的⼀元回归问题,但先要确定是线性还是⾮线性,然后就可以利⽤对应的回归⽅法建⽴他们之间的回归模型了,具体实现的 MATLAB 代码如下:(1)输⼊数据
%% 输⼊数据
clc, clear, close all
% 职⼯⼯资总额
x = [23.8,27.6,31.6,32.4,33.7,34.90,43.2,52.8,63.8,73.4];
% 商品零售总额
y = [41.4,51.8,61.7,67.9,68.7,77.5,95.9,137.4,155.0,175.0];
(2)采⽤最⼩⼆乘回归
%% 采⽤最⼩⼆乘法回归
% 作散点图
figure
plot(x,y,'r*') % 散点图,散点为红⾊
xlabel('x(职⼯⼯资总额)','fontsize',12)
ylabel('y(商品零售总额)','fontsize',12)
set(gca, 'linewidth',2) % 坐标轴线宽为2
% 采⽤最⼩⼆乘法拟合
Lxx = sum((x-mean(x)).^2); %在列表运算中,^与.^不同
Lxy = sum((x-mean(x)).*(y-mean(y)));
b1 = Lxy/Lxx;
b0 = mean(y) - b1 * mean(x);
y1 = b1 * x + b0;
hold on % hold on是当前轴及图像保持⽽不被刷新,准备接受此后将绘制的图形,多图共存
plot(x,y1, 'linewidth',2);
运⾏本节程序,会得到如图5所⽰的回归图形。在⽤最⼩⼆乘回归之前,先绘制了数据的散点图,这样就可以从图形上判断这些数据是否近似成线性关系。当发现它们的确近似在⼀条线上后,再⽤线性回归的⽅法进⾏回归,这样也更符合我们分析数据的⼀般思路。
图5
(3)采⽤ LinearModel.fit 函数进⾏线性回归
%% 采⽤ LinearModel.fit 函数进⾏线性回归
m2 = LinearModel.fit(x, y)
运⾏结果如下:
m2 =
Linear regression model:
y ~ 1 + x1
Estimated Coefficients:
Estimate SE tStat pValue
(Intercept) -23.549 5.1028 -4.615 0.0017215
x1 2.7991 0.11456 24.435 8.4014e-09
R-squared: 0.987, Adjusted R-Squared 0.985
F-statistic vs. constant model: 597, p-value = 8.4e-09
如下图,我们只需记住-23.594是⼀次函数的中x的系数,2.7991是⼀次函数中的常数项即可,其它的不⽤理会。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。