优化算法 | 基于粒子群优化算法的Bp神经网络预测21~22赛季NBA总冠军(附MATLAB代码)


前言

一年一度的NBA总决赛即将开始,去年我们在 优化算法 | 基于GA的Bp神经网络预测20~21赛季NBA总冠军花落谁家这篇推文成功预测雄鹿为2021赛季NBA总冠军,今年我们继续预测21~22赛季NBA总冠军。

各位小伙伴可以点击下方投票,看看各位小伙伴支持勇士,还是支持凯尔特人。不管预测结果如何,希望总决赛的每一场比赛都能够精彩,这样球迷才能享受视觉盛宴。

今天我们准备用基于粒子群优化算法(PSO)的Bp神经网络为各位预测一下今年的NBA总冠军花落谁家?


一、数据准备

在查阅若干资料和文献后,粗略地归纳出影响一只球队夺冠的13个指标,分别如下:
1.季后赛球队场均投篮命中率
2.季后赛球队场均3分命中率
3.季后赛球队场均罚篮命中率
4.季后赛球队场均得分
5.季后赛球队场均篮板
6.季后赛球队场均助攻
7.季后赛球队场均抢断
8.季后赛球队场均盖帽
9.季后赛球队场均进攻篮板率
10.季后赛球队场均防守篮板率
11.季后赛球队场均失误率
12.球星数量
13.去年是否进入总决赛

在确认完影响因素后,https://www.basketball-reference.com/这个网站分别整理出2000~2021年冠亚军的上述13项指标数据,整理结果如下:

冠军球队数据
冠军球队数据

亚军球队数据
亚军球队数据

预测总冠军花落谁家,实际上就是根据球队的季后赛数据、球星数量、去年是否进入总决赛等因素来进行预测,冠军球队的输出结果是1,亚军球队的输出结果是0

冠军球队数据和亚军球队数据各选择18条数据作为训练数据,其余数据作为测试数据。其中P_train.txt作为训练输入,T_train.txt作为训练输出,P_test.txt作为测试输入,T_test.txt作为测试输出,2021.txt为勇士和凯尔特人今年季后赛数据,用于预测今年NBA总冠军。

P_train.txt数据如下:
P_train.txt

T_train.txt数据如下:
T_train.txt

P_test.txt数据如下:
P_test.txt

T_test.txt数据如下:
T_test.txt

2022.txt数据如下:
2022.txt

二、基于PSO的Bp神经网络预测

我们在MATLAB数学建模(六) | 粒子群优化(PSO)算法讲解 (上)这篇推文中讲解了PSO的基本思想,喜欢看视频教学的小伙伴可以在B站PSO教学进行学习。

1.粒子表达方式

假设我们构建的Bp神经网络为3层网络,则Bp神经网络中需要优化的参数实际上包含4部分:输入层到隐含层的权值、隐层神经元阈值、隐含层到输出层的权值、输出层阈值

假设输入层神经元个数用 i n p u t n u m inputnum inputnum 表示,输出层神经元个数用 o u t p u t n u m outputnum outputnum表示,则隐层神经元个数 h i d d e n n u m hiddennum hiddennum可以用如下公式计算:
h i d d e n n u m = 2 ∗ i n p u t n u m + 1 hiddennum=2*inputnum+1 hiddennum=2inputnum+1

因此,输入层到隐层的权值个数为 w 1 n u m = i n p u t n u m ∗ h i d d e n n u m w1num=inputnum*hiddennum w1num=inputnumhiddennum ,隐层到输出层的权值个数为 w 2 n u m = o u t p u t n u m ∗ h i d d e n n u m w2num=outputnum*hiddennum w2num=outputnumhiddennum ,Bp神经网络中待优化的变量的个数为 N = w 1 n u m + h i d d e n n u m + w 2 n u m + o u t p u t n u m N=w1num+hiddennum+w2num+outputnum N=w1num+hiddennum+w2num+outputnum

