本文档是对课程内容的简单整理。
- 前缀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
clcclearclose all%% 加载数据 (模型)% [num_input,txt_input,raw_input]=xlsread('input') ;% [num_output,txt_output,raw_output]=xlsread('output') ;% input_0 = num_input(:,3:end);% input = num_input;% output = num_output;load('q3_21')% input% output% output = output(:, 2);% load('model_1')%% 数据预处理cut = 300;% 原始数据:样本*变量维度% data_train_input = input(1:cut,:);% data_train_output = output(1:cut,:);data_train_input = input; % 采用全部数据输入 神经网络默认分割为 70训练-15验证-15测试data_train_output = output;data_test_input = input(cut + 1:end,:);data_test_output = output(cut + 1:end,:);% 神经网络接收数据:转置 变量维度*样本input_train = data_train_input';output_train = data_train_output';input_test = data_test_input';output_test = data_test_output';%训练数据归一化[inputn,inputps] = mapminmax(input_train);[outputn,outputps] = mapminmax(output_train);% 定义网络net = newff(inputn, outputn, 50); % 获取 变量维度 变量维度 隐藏层神经元个数%参数设置net.trainParam.epochs=1000;%迭代次数net.trainParam.lr=0.4;%学习率net.trainParam.goal=0.00000000001;%收敛目标%神经网络训练net = train(net, inputn, outputn);% 保存网络save('model_1', 'net')%测试数据归一化inputn_test = mapminmax('apply', input_test, inputps);%神经网络测试输出an = sim(net,inputn_test);BPoutput = mapminmax('reverse', an, outputps);% 数据可视化% 数值figure(1)plot(BPoutput(1,:), '-', 'Color', [1 0.5 0], 'linewidth', 1.5) % 橘色hold onplot(output_test(1,:), '.', 'Color', [0 0.60 1], 'linewidth', 1.5, 'MarkerSize', 15); % 青蓝hold onplot(BPoutput(2,:),'k') %hold onplot(output_test(2,:),'g.');legend('模拟值(含硫量)','原始值(含硫量)','模拟值(辛烷值)','原始值(辛烷值)')% legend('模拟值(辛烷值)','原始值(辛烷值)')title('title')ylabel('ylabel')xlabel('xlabel')% axis([0 11, 85 95])% 误差err = abs(BPoutput - output_test);err_mean = mean(err, 1);figure(2)plot(err_mean,'-*')title('测试误差')ylabel('平均误差')xlabel('样本')% 数值百分比err_rate = err_mean ./ mean(output_test) * 100;figure(3)plot(err_rate,'-*')title('测试误差百分比')ylabel('平均误差百分比')xlabel('样本')
Python操作
需要归一化数据
D:\00000py\1\mcm nn_maxmin.py
import torchimport torch.nn.functional as F # 激励函数都在这import torchimport matplotlib.pyplot as pltimport numpy as npimport xlrd#### 数据预处理重要 使用Max-Min归一化 Z-Score效果不正常#### 数据选取可能重要# 读取数据data = xlrd.open_workbook(r'D:\00000MCM\0 codes\2020B\q3.xlsx') # datas q2xxhg# 转为ndarraytable = data.sheet_by_index(0) #按索引获取工作表,0就是工作表1resArray = []for i in range(1, table.nrows): #table.nrows表示总行数 去除第一行line=table.row_values(i) #读取每行数据,保存在line里面,line是listresArray.append(line) #将line加入到resArray中,resArray是二维listresArray=np.array(resArray) #将resArray从二维list变成数组# print(resArray)# 数据归一化mins = np.min(resArray, axis=0)maxs = np.max(resArray, axis=0)gyh = (resArray - mins) / (maxs - mins)# gyh = resArray# 选择数据x = gyh[..., 2:] # 325,365y = gyh[..., 1] # 325,1 # 未使用第一列# 523/5=65 0 64,65 129,130 194,195 259,260 324# train_range = range(0, 259 + 1)# test_range = range(260, 324 + 1)train_range = [i for i in range(0, 259 + 1)] # 数据范围test_range = [i for i in range(260, 324 + 1)]train_n = len(train_range) # 数据数量test_n = len(test_range)x_train = x[train_range, ...]x_test = x[test_range, ...]y_train = y[train_range, ...]y_test = y[test_range, ...]# 转为tensor# xt = torch.tensor(x, dtype=torch.float32)# yt = torch.tensor(y, dtype=torch.float32)x_train_t = torch.tensor(x_train, dtype=torch.float32)x_test_t = torch.tensor(x_test, dtype=torch.float32)y_train_t = torch.tensor(y_train, dtype=torch.float32)y_test_t = torch.tensor(y_test, dtype=torch.float32)# 建立神经网络 优化器 损失函数class Net(torch.nn.Module): # 继承 torch 的 Moduledef __init__(self, n_feature, n_hidden, n_output):super(Net, self).__init__() # 继承 __init__ 功能# 定义每层用什么样的形式self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出self.predict = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出def forward(self, x): # 这同时也是 Module 中的 forward 功能# 正向传播输入值, 神经网络分析出输出值x = F.leaky_relu(self.hidden(x)) # 激励函数(隐藏层的线性值)x = self.predict(x) # 输出值return xin_fature = x.shape[1] if len(x.shape) == 2 else 1out_fature = y.shape[1] if len(y.shape) == 2 else 1net = Net(n_feature=in_fature, n_hidden=50, n_output=out_fature) # 365 125# print(net) # net 的结构optimizer = torch.optim.SGD(net.parameters(), lr=0.002) # 传入 net 的所有参数, 学习率loss_func = torch.nn.MSELoss() # 预测值和真实值的误差计算公式 (均方差)losses = []epochs = 500# 训练网络for t in range(epochs):# for i in rangeprediction = net(x_train_t) # 喂给 net 训练数据 x, 输出预测值loss = loss_func(prediction, y_train_t) * 1.0 # 计算两者的误差print('train' + str(t) + 'loss: ', end='')print(loss.item() / train_n) # 单个样本losslosses.append(loss.item())optimizer.zero_grad() # 清空上一步的残余更新参数值loss.backward() # 误差反向传播, 计算参数更新值optimizer.step() # 将参数更新值施加到 net 的 parameters 上# # 可视化训练过程# if t % 10 == 0:# plt.cla()# plt.scatter(x.data.numpy(), y.data.numpy())# plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)# plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})# if t<90:# plt.pause(0.1)# else:# plt.pause(1)# 画loss下降图pltx = range(epochs)plt.plot(pltx, losses)plt.show()# 测试net.eval()final_output = net(x_test_t)final_loss = loss_func(final_output, y_test_t) # 计算两者的误差print('final output loss: ', end='')print(final_loss.item() / train_n)# 画对比图pltxx = range(test_n) # 画图用x值final = np.array(final_output.detach()) # 测试结果 -> ndarrayfinal_re = final * (maxs[1] - mins[1]) + mins[1] # final (65, 1) 需要减少维数final_re = final_re.squeeze()final_re = final_re.squeeze()final_true = y_test * (maxs[1] - mins[1]) + mins[1] # y_test (65, )plt.plot(pltxx, final_re)plt.plot(pltxx, final_true)# plt.legend()plt.show()# 误差计算err = final_re - final_true # 样本误差 (65, )final_mae = ((sum(abs(final_re - final_true)) / test_n) / (sum(abs(final_true)) / test_n)) * 100.0print('final output loss rate: ', end='')print(final_mae, end=' ')print('%')print('finish')
