* O' ~/ u. A& T/ c0 G(2)MATLAB 足够灵活,可以按照问题的需要,自主开发程序,解决问题。: L5 R# }. T$ t& G. f
7 B* @& J; H. d. A: u% Z7 @(3)MATLAB易上手,本身很简单,不存在壁垒。掌握正确的 MATLAB 使用方法和实用的小技巧,在半小时内就可以很快地变成 MATLAB 高手了。+ g5 a% c9 X- ?! k; p3 ~1 V% f( n
2 C) {5 f" k4 Y7 ]
正确且高效的 MATLAB 编程理念就是以问题为中心的主动编程。我们传统学习编程的方法是学习变量类型、语法结构、算法以及编程的其他知识,因为学习时候是没有目标的,也不知道学的知识什么时候能用到,收效甚微。而以问题为中心的主动编程,则是先找到问题的解决步骤,然后在 MATLAB 中一步一步地去实现。在每步实现的过程中,遇到问题,查找知识(互联网时代查询知识还是很容易的),定位方法,再根据方法,查询 MATLAB 中的对应函数,学习函数用法,回到程序,解决问题。在这个过程中,知识的获取都是为了解决问题的,也就是说每次学习的目标都是非常明确的,学完之后的应用就会强化对知识的理解和掌握,这样即学即用的学习方式是效率最高,也是最有效的方式。最重要的是,这种主动的编程方式会让学习者体验到学习的成就感的乐趣,有成就感,自然就强化对编程的自信了。这种内心的自信和强大在建模中会发挥意想不到的力量,所为信念的力量。# W" l' s- c% u1 f/ L
+ \8 A% d0 F7 a' _$ b, d
数学建模竞赛中的 MATLAB 水平要求:/ `* _3 j. ~' G9 e" \6 O+ O
6 A& X) H) n% a+ g9 [9 W! C" H, L ?
要想在全国大学生数学建模竞赛中拿到国奖, MATLAB 技能是必备的。 具体的技能水平应达到: ; f. S' V: z+ V2 }6 B a) z4 z& w! }; E* O1 E5 D0 f+ O: H+ g
1)了解 MATLAB 的基本用法,包括几个常用的命令,如何获取帮助,脚本结构,程序的分节与注释,矩阵的基本操作,快捷绘图方式; 4 b' F! J! v) f3 V$ l/ x# }! S6 C$ r) C9 J5 r8 F
2)熟悉 MATLAB 的程序结构,编程模式,能自由地创建和引用函数(包括匿名函数); % a& {; ~8 a/ g1 ?. Q0 }2 A: M8 Y- x7 k+ y9 K
3)熟悉常见模型的求解算法和套路,包括连续模型,规划模型,数据建模类的模型; ; H- [, O( T( B G* h* G# {2 }4 |0 D1 Z% d$ C1 r6 _9 h% z; C
4)能够用 MALTAB 程序将机理建模的过程模拟出来,就是能够建立和求解没有套路的数学模型。 ! m q- `2 e4 B$ b/ L- H
. O8 a: c6 G4 n( o: o J) t
要想达到如上要求, 不能按照传统的学习方式一步一步地学习, 而要结合上述提到的学习理念制定科学的训练计划。 ' Z2 y; a3 X& V n6 l- l+ D 8 }) a7 n, N6 J3 H/ c& G 2、已知股票的交易数据:日期、开盘价、最高价、最低价、收盘价、成交量和换手率,试用某种方法来评价这只股票的价值和风险。如何用MATLAB去求解该问题?(交易数据:点击此处获取数据) - i1 ~5 i) o( G: d+ a$ X6 g2 q2 J+ ]& X# n) x7 o; a2 {
解题步骤:- A: x, P0 N2 q- o$ v y% P7 j
. m4 d7 `0 N# c, O. ]; h
第一阶段:从外部读取数据7 Q2 F r+ z( Z. ?% n I
" k. R0 C& |" C* h+ ~$ TStep1.1:把数据文件sz000004.xls拖曳进‘当前文件夹区’,选中数据文件sz000004.xls,右键,将弹出右键列表,很快可发现有个“导入数据”菜单,如图 1 所示。 ) [# F; q( @: o; p2 o( g- K2 C. P& H
6 Y) W2 Q; ^' ?: s. \/ S: {8 O2 X
8 d' _& s+ G1 D. H+ @
图1. 启动导入数据引擎示意图 . T4 I. [ F. Z6 F/ C1 \+ x- Z% i* y9 a O/ I) f
Step1.2:单击“导入数据”这个按钮,则很快发现起到一个导入数据引擎,如图 4 所示。" _% ]' y, e' H6 F
% U7 d0 }9 m# [
" N! T& \; d' y : n% w, @& U% q2 L* P 图2. 导入数据界面 " N. z. G, H! T; B4 q' _3 y5 d5 I& a$ I8 z
Step1.3:观察图 2,在右上角有个“导入所选内容”按钮,则可直接单击之。马上我们就会发现在 MATLAB 的工作区(当前内存中的变量)就会显示这些导入的数据,并以列向量的方式表示,因为默认的数据类型就是“列向量”,当然您可以可以选择其他的数据类型,大家不妨做几个实验,观察一下选择不同的数据类型后会结果会有什么不同。至此,第一步获取数据的工作的完成。' n5 E& I, q( m* V/ J; E F
4 R9 J4 n5 O/ R- x6 A/ U: |1 e+ R 0 y3 o t! m. p Y. O 5 G8 ]+ K6 i E0 z% D第二阶段:数据探索和建模! ~& X- O+ u) f% W5 q" N2 e
# U- l7 ^/ q, ]3 F$ p. h; U1 x现在重新回到问题,对于该问题,我们的目标是能够评估股票的价值和风险,但现在我们还不知道该如何去评估,MATLAB 是工具,不能代替我们决策用何种方法来评估,但是可以辅助我们得到合适的方法,这就是数据探索部分的工作。下面我们就来尝试如何在 MATLAB 中进行数据的探索和建模。 5 h; u/ `. u8 q2 U. } 7 _2 n5 Z0 e: w1 Q* \3 dStep2.1:查看数据的统计信息,了解我们的数据。具体操作方式是双击工具区(直接双击这三个字),此时会得到所有变量的详细统计信息。通过查看这些基本的统计信息,有助于快速在第一层面认识我们所正在研究的数据。当然,只要大体浏览即可,除非这些统计信息对某个问题都有很重要的意义。数据的统计信息是认识数据的基础,但不够直观,更直观也更容易发现数据规律的方式就是数据可视化,也就是以图的形式呈现数据的信息。下面我们将尝试用 MATLAB 对这些数据进行可视化。 8 t: ~, \% b$ A% ] o& ^; L! q; @1 t
由于变量比较多,所以还有必要对这些变量进行初步的梳理。对于这个问题,我们一般关心收盘价随时间的变化趋势,这样我们就可以初步选定日期(DateNum)和收盘价(Pclose)作为重点研究对象。也就是说下一步,要对这这两个变量进行可视化。 . v T; Z; x; ?& P+ {: L% { ; O: s2 c& p- L对于一个新手,我们还不知道如何绘图。但不要紧,新版 MATLAB 提供了更强大的绘图功能——“绘图”面板,这里提供了非常丰富的图形原型,如图 3 所示。 0 w1 A+ H2 `' ~# I6 B" w 2 b' L1 @7 q) E2 U( `: h' `) D- {4 m1 A% W# n' I/ C
* N" Y- z( N7 @2 K
图3 MATLAB绘图面板中的图例 # s3 N, ]% v. o0 d! ~ C % ^" ?: h Z0 z/ L8 [% c要注意,需要在工作区选中变量后绘图面板中的这些图标才会激活。接下来就可以选中一个中意的图标进行绘图,一般都直接先选第一个(plot)看一下效果,然后再浏览整个面板,看看有没有更合适的。下面我们进行绘图操作。 1 K- K/ a5 n/ O+ m# W+ N, R0 V3 G) W h% a+ c& }# V
Step2.2:选中变量 DataNum 和 Pclose,在绘图面板中单机 plot 图标,马上可以得到这两个变量的可视化结果,如图 4 所示,同时还可以在命令窗口区看到绘制此图的命令: ; r S% [" X2 I- N- n4 f 1 T- }5 e3 t( Q>> plot(DateNum,Pclose) % [. I7 W; O1 K: C9 T9 K* C " J- N" `3 E: |# b% i: S5 H0 v) @" ?$ f9 \$ H% A0 j
/ u5 w) o2 m4 D. E/ t 图4 通过 plot 图标绘制的原图 7 l) ?7 ^5 a( q: D - _/ W# n# x* e( q# h. ?这样我们就知道了,下次再绘制这样的图直接用 plot 命令就可以了。一般情况下,用这种方式绘图的图往往不能满足我们的要求,比如我们希望更改: % J3 B& a6 \8 ~% E# b : e# t1 n' _" K! ^(1)曲线的颜色、线宽、形状; 9 Y& n3 ]! O6 M! w# W- n; \5 x 7 C8 P' j3 z( w, _/ D0 g9 ~1 J% W4 C(2)坐标轴的线宽、坐标,增加坐标轴描述;; c9 m7 [% x! B+ C
' G% }( ?' X5 t$ A5 d `2 i
(3)在同个坐标轴中绘制多条曲线。1 f( K; A4 p* z& K- t% p$ x5 e( z+ o- [
4 I8 q& {# |! }' d+ Z1 E
此时我们就需要了解更多关于命令 plot 的用法,这时就可以通过 MATLAB 强大的帮助系统来帮助我们实现期望的结果。最直接获取帮助的两个命令是 doc 和 help,对于新手来说,推荐使用 doc,因为 doc 直接打开的是帮助系统中的某个命令的用法说明,不仅全,而且有应用实例,这样就可以“照猫画虎”,直接参考实例,从而将实例快速转化成自己需要的代码。# X6 P5 ^; z" H1 R, d% J' t l1 f
) ?+ }$ d. h# z: h; k
接下来我们就要考虑如何评估股票的价值和风险呢?' Q2 s$ d6 ~) n$ T$ ^
: {7 O7 N0 A- J8 d9 M3 j) S5 ~/ `
对于一只好的股票,我们希望股票的增幅越大越好,体现在数学上,就是曲线的斜率越大越好。) ?" L3 B ?/ U/ D2 v
: \! _, a w" g+ J# [drawdown=max(Di-Dj)/Di,drawdown就是最大回撤率。其实就是对每一个净值进行回撤率求值,然后找出最大的。可以使用程序实现。最大回撤率越大,说明该股票的风险越高。所以最大回撤率越小,股票越好。; i5 b- D4 M& Q9 z: [; e
$ |( @# ?, A4 F5 K+ V/ h' N 斜率和最大回撤率不妨一个一个来解决。我们先来看如何计算曲线的斜率。对于这个问题,比较简单,由于从数据的可视化结果来看,数据近似成线性,所以不妨用多项式拟合的方法来拟合该改组数据的方程,这样我们就可以得到斜率。 : d+ a! A/ p8 ]* l! k \: Z( o f2 m% X+ y5 K9 V
Step2.3:通过polyfit()多项式拟合的命令,并计算股票的价值,具体代码为:8 F$ I& m F; T+ b* U* c. S
9 ~* t+ {& y; g7 E( r U. j# H>> p = polyfit(DateNum,Pclose,1); % 多项式拟合& l; f3 n0 ?+ ^* ^$ ~" y
3 F. i8 K! `' s, |4 S0 i: i
>> value = p(1) % 将斜率赋值给value,作为股票的价值" k6 M0 u; x* s
% |$ N5 [1 L* ]: ~
value =+ H) v5 R, n3 W+ T( v5 t a% D
! v& \0 _$ b, r+ e 0.1212 $ ~9 O- \3 r; Z8 }: }# v6 L4 k& k2 Z; P8 P- P, I9 d" {: L
代码分析:%后面的内容是注释。polyfit()有三个参数,前两个大家都能明白是什么意思,那第三个参数是什么意思呢?它表示多项式的阶数,也就是最高次数。比如:在本例中,第三个参数为1,说明其为一次项,即一次函数。第三个参数为你要拟合的阶数,一阶直线拟合,二阶抛物线拟合,并非阶次越高越好,看拟合情况而定。polyfit()返回阶数为 n 的多项式 p(x) 的系数,p 中的系数按降幂排列。在本例中的P(1)指的是最高项的系数,即斜率。" V; T7 r! N! v, p | ]3 _ G" b
8 M2 k1 ~! }8 C6 FStep2.4:用相似的方法,可以很快得到计算最大回撤的代码: 5 j( Q1 r k1 |, Y : b6 t+ k& g' o" [% e9 ^>> MaxDD = maxdrawdown(Pclose); % 计算最大回撤" {! Y$ B! F. G B* \: x: z2 i
! [* v+ C! T R6 H* m {9 ~( F
>> risk = MaxDD % 将最大回撤赋值给risk,作为股票的风险4 C" Y8 H* ?* n
$ p/ S2 q7 f2 h9 T3 X' G. }' hrisk = # \* M+ k V5 q6 h0 S 4 I r, d- u. O: ~( \% ]" U, S4 ~+ R 0.1155 & x* }6 U6 O8 f. T5 P2 `8 k5 R& u$ l( E. q! e9 R& Z2 a. K1 Y
代码分析:最大回撤率当然计算的是每天收盘时的股价。最大回撤率越大,说明该股票的风险越高。所以最大回撤率越小,股票越好。( y. Y# p3 ^+ g9 k5 ~0 u4 c
9 [ E' Y9 }- [" {% n e* M到此处,我们已经找到了评估股票价值和风险的方法,并能用 MALTAB 来实现了。但是,我们都是在命令行中实现的,并不能很方便地修改代码。而 MATLAB 最经典的一种用法就是脚本,因为脚本不仅能够完整地呈现整个问题的解决方法,同时更便于维护、完善、执行,优点很多。所以当我们的探索和开发工作比较成熟后,通常都会将这些有用的程序归纳整理起来,形成脚本。现在我们就来看如何快速开发解决该问题的脚本。+ r9 I& S; X! R+ d
5 b4 R8 _9 E8 \: b) J1 ^3 z
Step2.5:像 Step1.1 一样,重新选中数据文件,右键并单击“导入数据”菜单,待启动导入数据引擎后,选择“生成脚本”,然后就会得到导入数据的脚本,并保存该脚本。8 P5 i8 B) P' D. I8 Y7 N
( @) j% D4 p5 D
脚本源代码中有些地方要注意: 4 [! x) L4 t! ]' X4 ?" o/ b y% ]/ h1 b6 ]7 R
%%在matlab代码中的作用是将代码分块,上下两个%%之间的部分作为一块,在运行代码的时候可以分块运行,查看每一块代码的运行情况。常用于调试程序。%%相当于jupyter notebook中的cell。4 e: L8 N; ]/ X+ R! d
/ Z" F, _% v- ^" W' |
%后的内容是注释。) n- ~6 W A- k% ?
3 {4 w' s& l [7 b; L
每句代码后面的分号作用为不在命令窗口显示执行结果。# ~; D! j. D& A1 d1 p3 n; p( i0 W
$ q$ s4 e- B4 Y) {脚本源代码:1 n6 d' `5 C& _; R0 m3 r
5 c! I; I1 J8 q9 m5 t( H. \%% 预测股票的价值与风险: Z! j6 C S* p7 ] h3 Z: R
3 ?; m% k6 g' ]9 g; i
%% 导入数据 , q& R9 @; a- X% v) Z! t3 ]clc, clear, close all; M: Y0 p# y3 p0 F" c/ P/ J3 F
% clc:清除命令窗口的内容,对工作环境中的全部变量无任何影响 & N/ o4 H. ~! K4 o1 o
% clear:清除工作空间的所有变量 6 S3 @2 N% k; l
% close all:关闭所有的Figure窗口, R; @/ w- b M) E. N. S4 E a1 z
: g1 V& A0 m8 J$ G& V
% 导入数据 " F% G. D' M4 V- H- @: {[~, ~, raw] = xlsread('sz000004.xlsx', 'Sheet1', 'A2:H7');: F8 |# \- Z$ Q: U6 N
% [num,txt,raw],~表示省略该部分的返回值 + I1 i/ n2 T/ _' m9 {% xlsread('filename','sheet', 'range'),第二个参数指数据在sheet1还是其他sheet部分,range表示单元格范围0 i# W$ O- j% e, H4 F
9 [2 e- c. F, J! n W# v: [& K- h- _% 创建输出变量# |- _$ M' F, G' r
data = reshape([raw{:}],size(raw));# C( X% r. B) A& g% Y' @, h
% [raw{:}]指raw里的所有数据,size(raw):6 x 8 ,该语句把6x8的cell类型数据转换为6x8 double类型数据 6 M1 l/ \: N3 t4 p4 _* h % n4 m/ H* \/ C+ F% |6 |% v% 将导入的数组分配列变量名称 9 `; ]& z8 D) ~8 {Date = data(:, 1); % 第一个参数表示从第一行到最后一行,第二个参数表示第一列3 \% i7 ]8 s9 x5 _1 r7 [& C
DateNum = data(:, 2);% y) k! n( o1 G k8 c$ N7 p
Popen = data(:, 3);: X( o. J9 F$ C( n9 g, S" Y6 u; p
Phigh = data(:, 4);7 _) ~5 H# ~3 Z/ r& U6 Q* H
Plow = data(:, 5); # Z0 K# b, F% APclose = data(:, 6); 5 I0 O, T8 Q9 k5 m2 mVolum = data(:, 7); % Volume 表示股票成交量的意思,成交量=成交股数*成交价格 再加权求和( S. | \ `. C( n
Turn = data(:, 8); % turn表示股票周转率,股票周转率越高,意味着该股股性越活泼,也就是投资人所谓的热门股$ `8 c$ S. D" L9 V, h; m4 G$ J( |
( e7 e: o0 k5 O; U) E
% 清除临时变量data和raw - e# ~4 u' Y6 ]: k; _clearvars data raw; # [8 Y3 o/ \% P9 {$ |6 l5 I. c5 _" l Z0 F8 P+ ]$ i
%% 数据探索* @; E- u Y* e! F5 U4 F1 w
: ]! C7 g- z# G t) d5 u9 {
figure % 创建一个新的图像窗口 & k2 A# B* X( F4 ]plot(DateNum, Pclose, 'k'); % 'k',曲线是黑色的,打印后不失真 4 K, j( y1 R2 D# Udatetick('x','mm-dd'); % 更改日期显示类型。参数x表示x轴,mm-dd表示月份和日。yyyy-mm-dd,如2018-10-27 l f6 P3 f) l! u9 Lxlabel('日期') % x轴9 |3 B+ `/ T6 M
ylabel('收盘价') % y轴2 H* O& ^) r) S# y9 V
figure8 V; p; E3 w$ R/ ^# ~
bar(Pclose) % 作为对照图形 : O- A! W3 S. r( T Y4 b) S# x; Y" {5 L3 B( Q' b/ j3 [
%% 股票价值的评估: u) H! x1 q9 P3 V+ V
E2 j7 m8 u# J: ep = polyfit(DateNum, Pclose, 1); % 多项式拟合0 p3 R5 o4 p- }; k( }1 U
% polyfit()返回阶数为 n 的多项式 p(x) 的系数,p 中的系数按降幂排列 ( R b0 {& p2 B, _5 [' jP1 = polyval(p,DateNum); % 得到多项式模型的结果8 V0 K$ {7 N7 Q8 k; d
figure0 p+ ~! C3 W# y) [, i; S& C0 C
plot(DateNum,P1,DateNum,Pclose,'*g'); % 模型与原始数据的对照, '*g'表示绿色的* ; P. K) i& S# G( W7 }9 \0 Jvalue = p(1) % 将斜率赋值给value,作为股票的价值。p(1)最高项的次数 ) E3 z) I2 `8 `+ ]9 b " X4 J4 {2 G; W! V% R* M5 k%% 股票风险的评估5 x, Z7 A& R' @* J% p
MaxDD = maxdrawdown(Pclose); % 计算最大回撤* h2 V9 r8 a. [8 ^
risk = MaxDD % 将最大回撤赋值给risk,作为股票的风险* C* y% S! ^& Z5 F. Y% C( G. l
3、回归算法演练。; ]5 D- d7 }3 a0 _ P% b/ c
9 ]! }( I) v" F" ~- f) q2 E) [6 I(1)一元线性回归7 _$ \2 A' Y5 O& I! h
; K u b _. g8 r1 F
[ 例1 ] 近 10 年来,某市社会商品零售总额与职工工资总额(单位:亿元)的数据见表1,请建立社会商品零售总额与职工工资总额数据的回归模型。( r6 K E* ]/ u7 |1 M$ ^2 s