《量化投资:以MATLAB为工具》

MATLAB技术论坛

 找回密码
 注册账号
查看: 1832|回复: 5
收起左侧

[源码] BP网络回归k-fold交叉验证求最佳隐藏层神经元数目及建立最好模型

[复制链接]
发表于 2015-11-11 14:47:18 | 显示全部楼层 |阅读模式
%该代码可用于k-fold交叉验证建立模型,可以修改代码中的CV值;
%该代码首先需要一个txt的文本,要求all.txt,tab分割,最后一行为Y值,前面的所有行为X1,X2,...,Xn;
%all.txt文件和BP1.m及BP2.m放在同一个文件下,加入MATLAB路径;修改bp1.m的all.txt文件路径;
%可以输出mse,R^2等指标,通过交叉验证得到最佳的模型后,用于外部数据集的预测


%%%%%%BP1代码
% BP 神经网络算法
% 载入数据并将数据分成训练和预测两类

all=load('F:\matlab\work\BP\all.txt');
D=size(all);
a=349; %%  training_set_samples;  
%%如果你有20个样本,可以选取前a个样本做训练,剩下的就是外部测试集合了,这里我有500个样本,选取前349个做的训练集,训练集被分为5分;交叉训练
trainx=all(1:a,1:(D(1,2)-1));
trainy=all(1:a,D(1,2));
Experimental_X=all(a+1:D(1:1),1:(D(1,2)-1));
Experimental_Y=all(a+1:D(1:1),D(1,2));

p_train=trainx;
t_train=trainy;
desired_net=[];


%% 交叉验证
Hidden_layers=[];
R_sq_min=0.001;
desired_input=[];
desired_output=[];
result_perfp=[];
cv=5;  %%%5-fold cross validation
indices = crossvalind('Kfold',length(p_train),cv);
h=waitbar(0,'正在寻找最优化参数....');
k=1;
for i = 1:cv
    perfp=[];
    disp(['以下为第',num2str(i),'次交叉验证结果']);
    testa = (indices == i); traina = ~testa;
    p_cv_train=p_train(traina,:);  %%CV_train_X : p_cv_train
    t_cv_train=t_train(traina,:); %%CV_train_Y : t_cv_train
    p_cv_test=p_train(testa,:); %%%%CV_test_X : p_cv_test
    t_cv_test=t_train(testa,:); %%%%CV_test_Y : t_cv_test
    p_cv_train=p_cv_train';
    t_cv_train=t_cv_train';
    p_cv_test= p_cv_test';
    t_cv_test= t_cv_test';
    [p_cv_train,PS1]=mapminmax(p_cv_train,0,1);%%归一化输入,X的都是PS1
        [t_cv_train,PS2]=mapminmax(t_cv_train,0,1);%%归一化输出,Y的都是PS2
    p_cv_test=mapminmax('apply',p_cv_test,PS1);%%归一化
    for S=4:1:27
        net=newff(p_cv_train,t_cv_train,S,{'tansig','purelin'},'trainlm');
        net = init(net);
                net.trainParam.epochs=2000;
                net.trainParam.goal=0.003;
                net.trainParam.show=50;
                net.divideParam.trainRatio=1;
        net.divideParam.valRatio=0;
        net.divideParam.testRatio=0;
                net=train(net,p_cv_train,t_cv_train);
        waitbar(k/116,h);
        disp(['当前隐藏层节点数为', num2str(S)]);
        test_Out=sim(net,p_cv_test);
        test_Out=mapminmax('reverse',test_Out,PS2);%%反归一化
               
        train_Out=sim(net,p_cv_train);
        train_Out=mapminmax('reverse',train_Out,PS2); %%反归一化

        error_test=t_cv_test-test_Out;
                R_test=corrcoef(t_cv_test,test_Out);
               
                tt_cv_train=mapminmax('reverse',t_cv_train,PS2);%%反归一化
                error_train=tt_cv_train-train_Out;
                R_train=corrcoef(tt_cv_train,train_Out);
               
                test_R_Square=R_test(2:2)*R_test(2:2);
                train_R_Square=R_train(2:2)*R_train(2:2);       
               
        disp(['当前网络训练集的mse为',num2str(mse(error_train)),'        ','当前网络训练集的R^2为',num2str(train_R_Square),'        ','当前网络测试集的mse为',num2str(mse(error_test)),'        ','当前网络测试集的R^2为',num2str(test_R_Square)])
        perfp=[perfp mse(error_test)];
         if test_R_Square>R_sq_min
            R_sq_min=test_R_Square;
            desired_spread=S;
            desired_net=net;
            desired_input=mapminmax('reverse',p_cv_train,PS1);%fan归一化预测集的
            desired_input=desired_input';
            desired_output=mapminmax('reverse',t_cv_train,PS2);%fan归一化预测集的
            desired_output=desired_output';
        end
        k=k+1;
    end
    result_perfp(i,:)=perfp;
end;
close(h)
disp(['最佳隐藏层神经元数目为',num2str(desired_spread),'最佳的测试集的R^2为',num2str(R_sq_min)])

%%%bp2.m 得到最佳的模型后,外部数据来仿真测试:
%% 采用最佳BP模型仿真
[fold_input,PSX]=mapminmax(desired_input',0,1);%%归一化输入
[fold_output,PSY]=mapminmax(desired_output',0,1);%%归一化输出
% net=newgrnn(Train_X,Train_Y,0.25); %%建立GRNN模型


predicted_X=mapminmax('apply',Experimental_X',PSX);%归一化预测集的输入
Predicted_Y=sim(desired_net,predicted_X);%%利用模型net预测Y

Predicted_Y=mapminmax('reverse',Predicted_Y,PSY); %%将预测的Y值反归一化
Predicted_Y=Predicted_Y';

grnn_error=Experimental_Y-Predicted_Y;
grnn_R=corrcoef(Experimental_Y,Predicted_Y);
grnn_R_Square=grnn_R(2:2)*grnn_R(2:2);

disp(['测试集的mse为',num2str(mse(grnn_error)),'        ','测试集的R^2为',num2str(grnn_R_Square)])


Train_X=mapminmax('apply',trainx',PSX);%归一化预测集的输入
Train_pY=sim(desired_net,Train_X);%%利用模型net,输入训练X,输出Y
Train_pY=mapminmax('reverse',Train_pY,PSY);%%反归一化
Train_pY=Train_pY'; %%转职
grnn_train_error=trainy-Train_pY;
grnn_train_R=corrcoef(trainy,Train_pY);
grnn_train_R_Square=grnn_train_R(2:2)*grnn_train_R(2:2);

disp(['训练集mse为',num2str(mse(grnn_train_error)),'        ','训练集R^2为',num2str(grnn_train_R_Square)])
 楼主| 发表于 2015-11-11 14:50:41 | 显示全部楼层
代码可以下载:上传

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册账号

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-11-11 16:26:34 | 显示全部楼层
没人顶一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-11-11 16:29:16 | 显示全部楼层
大家都来讨论一下吧~
回复 支持 反对

使用道具 举报

发表于 2015-11-11 20:40:34 | 显示全部楼层
几个输入,几个输出呀?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-11-12 18:46:14 | 显示全部楼层
taotaowang 发表于 2015-11-11 20:40
几个输入,几个输出呀?

我这里是26个输入,1个输出,程序默认一个输出,即最后一列,前面的都认为是输入
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|网站地图|MATLAB技术论坛|Simulink仿真论坛 ( 蜀ICP备19014457号 

GMT+8, 2019-10-17 06:21 , Processed in 0.104707 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表