本文档是对课程内容的简单整理。

  • 前缀Z_ 为正课视频的简称,如Z1为正课视频第1课
  • 前缀G_ 为更新视频的简称,如G1为更新视频第1课

灰色预测 Matlab

(1)数据是以年份度量的非负数据(如果是月份或者季度数据一定要用我们上一讲学过的时间序列模型);
(2)数据能经过准指数规律的检验(除了前两期外,后面至少90%的期数的光滑比要低于0.5);
(3)数据的期数较短且和其他数据之间的关联性不强(小于等于10,也不能太短了,比如只有3期数据),要是数据期数较长,一般用传统的时间序列模型比较合适。

级比检验方法:
清风 / 老哥 两种

清风代码:

D:\00000MCM\清风\0 课件和代码\正课配套的课件和代码\第12讲.预测模型\代码和例题数据\灰色预测\main.m
三种方式

  • 原始
  • 新信息
  • 新陈代谢

老哥代码 PPT:

D:\00000MCM\清风\0 课件和代码\正课配套的课件和代码\第12讲.预测模型\代码和例题数据\灰色预测\laoge_huiseyuce.m

PPT 级比检验讲解
D:\00000MCM\B站老哥带你学数模课程课件\老哥带你学数模课件\课件\6.1 6.2 6.3 老哥带你学数模-数学建模灰色预测模型汇总..pdf

神经网络预测

文章
必须说明数据划分 训练验证测试
2020B 0089:BP神经网络
2020B 0019:BP神经网络(双输出 不同参数对比试验 隐含层元素 学习率)
2020B 0019:BP神经网络(分为三个小网络)

Matlab操作

数据归一化 反归一化操作
bp神经网络及matlab实现 - phlsheji - 博客园Matlab中的数据预处理-归一化(mapminmax)与标准化(mapstd)_hqh45的专栏-CSDN博客_mapminmax

需要归一化数据
D:\00000MCM\0 codes\2020B\q3.m

  1. clc
  2. clear
  3. close all
  4. %% 加载数据 (模型)
  5. % [num_input,txt_input,raw_input]=xlsread('input') ;
  6. % [num_output,txt_output,raw_output]=xlsread('output') ;
  7. % input_0 = num_input(:,3:end);
  8. % input = num_input;
  9. % output = num_output;
  10. load('q3_21')
  11. % input
  12. % output
  13. % output = output(:, 2);
  14. % load('model_1')
  15. %% 数据预处理
  16. cut = 300;
  17. % 原始数据:样本*变量维度
  18. % data_train_input = input(1:cut,:);
  19. % data_train_output = output(1:cut,:);
  20. data_train_input = input; % 采用全部数据输入 神经网络默认分割为 70训练-15验证-15测试
  21. data_train_output = output;
  22. data_test_input = input(cut + 1:end,:);
  23. data_test_output = output(cut + 1:end,:);
  24. % 神经网络接收数据:转置 变量维度*样本
  25. input_train = data_train_input';
  26. output_train = data_train_output';
  27. input_test = data_test_input';
  28. output_test = data_test_output';
  29. %训练数据归一化
  30. [inputn,inputps] = mapminmax(input_train);
  31. [outputn,outputps] = mapminmax(output_train);
  32. % 定义网络
  33. net = newff(inputn, outputn, 50); % 获取 变量维度 变量维度 隐藏层神经元个数
  34. %参数设置
  35. net.trainParam.epochs=1000;%迭代次数
  36. net.trainParam.lr=0.4;%学习率
  37. net.trainParam.goal=0.00000000001;%收敛目标
  38. %神经网络训练
  39. net = train(net, inputn, outputn);
  40. % 保存网络
  41. save('model_1', 'net')
  42. %测试数据归一化
  43. inputn_test = mapminmax('apply', input_test, inputps);
  44. %神经网络测试输出
  45. an = sim(net,inputn_test);
  46. BPoutput = mapminmax('reverse', an, outputps);
  47. % 数据可视化
  48. % 数值
  49. figure(1)
  50. plot(BPoutput(1,:), '-', 'Color', [1 0.5 0], 'linewidth', 1.5) % 橘色
  51. hold on
  52. plot(output_test(1,:), '.', 'Color', [0 0.60 1], 'linewidth', 1.5, 'MarkerSize', 15); % 青蓝
  53. hold on
  54. plot(BPoutput(2,:),'k') %
  55. hold on
  56. plot(output_test(2,:),'g.');
  57. legend('模拟值(含硫量)','原始值(含硫量)','模拟值(辛烷值)','原始值(辛烷值)')
  58. % legend('模拟值(辛烷值)','原始值(辛烷值)')
  59. title('title')
  60. ylabel('ylabel')
  61. xlabel('xlabel')
  62. % axis([0 11, 85 95])
  63. % 误差
  64. err = abs(BPoutput - output_test);
  65. err_mean = mean(err, 1);
  66. figure(2)
  67. plot(err_mean,'-*')
  68. title('测试误差')
  69. ylabel('平均误差')
  70. xlabel('样本')
  71. % 数值百分比
  72. err_rate = err_mean ./ mean(output_test) * 100;
  73. figure(3)
  74. plot(err_rate,'-*')
  75. title('测试误差百分比')
  76. ylabel('平均误差百分比')
  77. xlabel('样本')

Python操作

