本文档是对课程内容的简单整理。
- 前缀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
clc
clear
close 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 on
plot(output_test(1,:), '.', 'Color', [0 0.60 1], 'linewidth', 1.5, 'MarkerSize', 15); % 青蓝
hold on
plot(BPoutput(2,:),'k') %
hold on
plot(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 torch
import torch.nn.functional as F # 激励函数都在这
import torch
import matplotlib.pyplot as plt
import numpy as np
import xlrd
#### 数据预处理重要 使用Max-Min归一化 Z-Score效果不正常
#### 数据选取可能重要
# 读取数据
data = xlrd.open_workbook(r'D:\00000MCM\0 codes\2020B\q3.xlsx') # datas q2xxhg
# 转为ndarray
table = data.sheet_by_index(0) #按索引获取工作表,0就是工作表1
resArray = []
for i in range(1, table.nrows): #table.nrows表示总行数 去除第一行
line=table.row_values(i) #读取每行数据,保存在line里面,line是list
resArray.append(line) #将line加入到resArray中,resArray是二维list
resArray=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,365
y = 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 的 Module
def __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 x
in_fature = x.shape[1] if len(x.shape) == 2 else 1
out_fature = y.shape[1] if len(y.shape) == 2 else 1
net = 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 range
prediction = 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) # 单个样本loss
losses.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()) # 测试结果 -> ndarray
final_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.0
print('final output loss rate: ', end='')
print(final_mae, end=' ')
print('%')
print('finish')