MATLAB神经网络(四):基于Adaboost的强分类器设计

Adaboost算法的思想是合并多个“弱”分类器的输出以产生有效分类。其主要步骤为:首先给出弱学习算法和样本空间(x,y),从样本空间中找出m组训练数据,每组训练数据的权重都是1/m。然后用弱学习算法迭代运算T次,每次运算后都按照分裂结果更新训练数据权重分布,对于分类失败的训练个体赋予较大权重,下一次迭代运算时更加关注这些训练个体。弱分类通过反复迭代得到一个分类函数序列f1,f2,f3.....fT,每个分类函数赋予一个权重,分裂结果越好的函数,其对应权重越大。T次迭代之后,最终强分类函数F由弱分类函数加权得到。

本例为公司财务预警系统,通过公司的各项指标综合评价并预测公司财务状况、发展趋势和变化,为决策者科学决策提供智力支持。指标可分为表内信息指标、盈利能力指标、偿还能力指标、成长能力指标、现金流量指标和表外信息指标六大指标,每项大指标又分为若干小指标,如盈利能力指标又可分为净资产收益率、总资产报酬率、每股收益、主营业务利润率和成本费用利润率等。在用于公司财务预警如果对所有指标都进行评价后综合,模型过于复杂,并且各指标间相关性较强,,因此在模型建立前需要筛选指标。

指标筛选分为显著性分析和因子分析两步。显著性分析通过T检验分析ST公司和非ST公司,在财务指标中找出差别较大、能够明显区分两类公司的财务指标。因子分析在显著性分析基础上对筛选出来的指标计算主成分特征值,从中找出特征值大的指标为公司预警方法的最终评价指标。

load data input_train output_train input_test output_test

%测试样本权重
[mm,nn]=size(input_train);
D(1,:)=ones(1:nn)/nn;

弱分类器学习分类:把BP神经网络看作弱分类器,经过训练后分类训练样本,并且根据训练样本分类结果调整训练样本权重值,最终得出一系列弱分类器权重。

K=10; %弱分类器数量
for i=1:K
      %训练样本归一化
      [inputn,inputps=mapminmax(input_train);
      [outputn,outputps]=mapminmax(output_train);
      error(i)=0;
     
       %BP神经网络构建
       net=newff(inputn,outputn,6);
       net.trainParam.epochs=4;
       net.trainParam.lr=0.1;
       net.trainParam.goal=0.0004;
 
       %BP神经网络训练
       net=train(net,inputn,outputn);
  
       %训练数据预测
       an1=sim(net.inputn);
       test_simul(i,:)=mapminmax('reverse',an1,outputps)
       %测试数据预测
       input_test=mapminmax('apply',input_test,inputps);
       an2=sim(net,inputn_test);
       test_simu(i,:)=mapminmax('reverse',an,outputps);
       %统计输出结果
       kk1=find(test_simu(i,:)>0);
       kk2=find(test_simu(i,:)<0);
       aa(kk1)=1;
       aa(kk2)=-1;
      
       %统计错误样本数
      for j=1:nn
             if aa(j)~-output_train(j);
                    error(i)=error(i)+D(i,j);
             end
       end
       %弱分类器i权重
       at(i)=0.5*log((1-error(i))/error(i));
       %更新D值
       for j=1:nn
             D(i+1,j)=D(i,j)*exp(-at(i)*aa(j)*test_simu(i,j));
        end
       
       %D值归一化
        Dsum=sum(D(i+1,:));
        D(i+1,:)=D(i+1,:)/Dsum;
       end

强分类器分类和结果统计

由10组弱分类器BP网络组成强分类器对分析样本进行分类,并统计分类误差。

%强分类器分类结果
output=sign(at*test_simu);
%统计强分类器每类分类错误个数
kkk1=0;
kkk2=0;
for j=1:350
  if output(j)==1
     if output(j)~=output_test(j)
        kkk1=kkk1+1;
      end
  end

  if output(j)==-1
    if output(j)~=output_test(j)
       kkk2=kkk2+1;
      end
  end
end

%统计弱分类器每类分类误差个数
for i=1:K
     error1(i)=0;
     kk1=find(test_simu(i,:)>0);
     kk2=find(test_simu(i,:)<0);
    
     aa(kk1)=1;
     aa(kk2)=-1;

 for j=1:350
     if aa(j)~=output_test(j);
         error1(i)=error1(i)+1;
     end
   end
end

Adaboost方法不仅可以用于设计强分类器,还可以用于设计强预测器。强预测器设计思路与强分类器类似,都是先赋予测试样本权重,然后根据弱预测器预测结果调整测试样本权重并确定弱预测器权重,最后把弱预测器序列作为强预测器。不同的是在强分类器中增加预测错类别样本的群众,在强预测器增加预测误差超过阈值的样本黔中,采用BP_Adaboost强预测器预测第2章中非线性函数输出,函数形式为

[公式]

步骤分为:
数据集选择:从样本空间中选择训练样本,测试样本,并对测试样本分配权重。

%下载数据
load data1 input output
%从中随机选择1900组训练数据和100组测试数据
k=rand(1:2000);
[x,n]=sort(k);
%训练样本
input_train=input(n(1:1900),:)';
output_train=output(n(1:1900),:)';
%测试样本
input_test=input(n(1901:2000),:)';
output_test=output(n(1901:2000),:)';
%归一化
[inputn,inputps]=mapminmax(input_train);
[outputn,outputps]=mapminmax(output_train);
%样本权重
[mm,nn]=size(input_train);
D(1,:)=ones(1,nn)/nn; 

弱预测器学习预测

K=10;
%循环开始
for i=1:K
     %弱预测器训练
     net=newff(inputn.outputn,5);
     net.trainParam.epochs=20;
     net.trainParam.lr=0.1;
     net.train(net,inputn,outputn);

     %弱预测器预测
     an1=sim(net,inputn);
     BPoutput=mapminmax('reverse',an1,outputps);
     %预测误差
     erroryc(i,:)=output_train-BPoutput
     %测试数据预测
     inputn1=mapminmax('apply',input_test,inputps)
     an2=sim(net,inputn1);
     test_simu(i,:)=mapminmax('reverse',an2,outputps);
   
     %调整D值
     Error(i)=0;
     for j=1:nn
          if abs(erroryc(i,j))>0.1 %误差超过阈值
               Error(i)=Error(i)+D(i,j);
               D(i+1,j)=D(i,j)*1.1;
          else
               D(i+1,j)=D(i,j);
          end
      end

      %D值归一化
      at(i)=0.5/exp(abs(Error(i))); %log(1-Error(i))/Error(i));
      D(i+1,:)=D(i+1,:)/sum(D(i+1,:));
   end

强预测器预测

把10组弱预测器函数组成强预测器预测输出,并比较强预测器预测误差和弱预测器预测误差

%弱预测器权重归一化
at=at/sum(at);

%强预测器预测结果
output=at*test_simu;
%强预测器预测误差
error=output_test-output;

%弱预测器预测误差
for i=1:10
   error1(i,:)=test_simu(i,:)-output;
end

%误差比较
plot(abs(error),'-*')
hold on
plot(abs(error1)),'-or')
title('强预测器预测误差绝对值','fontsize',12)
xlabel('预测样本','fontize',12)
ylabel('误差绝对值','fontsize',12)
legend('强预测器预测','弱预测器预测')