需要归一化数据
D:\00000py\1\mcm nn_maxmin.py

  1. import torch
  2. import torch.nn.functional as F # 激励函数都在这
  3. import torch
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. import xlrd
  7. #### 数据预处理重要 使用Max-Min归一化 Z-Score效果不正常
  8. #### 数据选取可能重要
  9. # 读取数据
  10. data = xlrd.open_workbook(r'D:\00000MCM\0 codes\2020B\q3.xlsx') # datas q2xxhg
  11. # 转为ndarray
  12. table = data.sheet_by_index(0) #按索引获取工作表,0就是工作表1
  13. resArray = []
  14. for i in range(1, table.nrows): #table.nrows表示总行数 去除第一行
  15. line=table.row_values(i) #读取每行数据,保存在line里面,line是list
  16. resArray.append(line) #将line加入到resArray中,resArray是二维list
  17. resArray=np.array(resArray) #将resArray从二维list变成数组
  18. # print(resArray)
  19. # 数据归一化
  20. mins = np.min(resArray, axis=0)
  21. maxs = np.max(resArray, axis=0)
  22. gyh = (resArray - mins) / (maxs - mins)
  23. # gyh = resArray
  24. # 选择数据
  25. x = gyh[..., 2:] # 325,365
  26. y = gyh[..., 1] # 325,1 # 未使用第一列
  27. # 523/5=65 0 64,65 129,130 194,195 259,260 324
  28. # train_range = range(0, 259 + 1)
  29. # test_range = range(260, 324 + 1)
  30. train_range = [i for i in range(0, 259 + 1)] # 数据范围
  31. test_range = [i for i in range(260, 324 + 1)]
  32. train_n = len(train_range) # 数据数量
  33. test_n = len(test_range)
  34. x_train = x[train_range, ...]
  35. x_test = x[test_range, ...]
  36. y_train = y[train_range, ...]
  37. y_test = y[test_range, ...]
  38. # 转为tensor
  39. # xt = torch.tensor(x, dtype=torch.float32)
  40. # yt = torch.tensor(y, dtype=torch.float32)
  41. x_train_t = torch.tensor(x_train, dtype=torch.float32)
  42. x_test_t = torch.tensor(x_test, dtype=torch.float32)
  43. y_train_t = torch.tensor(y_train, dtype=torch.float32)
  44. y_test_t = torch.tensor(y_test, dtype=torch.float32)
  45. # 建立神经网络 优化器 损失函数
  46. class Net(torch.nn.Module): # 继承 torch 的 Module
  47. def __init__(self, n_feature, n_hidden, n_output):
  48. super(Net, self).__init__() # 继承 __init__ 功能
  49. # 定义每层用什么样的形式
  50. self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出
  51. self.predict = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出
  52. def forward(self, x): # 这同时也是 Module 中的 forward 功能
  53. # 正向传播输入值, 神经网络分析出输出值
  54. x = F.leaky_relu(self.hidden(x)) # 激励函数(隐藏层的线性值)
  55. x = self.predict(x) # 输出值
  56. return x
  57. in_fature = x.shape[1] if len(x.shape) == 2 else 1
  58. out_fature = y.shape[1] if len(y.shape) == 2 else 1
  59. net = Net(n_feature=in_fature, n_hidden=50, n_output=out_fature) # 365 125
  60. # print(net) # net 的结构
  61. optimizer = torch.optim.SGD(net.parameters(), lr=0.002) # 传入 net 的所有参数, 学习率
  62. loss_func = torch.nn.MSELoss() # 预测值和真实值的误差计算公式 (均方差)
  63. losses = []
  64. epochs = 500
  65. # 训练网络
  66. for t in range(epochs):
  67. # for i in range
  68. prediction = net(x_train_t) # 喂给 net 训练数据 x, 输出预测值
  69. loss = loss_func(prediction, y_train_t) * 1.0 # 计算两者的误差
  70. print('train' + str(t) + 'loss: ', end='')
  71. print(loss.item() / train_n) # 单个样本loss
  72. losses.append(loss.item())
  73. optimizer.zero_grad() # 清空上一步的残余更新参数值
  74. loss.backward() # 误差反向传播, 计算参数更新值
  75. optimizer.step() # 将参数更新值施加到 net 的 parameters 上
  76. # # 可视化训练过程
  77. # if t % 10 == 0:
  78. # plt.cla()
  79. # plt.scatter(x.data.numpy(), y.data.numpy())
  80. # plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
  81. # plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
  82. # if t<90:
  83. # plt.pause(0.1)
  84. # else:
  85. # plt.pause(1)
  86. # 画loss下降图
  87. pltx = range(epochs)
  88. plt.plot(pltx, losses)
  89. plt.show()
  90. # 测试
  91. net.eval()
  92. final_output = net(x_test_t)
  93. final_loss = loss_func(final_output, y_test_t) # 计算两者的误差
  94. print('final output loss: ', end='')
  95. print(final_loss.item() / train_n)
  96. # 画对比图
  97. pltxx = range(test_n) # 画图用x值
  98. final = np.array(final_output.detach()) # 测试结果 -> ndarray
  99. final_re = final * (maxs[1] - mins[1]) + mins[1] # final (65, 1) 需要减少维数final_re = final_re.squeeze()
  100. final_re = final_re.squeeze()
  101. final_true = y_test * (maxs[1] - mins[1]) + mins[1] # y_test (65, )
  102. plt.plot(pltxx, final_re)
  103. plt.plot(pltxx, final_true)
  104. # plt.legend()
  105. plt.show()
  106. # 误差计算
  107. err = final_re - final_true # 样本误差 (65, )
  108. final_mae = ((sum(abs(final_re - final_true)) / test_n) / (sum(abs(final_true)) / test_n)) * 100.0
  109. print('final output loss rate: ', end='')
  110. print(final_mae, end=' ')
  111. print('%')
  112. print('finish')