综上所述,一个粒子的变量数目为N。因为权值和阈值的初始值一般是在 [ − 0.5 , 0.5 ] [-0.5,0.5] [0.5,0.5]之间的随机数,所以,粒子的变量取值下限为 V a r M i n = − 0.5 VarMin=-0.5 VarMin=0.5 ,变量取值上限为 V a r M a x = 0.5 VarMax=0.5 VarMax=0.5 。速度取值上限为 V e l M a x = 0.1 ∗ ( V a r M a x − V a r M i n ) VelMax=0.1*(VarMax-VarMin) VelMax=0.1(VarMaxVarMin),速度取值上限为 V e l M i n = − V e l M a x VelMin=-VelMax VelMin=VelMax

2.目标函数

在当前权值和阈值下,Bp神经网络的预测性能怎么样,这里我们使用 n o r m ( T s i m − T t e s t ) norm(T_{sim}-T_{test}) norm(TsimTtest) 函数来进行评价, T s i m T_{sim} Tsim是预测结果, T t e s t T_{test} Ttest是测试数据的输出结果。 e r r err err预测结果与测试结果差的范数,范数越小说明预测得越准确,如果范数为0,说明预测得完全准确。

err=norm(T_sim-T_test);                         %预测结果与测试结果差的范数,范数越小说明预测得越准确,如果范数为0,说明预测得完全准确

3.粒子速度和位置的更新

粒子位置更新的目的是搜索到更好的解,随着粒子群位置的更新,搜索到的解的质量也随之提高。

PSO算法中粒子位置的更新离不开速度的影响,因此粒子位置更新的公式如下:
X i d k + 1 = X i d k + V i d k + 1 V i d k + 1 = ω V i d k + c 1 r 1 ( P i d k − X i d k ) + c 2 r 2 ( P g d k − X i d k ) \begin{array}{l} X_{i d}^{k+1}=X_{i d}^{k}+V_{i d}^{k+1} \\ V_{i d}^{k+1}=\omega V_{i d}^{k}+c_{1} r_{1}\left(P_{i d}^{k}-X_{i d}^{k}\right)+c_{2} r_{2}\left(P_{g d}^{k}-X_{i d}^{k}\right) \end{array} Xidk+1=Xidk+Vidk+1Vidk+1=ωVidk+c1r1(PidkXidk)+c2r2(PgdkXidk)
其中, k k k为迭代次数;
w w w为惯性权重, 其取值一般为随着迭代次数的增加从0.9到0.4线性递减;
X i d k + 1 X_{i d}^{k+1} Xidk+1为第 k + 1 k+1 k+1代粒子 i i i的位置;
X i d k X_{i d}^{k} Xidk为第 k k k代粒子 i i i的位置;
V i d k + 1 V_{i d}^{k+1} Vidk+1为第 k + 1 k+1 k+1代粒子 i i i的速度;
V i d k V_{i d}^{k} Vidk为第 k k k代粒子 i i i的速度;
P i d k P_{i d}^{k} Pidk为第 k k k代个体最优粒子 i i i的位置;
P g d k P_{g d}^{k} Pgdk为第 k k k代全局最优粒子的位置;
r 1 r_1 r1 r 2 r_2 r2 [ 0 , 1 ] [0,1] [0,1]之间的随机数;
c 1 c_1 c1 c 2 c_2 c2为常数。


三、MATLAB代码

目标函数代码如下:

%% 输入
% x:一个个体的初始权值和阈值
% P:训练样本输入
% T:训练样本输出
% hiddennum:隐含层神经元数
% P_test:测试样本输入
% T_test:测试样本期望输出
%% 输出
% err:预测样本的预测误差的范数
function [err,T_sim]=BpFunction(x,P,T,hiddennum,P_test,T_test)
inputnum=size(P,2);                                                 %输入层神经元个数
outputnum=size(T,2);                                                %输出层神经元个数
%% 数据归一化
[p_train,ps_train]=mapminmax(P',0,1);
p_test=mapminmax('apply',P_test',ps_train);
[t_train,ps_output]=mapminmax(T',0,1);
%% 开始构建BP网络
net=newff(p_train,t_train,hiddennum);                               %隐含层为hiddennum个神经元
%设定参数网络参数
net.trainParam.epochs=1000;
net.trainParam.goal=1e-3;
net.trainParam.lr=0.01;
net.trainParam.showwindow=false;                                    %高版MATLAB使用 不显示图形框
%% BP神经网络初始权值和阈值
w1num=inputnum*hiddennum;                                           %输入层到隐层的权值个数
w2num=outputnum*hiddennum;                                          %隐含层到输出层的权值个数
W1=x(1:w1num);                                                      %初始输入层到隐含层的权值
B1=x(w1num+1:w1num+hiddennum);                                      %隐层神经元阈值
W2=x(w1num+hiddennum+1:w1num+hiddennum+w2num);                      %隐含层到输出层的权值
B2=x(w1num+hiddennum+w2num+1:w1num+hiddennum+w2num+outputnum);      %输出层阈值
net.iw{1,1}=reshape(W1,hiddennum,inputnum);                         %为神经网络的输入层到隐含层权值赋值
net.lw{2,1}=reshape(W2,outputnum,hiddennum);                        %为神经网络的隐含层到输出层权值赋值
net.b{1}=reshape(B1,hiddennum,1);                                   %为神经网络的隐层神经元阈值赋值
net.b{2}=reshape(B2,outputnum,1);                                   %为神经网络的输出层阈值赋值
%% 开始训练
net = train(net,p_train,t_train);
%% 测试网络
t_sim = sim(net,p_test);
T_sim1 = mapminmax('reverse',t_sim,ps_output);                      %反归一化
T_sim=T_sim1';
err=norm(T_sim-T_test);                                             %预测结果与测试结果差的范数,范数越小说明预测得越准确,如果范数为0,说明预测得完全准确
index0= T_sim<0;                                                    %找到预测值小于0的索引
index1= T_sim>1;                                                    %找到预测值小于1的索引
penalty=1000*abs(sum(T_sim(index0)))+1000*sum(T_sim(index1)-1);     %预测值小于0或大于1会有惩罚
err=err+penalty;                                                    %总误差
end

主函数代码如下:

%% 基于PSO的Bp神经网络预测2022赛季NBA总冠军
%%%%%%%%%%%%%%%%%%%%%%% @copyright 微信公众号:优化算法交流地 %%%%%%%%%%%%%%%%%%%%%%%
clc;
clear;
tic
close all;
%% 加载神经网络的训练样本 测试样本每列一个样本 输入P 输出T
P=importdata('P_train.txt');                            %训练输入
T=importdata('T_train.txt');                         	%训练输出
P_test=importdata('P_test.txt');                        %测试输入
T_test=importdata('T_test.txt');                        %测试输出
cur_season=importdata('2022.txt');                      %雄鹿和太阳今年NBA季后赛数据,第1行为勇士队数据,第2行为凯尔特人队数据
inputnum=size(P,2);                                     %输入层神经元个数
hiddennum=2*inputnum+1;                                 %初始隐层神经元个数
outputnum=size(T,2);                                    %输出层神经元个数
w1num=inputnum*hiddennum;                               %输入层到隐层的权值个数
w2num=outputnum*hiddennum;                              %隐层到输出层的权值个数
N=w1num+hiddennum+w2num+outputnum;                      %待优化的变量的个数
%% 定义粒子群优化算法参数
nVar=N;                                                 %变量数目
VarSize=[1,nVar];                                       %变量矩阵大小
VarMin=-0.5;                                            %变量取值下限
VarMax=0.5;                                             %变量取值上限
MaxIt=200;                                              %最大迭代次数
nPop=50;                                            	%种群数目
w=1;                                                    %惯性权重
wdamp=0.99;                                             %惯性重量降低系数
c1=1.5;                                                 %个体学习系数
c2=2.0;                                                 %群体学习系数
VelMax=0.1*(VarMax-VarMin);                             %速度上限
VelMin=-VelMax;                                         %速度下限
%% 初始化
empty_particle.Position=[];
empty_particle.Cost=[];
empty_particle.Velocity=[];
empty_particle.Best.Position=[];
empty_particle.Best.Cost=[];
particle=repmat(empty_particle,nPop,1);
GlobalBest.Cost=inf;
for i=1:nPop
    %初始化位置
    particle(i).Position=unifrnd(VarMin,VarMax,VarSize);
    %初始化速度
    particle(i).Velocity=zeros(VarSize);
    %个体评价
    particle(i).Cost=BpFunction(particle(i).Position,P,T,hiddennum,P_test,T_test);
    %更新个体最优
    particle(i).Best.Position=particle(i).Position;
    particle(i).Best.Cost=particle(i).Cost;
    %更新群体最优
    if particle(i).Best.Cost<GlobalBest.Cost
        GlobalBest=particle(i).Best;
    end
end
BestCost=zeros(MaxIt,1);
%% 主循环
for it=1:MaxIt
    for i=1:nPop
        %更新速度
        particle(i).Velocity = w*particle(i).Velocity ...
            +c1*rand(VarSize).*(particle(i).Best.Position-particle(i).Position) ...
            +c2*rand(VarSize).*(GlobalBest.Position-particle(i).Position);
        %对超出范围的速度进行调整
        particle(i).Velocity = max(particle(i).Velocity,VelMin);
        particle(i).Velocity = min(particle(i).Velocity,VelMax);
        %更新位置
        particle(i).Position = particle(i).Position + particle(i).Velocity;
        %对超出位置范围的速度进行调整
        IsOutside=(particle(i).Position<VarMin | particle(i).Position>VarMax);
        particle(i).Velocity(IsOutside)=-particle(i).Velocity(IsOutside);
        %对超出范围的位置进行调整
        particle(i).Position = max(particle(i).Position,VarMin);
        particle(i).Position = min(particle(i).Position,VarMax);
        %种群评估
        particle(i).Cost=BpFunction(particle(i).Position,P,T,hiddennum,P_test,T_test);
        %更新个体最优
        if particle(i).Cost<particle(i).Best.Cost
            particle(i).Best.Position=particle(i).Position;
            particle(i).Best.Cost=particle(i).Cost;
            %更新群体最优
            if particle(i).Best.Cost<GlobalBest.Cost  
                GlobalBest=particle(i).Best;  
            end 
        end
    end
    BestCost(it)=GlobalBest.Cost;
    disp(['Iteration ' num2str(it) ': Best Cost = ' num2str(BestCost(it))]);
    w=w*wdamp;
end
BestSol=GlobalBest;
%% Results
figure;
%plot(BestCost,'LineWidth',2);
semilogy(BestCost,'LineWidth',2);
xlabel('迭代次数')
ylabel('误差的变化')
title('进化过程')
grid on;
fprintf(['最优初始权值和阈值:\n=',num2str(BestSol.Position),'\n最小误差=',num2str(BestSol.Cost),'\n'])
%% 预测今年总冠军概率
cur_test=zeros(size(cur_season,1),1);
[~,bestCur_sim]=BpFunction(BestSol.Position,P,T,hiddennum,cur_season,cur_test);
prob=softmax(bestCur_sim);                                     %将预测结果映射为和为1的概率
disp(['勇士队获得2021年NBA总冠军概率为',num2str(prob(1))]);
disp(['凯尔特人队获得2021年NBA总冠军概率为',num2str(prob(2))]);
toc
%%%%%%%%%%%%%%%%%%%%%%% @copyright 微信公众号:优化算法交流地 %%%%%%%%%%%%%%%%%%%%%%%

四、预测结果

预测结果如下:
在这里插入图片描述

预测结果为两支球队夺冠的概率几乎相等,究其原因两支队伍的基础数据和高阶数据都十分接近,所以难分伯仲。
2022.txt
此外,因为训练数据量较少,所以训练结果准确性有待提高,各位还是欣赏比赛、支持自己喜欢的球队吧。


五、代码获取方式

在公众号后台回复关键词 PSOBPNBA,即可提取本篇推文代码。


总结

本次推文使用基于PSO的Bp神经网络预测21~22赛季NBA总冠军,重点讲解粒子的编码方式、目标函数和粒子速度和位置的更新,最终预测结果为两支球队夺冠概率各为50%。当然了,会有小伙伴说,我蒙的比这预测都准,反正都是一半一半的概率。不过,我们讲解的是思想,各位领会到了思想,我们的教学就达到目的了。


咱们下期再见

近期你可能错过了的好文章

新书上架 | 《MATLAB智能优化算法:从写代码到算法思想》

优化算法 | 灰狼优化算法(文末有福利)

优化算法 | 鲸鱼优化算法

遗传算法(GA)求解带时间窗的车辆路径(VRPTW)问题MATLAB代码

粒子群优化算法(PSO)求解带时间窗的车辆路径问题(VRPTW)MATLAB代码

知乎 | bilibili | CSDN:随心390

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值