精华内容
下载资源
问答
  • 先用动态聚类法对福州市居民历史用电负荷进行聚类分析以获得一个样本空间,在此基础上采用偏最小二乘回归方法进行建模和短期负荷预测分析
  • 对医院病床周转次数及相关多变量时间序列数据拟合动 态回归,很好的建模方法
  • 文章目录 一、题目 二、分享 一、题目 C题 中... 二、分享 需要附件数据请移步 2020数学建模国赛A-E题 关于动态规划的具体解说请移步 动态规划------求解决策过程中最优化的数学方法 关于动态规划的相关资料可以参考 ...

    一、题目

    C题 中小微企业的信贷决策

    在实际中,由于中小微企业规模相对较小,也缺少抵押资产,因此银行通常是依据信贷政策、企业的交易票据信息和上下游企业的影响力,向实力强、供求关系稳定的企业提供贷款,并可以对信誉高、信贷风险小的企业给予利率优惠。银行首先根据中小微企业的实力、信誉对其信贷风险做出评估,然后依据信贷风险等因素来确定是否放贷及贷款额度、利率和期限等信贷策略。
    某银行对确定要放贷企业的贷款额度为万元;年利率为4%15%;贷款期限为1年。附件13分别给出了123家有信贷记录企业的相关数据、302家无信贷记录企业的相关数据和贷款利率与客户流失率关系的2019年统计数据。该银行请你们团队根据实际和附件中的数据信息,通过建立数学模型研究对中小微企业的信贷策略,主要解决下列问题:
    (1) 对附件1中123家企业的信贷风险进行量化分析,给出该银行在年度信贷总额固定时对这些企业的信贷策略。
    (2) 在问题1的基础上,对附件2中302家企业的信贷风险进行量化分析,并给出该银行在年度信贷总额为1亿元时对这些企业的信贷策略。
    (3) 企业的生产经营和经济效益可能会受到一些突发因素影响,而且突发因素往往对不同行业、不同类别的企业会有不同的影响。综合考虑附件2中各企业的信贷风险和可能的突发因素(例如:新冠病毒疫情)对各企业的影响,给出该银行在年度信贷总额为1亿元时的信贷调整策略。

    附件1 123家有信贷记录企业的相关数据
    附件2 302家无信贷记录企业的相关数据
    附件3 银行贷款年利率与客户流失率关系的2019年统计数据

    附件中数据说明:
    (1) 进项发票:企业进货(购买产品)时销售方为其开具的发票。
    (2) 销项发票:企业销售产品时为购货方开具的发票。
    (3) 有效发票:为正常的交易活动开具的发票。
    (4) 作废发票:在为交易活动开具发票后,因故取消了该项交易,使发票作废。
    (5) 负数发票:在为交易活动开具发票后,企业已入账记税,之后购方因故发生退货并退款,此时,需开具的负数发票。
    (6) 信誉评级:银行内部根据企业的实际情况人工评定的,银行对信誉评级为D的企业原则上不予放贷。
    (7) 客户流失率:因为贷款利率等因素银行失去潜在客户的比率。

    二、分享

    需要附件数据请移步

    2020数学建模国赛A-E题

    关于动态规划的具体解说请移步

    动态规划------求解决策过程中最优化的数学方法

    关于动态规划的相关资料可以参考
    https://blog.csdn.net/weixin_45870610/article/details/108411295文末提供的资料

    神经网络预测财务危机

    判别分析法预测借款人在一定时期内的信用状况(违约或不违约、破产或不破产)

    回归分析:将数据归一化处理,再得出总和风险评分

    展开全文
  • 然后,我们应用了回归模型,ETS(误差,趋势,季节性)模型,季节性ARIMA(自回归,积分,移动平均值)模型和动态回归模型来进一步分解数据并进行预测。 最后,我们基于参数RMSE评估了预测的模型性能。 所有项目...
  • MATLAB回归分析

    千次阅读 2014-12-30 07:35:35
    数据预处理 1.计算每年每一个变量的基本统计量:均值,标准差,中位数;并用折线图给出原始数据和均值、中位数的...每年各变量频数直方图的变化趋势,可做动态图。 利用MATLAB作图如下:   (此频数直方图是动

    数据预处理

    1.计算每年每一个变量的基本统计量:均值,标准差,中位数;并用折线图给出原始数据和均值、中位数的变化趋势。

    由所给的《中国企业商品价格指数数据99年至今》数据,利用MATLAB,很容易计算出结果,并画出折线图。

    折线图如下:

     

    2.给出各变量按季节变化趋势;每年各变量频数直方图的变化趋势,可做动态图。

    利用MATLAB作图如下:

     

    (此频数直方图是动态图)

    3. 按原始数据,指出被解释变量和每解释变量之间的关系,画图;

    利用MATLAB分别作图如下:

    从图中可以看出,随着农产品价格指数的增长,总指数有线性增长的趋势,所以总指数与农产品价格指数有线性关系。

    从图中可以看出,随着矿产品价格指数的增长,总指数有线性增长的趋势,所以总指数与矿产品价格指数有线性关系。

    从图中可以看出,随着煤油电价格指数的增长,总指数有线性增长的趋势,所以总指数与煤油电价格指数有线性关系。

    4.按年平均数、中位数预处理数据,指出被解释变量和每个解释变量之间的关系,画图;

    利用MATLAB,分别作图如下:

    从图中可以看出,对于每个解释变量(各个价格指数中均值),随着其增长,被解释变量(总指数均值)都有线性增长的趋势,所以被解释变量与每个解释变量分别有线性关系。

    从图中可以看出,对于每个解释变量(各个价格指数均中位数),随着其增长,被解释变量(总指数中位数)都有线性增长的趋势,所以被解释变量与每个解释变量分别有线性关系。

    (本节MATLAB代码见附录一)

    一元回归分析

    基本模型

    下面先从简单入手,由上节数据预处理第三问求解得出,总指数y与农产品价格指数x之间存在线性关系,所以,可以建立以下一元线性回归模型:

    y i= β0+β1xi+ε ,   i=1,2……,191

    εi独立同分布,其分布为N(0,σ2

    由数据(xi,yi)(i=1,2……,191)可获得β0β1的估计 称

    为y关于x的回归方程,,为回归系数,

    εi是随机误差。

    模型求解

    利用MATLAB统计工具箱,得到模型的回归系数估计值及其置信区间(置信水平α=0.05)、检验统计量R2,F,p,s2

     

     

    回归系数

    回归系数估计值

    回归系数估计值

    43.5577

       [39.1754 ,47.9401]

         

       0.5606

    [ 0.5184 ,0.6028]

    R2= 0.7839   F=685.6542   p<0.0001   s2 =4.4997

    残差图如下:

    剔除异常值后,再对模型进行求解,结果见下表:

    回归系数

    回归系数估计值

         回归系数估计值

    46.6171

          [43.0129,50.2213]

         

      0.5323

     [0.4976,0.5670]

    R2= 0.8391   F=917.7627   p<0.0001   s2 =2.9046

     

     

    回归方程为:= 46.6171+0.5323x

    结果分析

    R2=0.8391是指因变量y的83.91%可由模型确定。F=917.7627远大于临界值,p远小于α,说明回归方程显著。

    同时,回归系数置信区间不包含0,说明回归变量对因变量y的影响是显著的。

    综上,该模型是可用的。

    (本节代码见附录二)

    多元回归分析

    基本模型

     

    由上节数据预处理第三问求解得出,总指数y与农产品价格指数x1、矿产品价格指数x2,煤油电价格指数x3之间均存在线性关系,故而,建立如下多元线性回归模型:

    yi= β0+β1X1i+β2X2i+β3X3i+ε ,   i=1,2……,191

    εi独立同分布,其分布为N(0,σ2

    由数据(x1i,x2i,x3i,yi)(i=1,2……,191)可获得β0β1β2β3的估计 称

    为y关于x1,x2,x3的回归方程,,为回归系数,εi是随机误差。

     

    模型求解

    利用MATLAB统计工具箱,得到模型的回归系数估计值及其置信区间(置信水平α=0.05)、检验统计量R2,F,p,s2。结果见下表:

     

    回归系数

    回归系数估计值

        回归系数置信区间

    32.5824

    [30.6793,34.4855]

    0.3742

    [0.3485,0.4001]

        

    0.1372

    [0.1087,0.1656]

        

    0.1503

    [0.1312,0.1693]

    R2 = 1.0000  F=2008.4  p<0.0001  s2 = 0.6000

    残差图如下:

     

    剔除异常值后,再对模型进行求解,结果见下表:                                                                                                                                                    

    回归系数

    回归系数估计值

       回归系数置信区间

             32.6886

    [30.9173,34.4598]

    0.3771

    [0.3532,0.4010]

       

    0.1313

    [0.1051,0.1575]

       

    0.1524

    [0.1347,0.1701]

    R2= 1.0000 F=2291.3   p<0.0001  s2 = 0.5000

     

    回归方程:

                                                                

    = 32.6886+0.3771x1+0.1313x2+0.1524x3

    结果分析

    R2近似等于1,说明回归方程非常显著。F=2291.3远远大于临界值,p远远小于α,故而同样说明回归方程显著。

    同时,回归系数置信区间均不包含0,说明各个回归变量对因变量y的影响是显著的。

    综上,该模型是非常好的。

    (本节代码见附录三)

    时间序列模型

    问题分析

    题目所给的原始数据是以时间为序的,称时间序列。许多经济数据在时间上有一定的滞后性,实际上,在对时间序列做回归分析时,随机误差实际上,在对时间序列做回归分析时,随机误差εi有可能存在相关性,违背模型关于εi(对时间)相互独立的基本假设,同一变量的顺序观测值之间出现相关现象(称为自相关)是很自然的。然而一旦数据中存在这种自相关序列,如果仍采用普通的回归模型直接处理,将会出现不良结果,其预测也就失去了意义。为此,我们必须先来诊断数据是否存在自相关,如果存在,就要考虑自相关关系,建立新的回归模型。

    残差ei = yi -可以作为εi估计值,画出ei– ei-1的散点图,能够从直观上判断εi的自相关性。由前面多元线性回归模型得到残差ei,作出ei– ei-1的散点图

    如下:

    可以看到:大部分点都落到了第一、第三象限中,表明εi存在正的自相关。

    为了对εi的自相关性作定量诊断,并在诊断后得到新的结果,我们考虑如下的模型

    yi= β0+β1X1i+β2X2i+β3X3i+ε,εi = ρεi-1+ui

    其中,ρ是相关系数,ui相互独立且服从均值为0的正态分布。

    ρ= 0,则退化为普通的回归模型;若ρ>0,则εi存在正的自相关;若ρ<0,则εi存在负的自相关。

    下面做定量检验,即Durbin-Watson检验(简称D-W检验),计算DW统计量:

    DW =

    经过简单的运算可知,当n较大时,

     

     

    DW

     

                                                                  

    正是自相关系数ρ的估计值,于是 = 1 – DW/2。若在1附近,即DW在0或4附近,εi的自相关性很强。

    基本模型

    要根据DW的具体数值确定εi是否存在自相关,应该在给定的检验水平下,依照样本容量和回归变量数目,查D-W分布表,得到检验的临界值dL和dU,继而作出判断[1]

    计算可得DW= 0.3014<dL, =0.8493,α= 0.05,n=183,k=4,查表知,εi存在自相关。

    作变换

                                   

     

    然后,利用变换后的数据重新估计。

    模型求解

    利用MATLAB工具箱计算,得到结果如下表:

    回归系数

    回归系数估计值

        回归系数置信区间

          6.0977

    [5.6641,6.5313]

          0.2714

    [0.2438,0.2989]

       

          0.1875

    [0.1610,0.2139]

       

          0.1271

    [0.1071,0.1471]

    R2 = 0.9124  F=618.2362  p<0.0001  s2 = 0.1071

                                                                  

     

     

    回归方程:

      

    把、、、还原为原始变量、、、得到结果为

     

     

                                         

    结果分析

    对上述模型在进行一次自相关检验,即诊断随机误差ui是否还存在自相关。计算出DW = 1.4430,α= 0.05,n=182,k=4 ,查表知,du<DW<4-du。即随机误差ui不存在自相关。

    基于时间序列模型的回归模型与前面的多元线性回归预测值,如下图:

       

    基于时间序列模型的回归模型与前面的多元线性回归残差图,如下图:

     

    从两图中易知,基于时间序列,即加入自相关后的模型更贴近实际,预测结果更好,也就是说其更适合。

    参考文献   

    [1]何晓群,刘文卿.应用回归分析.清华大学出版社,2001.

    [2]姜启源,谢金星.数学模型(第四版).高等教育出版社.2012.

    附录一

    load data

    year = 1999 : 2014;

    for i = 1 : 4

       for j = 1 : 15

           jun_zhi(j,i) = mean(data((j-1)*12+1 : j*12 ,i+1));

           biao_zhun_cha(j,i) = std(data((j-1)*12+1 : j*12 ,i+1));

           zhong_wei_shu(j,i) = median(data((j-1)*12+1 : j*12 ,i+1));

       end

    end

    for i = 1 : 4

       jun_zhi(16,i) = mean(data(181:191,i+1));

       biao_zhun_cha(16,i) = std(data(181:191,i+1));

       zhong_wei_shu(16,i) = median(data(181:191,i+1));

    end

    %完成数据的初始化

    %开始绘制原始数据折线图

    plot(data(:,1),data(:,2:5),'-*')

    legend('总产品','农产品','矿产品','煤油电')

    title('原始数据折线图')

    xlabel('时间')

    ylabel('商品价格指数')

    %完成原始数据折线图的绘制

    %开始绘制均值和中位数的折线图

    figure;

    plot(year,jun_zhi,'-*')

    legend('总产品','农产品','矿产品','煤油电')

    title('商品价格指数均值折线图')

    xlabel('时间')

    ylabel('均值')

    figure;

    plot(year,zhong_wei_shu,'-*')

    legend('总产品','农产品','矿产品','煤油电')

    title('商品价格指数中位数折线图')

    xlabel('时间')

    ylabel('中位数')

    %完成均值和中位数的折线图的绘制

    %开始均值按季度变化绘图

    ones(63,4);

    for i=1:63

       jun_zhi_season(i,:) = (data(i*3-2,2:5)...

           +data(i*3-1,2:5)+data(i*3,2:5))./3;

    end

    x_season = 1:63;

    figure;

    plot(x_season,jun_zhi_season,'-*');

    xlabel('季度(1-63代表顺序的63个季度)');

    ylabel('季度均值');

    legend('总产品','农产品','矿产品','煤油电');

    title('各变量按季节变化趋势');

    %完成均值按季度变化图形的绘制

    % 动态频数直方图

    data_dymic = sort(data(:,2:5));

    temp = data_dymic(191,:);

    data_dymic(3:191,:) = data_dymic(2:190,:);

    data_dymic(2,:)= temp;

    i=1;

    figure;

    while(i<=190)

       subplot(2,2,1);

           hist(data_dymic(1:i+1,1),5);

           axis([90 112 0 70]);

           title('总指数频数直方图');

       subplot(2,2,2);

           hist(data_dymic(1:i+1,2),5);

           axis([90 125 0 70]);

           title('农产品价格指数频数直方图');

       subplot(2,2,3);

           hist(data_dymic(1:i+1,3),5);

           axis([80 125 0 70]);

           title('矿产品价格指数频数直方图');

        subplot(2,2,4);

           hist(data_dymic(1:i+1,4),5);

           axis([80 130 0 65]);

           title('煤油电价格指数频数直方图');

           pause(0.01);

        i = i+1;

    end

     %结束动态图的绘制

     %开始总指数其他各个指数之间关系的散点图并拟合的绘制

    all = data(:,2);

    agriculture = data(:,3);

    mining = data(:,4);

    coe = data(:,5);

    figure;

    A = polyfit(agriculture,all,1);    %拟合

    all2 = polyval(A,agriculture);

    plot(agriculture,all,'b*',agriculture,all2,'r-')

    title('总指数与农产品价格指数的关系图');

    xlabel('农产品价格指数');

    ylabel('总指数');

    figure;

    A = polyfit(mining,all,1);

    all2 = polyval(A,mining);

    plot(mining,all,'b*',mining,all2,'r-')

    title('总指数与矿产品价格指数的关系图');

    xlabel('矿产品价格指数');

    ylabel('总指数');

    figure;

    A = polyfit(coe,all,1);

    all2 = polyval(A,coe);

    plot(coe,all,'b*',coe,all2,'r-')

    title('总指数与煤油电价格指数的关系图');

    xlabel('煤油电价格指数');

    ylabel('总指数');

    %结束总指数其他各个指数之间关系的散点图并拟合的绘制

    %开始总指数与各指数均值、中位数关系的散点图并拟合

    figure;

    subplot(2,2,1);

    B = polyfit(jun_zhi(:,2),jun_zhi(:,1),1);

    all3 = polyval(B,jun_zhi(:,2));

    plot(jun_zhi(:,2),jun_zhi(:,1),'b*',jun_zhi(:,2),all3,'r-')

    title('总指数均值与农产品指数均值');

    xlabel('农产品指数均值');

    ylabel('总指数均值');

    subplot(2,2,2);

    B = polyfit(jun_zhi(:,3),jun_zhi(:,1),1);

    all3 = polyval(B,jun_zhi(:,3));

    plot(jun_zhi(:,3),jun_zhi(:,1),'b*',jun_zhi(:,3),all3,'r-')

    title('总指数均值与矿产品指数均值');

    xlabel('矿产品指数均值');

    ylabel('总指数均值');

    subplot(2,2,3);

    B = polyfit(jun_zhi(:,4),jun_zhi(:,1),1);

    all3 = polyval(B,jun_zhi(:,4));

    plot(jun_zhi(:,4),jun_zhi(:,1),'b*',jun_zhi(:,4),all3,'r-')

    title('总指数均值与煤油电指数均值');

    xlabel('煤油电指数均值');

    ylabel('总指数均值');

    figure;

    subplot(2,2,1);

    B =polyfit(zhong_wei_shu(:,2),zhong_wei_shu(:,1),1);

    all3 = polyval(B,zhong_wei_shu(:,2));

    plot(zhong_wei_shu(:,2),zhong_wei_shu(:,1),'b*',...

       zhong_wei_shu(:,2),all3,'r-')

    title('总指数中位数与农产品指数中位数');

    xlabel('农产品指数中位数');

    ylabel('总指数中位数');

    subplot(2,2,2);

    B =polyfit(zhong_wei_shu(:,3),zhong_wei_shu(:,1),1);

    all3 = polyval(B,zhong_wei_shu(:,3));

    plot(zhong_wei_shu(:,3),zhong_wei_shu(:,1),'b*',...

       zhong_wei_shu(:,3),all3,'r-')

    title('总指数中位数与矿产品指数中位数');

    xlabel('矿产品指数中位数');

    ylabel('总指数中位数');

    subplot(2,2,3);

    B =polyfit(zhong_wei_shu(:,4),zhong_wei_shu(:,1),1);

    all3 = polyval(B,zhong_wei_shu(:,4));

    plot(zhong_wei_shu(:,4),zhong_wei_shu(:,1),'b*',...

       zhong_wei_shu(:,4),all3,'r-')

    title('总指数中位数与煤油电指数中位数');

    xlabel('煤油电指数中位数');

    ylabel('总指数中位数');

    %第一题结束

    附录二

    load data

    all = data(:,2);

    agriculture = data(:,3);

    X = [ ones(191,1),agriculture ];

    [b,bint,r,rint,stats] = regress(all,X);

    b

    bint

    stats

    rcoplot(r,rint)  %残差图

    for i =191:-1:1    %剔除异常

       if(abs(rint(i,1))+abs(rint(i,2))==abs(rint(i,1)+rint(i,2)))

           all(i) = [];

           agriculture(i) = [];

       end

    end

    X = [ ones(178,1),agriculture ];

    [b,bint,r,rint,stats] = regress(all,X);

    b

    bint

    stats

    附录三

    load data

    all = data(:,2);

    agriculture = data(:,3);

    mining = data(:,4);

    coe = data(:,5);

    X = [ ones(191,1),agriculture,mining,coe ];

    [b,bint,r,rint,stats] = regress(all,X);

    b

    bint

    stats

    rcoplot(r,rint)  %残差图

    for i =191:-1:1    %剔除异常**必须从后往前剔除

       if(abs(rint(i,1))+abs(rint(i,2))==abs(rint(i,1)+rint(i,2)))

           all(i) = [];

           agriculture(i) = [];

           mining(i) = [];

           coe(i) = [] ;

       end

    end

    %

    X = [ ones(183,1),agriculture,mining,coe ];

    [b,bint,r,rint,stats] = regress(all,X);

    b

    bint

    stats

    附录四

    et =all-(b(1)*ones(183,1)+b(2)*agriculture+b(3)*mining+b(4)*coe);

    plot(et(1:182),et(2:183),'+');

    hold on

    x_time =linspace(0,0,10);

    y_time = linspace(-2,2,10);

    plot(x_time,y_time)

    plot(y_time,x_time)

    hold off

    %

    s1 = 0;

    s2 = 0;

    for i = 2:183

       s1 = s1+et(i)*et(i-1);

       s2 = s2+et(i)*et(i);

    end

    DW = 2*(1-s1/s2)

    p_time = s1/s2

    %

    %数据变换

    all_time= all(2:183)-p_time*all(1:182);

    agriculture_time =agriculture(2:183)-p_time*agriculture(1:182);

    mining_time=mining(2:183)-p_time*mining(1:182);

    coe_time= coe(2:183)-p_time*coe(1:182);

    %回归

    X_time = [ones(182,1),agriculture_time,mining_time,coe_time ];

    [b_time,bint_time,r_time,rint_time,stats_time]=...

          regress(all_time,X_time);

     

    b_time

    bint_time

    stats_time

    %%%%%%%%%%%%%%%%%%%%

    et2 = all_time-(b_time(1)*ones(182,1)+b_time(2)*...

       agriculture_time+b_time(3)*mining_time+b_time(4)*coe_time);

    s1 = 0;

    s2 = 0;

    for i = 2:182

       s1 = s1+et2(i)*et2(i-1);

       s2 = s2+et2(i)*et2(i);

    end

    DW = 2*(1-s1/s2)

    figure;

    %

    yuce_multi = b(1)*ones(183,1)+b(2)*agriculture+b(3)*mining+b(4)*coe;

    yuce_time(1) = 95.88;

    yuce_time(2:183) =6.0977*ones(182,1)+0.8493*all(1:182)+0.2714...

       *agriculture(2:183)-0.2305*agriculture(1:182)+0.1875*mining...

       (2:183)-0.1592*mining(1:182)+0.1271*coe(2:183)-0.1079*coe(1:182);

    count = 1:183;

    plot(count,all,'o',count,yuce_time,'*',count,yuce_multi,'+')

    legend('总指数','时间序列','多元线性回归');

    figure;

    et_time = all - yuce_time';

    plot(count,et_time,'*',count,et,'+')

    legend('时间序列','多元线性回归');

    hold on

    x_time =linspace(0,183,10);

    y_time = linspace(0,0,10);

    plot(x_time,y_time)

    hold off

    展开全文
  • 基于大庆油田采油二厂压裂措施...定量关系,且回归分析计算的精度较高,多元二次回归分析和DPS平均拟合误差分别为0.940%、0. 916%,预测平均误差分别为1.850%、1.831%,研究为油田开发动态数据规律研究提供了有效的方法。
  • 支持向量机自回归分析的股市动态预测模型。该模型利用滚动时间窗 动态截取股票时间序列,然后对其进行相空间重构,最后利用支持向量 机回归算法,在高维映射空间中求解线性回归问题。利用上证综指的 长期和短期数据...
  • logistic回归是一种广义线性回归(generalized linear model),因此与多重线性回归分析有很多相同之处。它们的模型形式基本上相同,都具有 w‘x+b,其中w和b是待求参数,其区别在于他们的因变量不同,多重线性回归...
  • 该程序包实现了按时间排序的功能数据的动态回归模型中的动态标量函数回归模型(贝叶斯分析,2020年),其中功能数据响应在标量预测变量上进行了回归。 在此,功能响应和标量预测变量都可以按时间排序。 使用未知基础...
  • 用于运行此存储库中包含的网络预处理和分析功能的描述和示例脚本。 详细信息请参见纸张。 扩展预处理 由于运动对连通性度量的已知影响,我们在FSL中跟踪了标准的预处理,并进行了扩展的干扰回归。 将来自运动校正,...
  • 回归分析作为一种估算资源消耗的方法常用于克服不易于直接测量的问题,但在多租户应用的动态负载环境下效果并不好。针对多租户环境下的动态负载变化,以CPU资源消耗为研究目标,提出一种基于回归分析方法的改良策略...
  • 针对回归分析问题提出了一种动态确定结果合成权重的神经网络集成构造方法,在训练出个体神经网络之后,根据各个体网络在输入空间上对训练样本的预测误差,应用广义回归网络来动态地确定各个体网络在特定输入空间上的...
  • matlab回归分析计算t统计量代码μLA包装 微型线性代数包 发音:mu la pack 一个小的线性代数软件包,用于计算各种矩阵/矢量运算。 该库经过优化,可在微控制器和嵌入式环境中使用,但可在可编译C的任何地方使用。 ...
  • 这次主要是来分析一下动态代理的作用与实现原理。既然都已经分析了原理,最后自然也要动手仿照Retrofit来简单实现一个Demo。 通过最后的Demo实现,相信动态代理你也基本没什么问题了。 静态代理 既然说到动态代理,...

    我们一直都在使用Retroift,都知道它的核心是动态代理。例如在之前的文章重温Retrofit源码,笑看协程实现中也简单提及到动态代理(来填之前挖的坑…)。

    咳咳,大家不要关注起因,还是要回归当前的内容。

    这次主要是来分析一下动态代理的作用与实现原理。既然都已经分析了原理,最后自然也要动手仿照Retrofit来简单实现一个Demo

    通过最后的Demo实现,相信动态代理你也基本没什么问题了。

    静态代理

    既然说到动态代理,自然少不了静态代理。那么静态代理到底是什么呢?我们还是通过一个简单的场景来了解。

    假设有一个Bird接口来代表鸟的一些特性,例如fly飞行特性

    interface Bird {
        fun fly()
    }
    

    现在分别有麻雀、老鹰等动物,因为它们都是鸟类,所以都会实现Bird接口,内部实现自己的fly逻辑。

    // 麻雀
    class Sparrow : Bird {
        override fun fly() {
            println("Sparrow: is fly.")
            Thread.sleep(1000)
        }
    }
    // 老鹰
    class Eagle : Bird {
        override fun fly() {
            println("Eagle: is fly.")
            Thread.sleep(2000)
        }
    }
    

    麻雀与老鹰的飞行能力都实现了,现在有个需求:需要分别统计麻雀与老鹰飞行的时长。

    你会怎么做呢?相信在我们刚学习编程的时候都会想到的是:这还不简单直接在麻雀与老鹰的fly方法中分别统计就可以了。

    如果实现的鸟类种类不多的话,这种实现不会有太大的问题,但是一旦实现的鸟类种类很多,那么这种方法重复做的逻辑将会很多,因为我们要到每一种鸟类的fly方法中都去添加统计时长的逻辑。

    所以为了解决这种无意义的重复逻辑,我们可以通过一个ProxyBird来代理实现时长的统计。

    class BirdProxy(private val bird: Bird) : Bird {
        override fun fly() {
            println("BirdProxy: fly start.")
            val start = System.currentTimeMillis() / 1000
            bird.fly()
            println("BirdProxy: fly end and cost time => ${System.currentTimeMillis() / 1000 - start}s")
        }
    }
    

    ProxyBird实现了Bird接口,同时接受了外部传进来的实现Bird接口的对象。当调用ProxyBirdfly方法时,间接调用了传进来的对象的fly方法,同时还进行来时长的统计。

    class Main {
        companion object {
            @JvmStatic
            fun main(args: Array<String>) {
                ProxyBird(Sparrow()).fly()
                println()
                ProxyBird(Eagle()).fly()
            }
    
        }
    }
    

    最后输出如下:

    ProxyBird: fly start.
    Sparrow: is fly.
    ProxyBird: fly end and cost time => 1s
     
    ProxyBird: fly start.
    Eagle: is fly.
    ProxyBird: fly end and cost time => 2s
    

    上面这种模式就是静态代理,可能有许多读者都已经不知觉的使用到了这种方法,只是自己没有意识到这是静态代理。

    那它的好处是什么呢?

    通过上面的例子,很自然的能够体会到静态代理主要帮我们解决的问题是:

    1. 减少重复逻辑的编写,提供统一的便捷处理入口。
    2. 封装实现细节。

    动态代理

    既然已经有了静态代理,为什么又要来一个动态代理呢?

    任何东西的产生都是有它的必要性的,都是为了解决前者不能解决的问题。

    所以动态代理就是来解决静态代理所不能解决的问题,亦或者是它的缺点。

    假设我们现在要为Bird新增一种特性:chirp鸟叫。

    那么基于前面的静态代理,需要做些什么改变呢?

    1. 修改Bird接口,新增chirp方法。
    2. 分别修改SparrowEagle,为它们新增chirp的具体实现。
    3. 修改ProxyBird,实现chirp代理方法。

    1、3还好,尤其是2,一旦实现Bird接口的鸟类种类很多的话,将会非常繁琐,这时就真的是牵一发动全身了。

    这还是改动现有的Bird接口,可能你还需要新增另外一种接口,例如Fish鱼,实现有关鱼的特性。

    这时又要重新生成一个新的代理ProxyFish来管理有关鱼的代理。

    所以从这一点,我们可以发现静态代理的机动性很差,对于那些实现了之后不怎么改变的功能,可以考虑使用它来实现,这也完全符合它的名字中的静态的特性。

    那么这种情况动态代理就能够解决吗?别急,能否解决接着往下看。

    接着上面,我们为Bird新增chirp方法

    interface Bird {
        fun fly()
        
        fun chirp()
    }
    

    然后再通过动态代理的方式来实现这个接口

    class Main {
        companion object {
            @JvmStatic
            fun main(args: Array<String>) {
                val proxy = (Proxy.newProxyInstance(this::class.java.classLoader, arrayOf(Bird::class.java), InvocationHandler { proxy, method, args ->
                    if (method.name == "fly") {
                        println("calling fly.")
                    } else if (method.name == "chirp") {
                        println("calling chirp.")
                    }
                }) as Bird)
                
                proxy.fly()
                proxy.chirp()
            }
        }
    }
    

    输出如下:

    calling fly.
    calling chirp.
    

    方式很简单,通过Proxy.newProxyInstance静态方法来创建一个实现Bird接口的代理。该方法主要有三个参数分别为:

    1. ClassLoader: 生成代理类的类类加载器。
    2. interface 接口Class数组: 对应的接口Class。
    3. InvocationHandler: InvocationHandler对象,所有代理方法的回调。

    这里关键点是第三个参数,所有通过调用代理类的代理方法都会在InvocationHandler对象中通过它的invoke方法进行回调

    public interface InvocationHandler {
        public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable;
    }
    

    这就是上面将判断调用具体接口方法的逻辑写在InvocationHandler对象的invoke方法的原因。

    那它到底是如何实现的呢?怎么就成了一个代理类呢?我也没看到代理类在哪啊?怎么就所有调用都通过InvocationHandler的呢?

    有这些疑问很正常,开始接触动态代理时都会有这些疑问。导致这些疑问的直接原因是我们不能直接看到所谓的代理类。因为动态代理是在运行时生成代理类的,所以不像在编译时期一样能够直接看到源码。

    那么下面目标就很明确了,解决看不到源码的问题。

    既然是运行时生成的,那么在运行的时候将生成的代理类写到本地目录下不就可以了吗?至于如何写Proxy已经提供了ProxyGenerator。它的generateProxyClass方法能够帮助我们得到生成的代理类。

    class Main {
        companion object {
            @JvmStatic
            fun main(args: Array<String>) {
                val byte = ProxyGenerator.generateProxyClass("\$Proxy0", arrayOf(Bird::class.java))
                FileOutputStream("/Users/{path}/Downloads/\$Proxy0.class").apply {
                    write(byte)
                    flush()
                    close()
                }
            }
        }
    }
    

    运行上面的代码就会在Downloads目录下找到$Proxy0.class文件,将其直接拖到编译器中,打开后的具体代码如下:

    public final class $Proxy0 extends Proxy implements Bird {
        private static Method m1;
        private static Method m4;
        private static Method m2;
        private static Method m3;
        private static Method m0;
     
        public $Proxy0(InvocationHandler var1) throws  {
            super(var1);
        }
     
        public final boolean equals(Object var1) throws  {
            try {
                return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
     
        public final void fly() throws  {
            try {
                super.h.invoke(this, m4, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
     
        public final String toString() throws  {
            try {
                return (String)super.h.invoke(this, m2, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
     
        public final void chirp() throws  {
            try {
                super.h.invoke(this, m3, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
     
        public final int hashCode() throws  {
            try {
                return (Integer)super.h.invoke(this, m0, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
     
        static {
            try {
                m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
                m4 = Class.forName("com.daily.algothrim.Bird").getMethod("fly");
                m2 = Class.forName("java.lang.Object").getMethod("toString");
                m3 = Class.forName("com.daily.algothrim.Bird").getMethod("chirp");
                m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            } catch (NoSuchMethodException var2) {
                throw new NoSuchMethodError(var2.getMessage());
            } catch (ClassNotFoundException var3) {
                throw new NoClassDefFoundError(var3.getMessage());
            }
        }
    }
    

    首先$Proxy0继承了Proxy同时实现了我们熟悉的Bird接口;然后在它的构造方法中接受了一个var1参数,它的类型是InvocationHandler。继续看方法,实现了类的默认三个方法equalstoStringhashCode,同时也找到了我们需要的flychirp方法。

    例如fly方法,调用了

    super.h.invoke(this, m4, (Object[])null)
    

    这里的h就是之前的var1,即InvocationHandler对象。

    到这里迷雾已经揭晓了,调用invoke方法,同时将代理类的自身this、对应的method信息与方法参数传递过去。

    所以我们只需要在动态代理的最后一个参数InvocationHandlerinvoke方法中进行处理不同代理方法的相关逻辑。这样做的好处是,不管你如何新增与删除Bird中的接口方法,我都只要调整invoke的处理逻辑即可,将改动的范围缩小到最小化。

    这就是动态代理的好处之一(另一个主要的好处自然是减少代理类的书写)。

    Android中运用动态代理的典型非Retrofit莫属。由于是一个网络框架,一个App对于网络请求来说接口自然是随着App的迭代不断增加的。对于这种变化频繁的情况,Retrofit使用动态代理为入口,暴露出一个对应的Service接口,而相关的接口请求方法都在Service中进行定义。所以我们每新增一个接口,都不需要做过多的别的修改,相关的网络请求逻辑都封装到动态代理的invoke方法中,当然Retrofit原理是借助添加Annomation注解的方式来解析不同网络请求的方式与相关的参数逻辑。最终再将解析的数据进行封装传递给下层的OKHttp

    所以Retrofit的核心就是动态代理与注解的解析。

    这篇文章的原理解析部分就完成了,最后既然分析了动态代理与Retrofit的关系,我这里提供了一个Demo来巩固一下动态代理,同时借鉴Retroift的一些思想对一个简易版的打点系统进行上层封装。

    Demo

    Demo是一个简单的模拟打点系统,通过定义Statistic类来创建动态代理,暴露Service接口,具体如下:

    class Statistic private constructor() {
     
        companion object {
            @JvmStatic
            val instance by lazy { Statistic() }
        }
     
        @Suppress("UNCHECKED_CAST")
        fun <T> create(service: Class<T>): T {
            return Proxy.newProxyInstance(service.classLoader, arrayOf(service)) { proxy, method, args ->
                return@newProxyInstance LoadService(method).invoke(args)
            } as T
        }
    
    }
    

    通过入口传进来的Service接口,从而创建对应的动态代理类,然后将对Service接口中的方法调用的逻辑处理都封装到了LoadServiceinvoke方法中。当然Statistic也借助了注解来解析不同的打点类型事件。

    例如,我们需要分别对ButtonText进行点击与展示打点统计。

    首先我们可以如下定义对应的Service接口,这里命名为StatisticService

    interface StatisticService {
     
        @Scan(ProxyActivity.PAGE_NAME)
        fun buttonScan(@Content(StatisticTrack.Parameter.NAME) name: String)
     
        @Click(ProxyActivity.PAGE_NAME)
        fun buttonClick(@Content(StatisticTrack.Parameter.NAME) name: String, @Content(StatisticTrack.Parameter.TIME) clickTime: Long)
     
        @Scan(ProxyActivity.PAGE_NAME)
        fun textScan(@Content(StatisticTrack.Parameter.NAME) name: String)
     
        @Click(ProxyActivity.PAGE_NAME)
        fun textClick(@Content(StatisticTrack.Parameter.NAME) name: String, @Content(StatisticTrack.Parameter.TIME) clickTime: Long)
    }
    

    然后再通过Statistic来获取动态代理的代理类对象

    private val mStatisticService = Statistic.instance.create(StatisticService::class.java)
    

    有了对应的代理类对象,剩下的就是在对应的位置直接调用。

    class ProxyActivity : AppCompatActivity() {
     
        private val mStatisticService = Statistic.instance.create(StatisticService::class.java)
     
        companion object {
            private const val BUTTON = "statistic_button"
            private const val TEXT = "statistic_text"
            const val PAGE_NAME = "ProxyActivity"
        }
     
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val extraData = getExtraData()
            setContentView(extraData.layoutId)
            title = extraData.title
    
            // statistic scan
            mStatisticService.buttonScan(BUTTON)
            mStatisticService.textScan(TEXT)
        }
    
        private fun getExtraData(): MainModel =
                intent?.extras?.getParcelable(ActivityUtils.EXTRA_DATA)
                        ?: throw NullPointerException("intent or extras is null")
    
        fun onClick(view: View) {
            // statistic click
            if (view.id == R.id.button) {
                mStatisticService.buttonClick(BUTTON, System.currentTimeMillis() / 1000)
            } else if (view.id == R.id.text) {
                mStatisticService.textClick(TEXT, System.currentTimeMillis() / 1000)
            }
        }
    }
    

    这样一个简单的打点上层逻辑封装就完成了。由于篇幅有限(懒…)内部具体的实现逻辑就不展开了。

    相关源码都在android-api-analysis项目中,感兴趣的可以自行查看。

    使用前请先把分支切换到feat_proxy_dev

    项目

    android_startup: 提供一种在应用启动时能够更加简单、高效的方式来初始化组件,优化启动速度。不仅支持Jetpack App Startup的全部功能,还提供额外的同步与异步等待、线程控制与多进程支持等功能。

    AwesomeGithub: 基于Github客户端,纯练习项目,支持组件化开发,支持账户密码与认证登陆。使用Kotlin语言进行开发,项目架构是基于Jetpack&DataBindingMVVM;项目中使用了ArouterRetrofitCoroutineGlideDaggerHilt等流行开源技术。

    flutter_github: 基于Flutter的跨平台版本Github客户端,与AwesomeGithub相对应。

    android-api-analysis: 结合详细的Demo来全面解析Android相关的知识点, 帮助读者能够更快的掌握与理解所阐述的要点。

    daily_algorithm: 每日一算法,由浅入深,欢迎加入一起共勉。

    展开全文
  • 数据分析法 从大量的观测数据... 回归分析法——用于对函数的一组观测值,确定函数的表达式,由于处理的是静态的独立数据,故称为数理统计方法. 2. 时间序列分析法——处理的是动态的相关数据,又称为过程统计方法.
  • 证券分析是一个Python软件包,旨在为共同基金,交易所交易基金和股票的每日收盘价动态列表提供可自定义的最小二乘回归分析。 安装 要安装证券分析,只需从下载目录执行以下命令: sudo python setup.py install 要...
  • 基于内蒙古1995-2015年的统计数据,建立工业化和能源强度间的向量自回归模型(VAR模型),进行协整分析之后,运用脉冲响应函数和动态方差分解法,对工业化和能源强度这两组变量的交互动态响应关系进行分析和预测,从而探索...
  • 运用ArcGIS地理信息系统软件,得到研究区详细的土地利用类型转变数据,依据数据建立了单一土地利用类型动态度、线性回归方程以及综合土地利用类型动态度3个分析模型,进而为大型露天矿区的生态重建提供决策支持。
  • 本文介绍以IBM―PC/XT机为基础的离线自回归分析系统,给出该系统对多普勒血流信号处理所获得的动态功率谱。实验结果表明,该系统对血流信号的处理结果,与FFT系统的处理结果相比,具有分辨率高、方差小等优点。
  • 为了获取超细颗粒动态散射光模拟信号, 在分析超细颗粒动态散射光信号特性的基础上, 通过建立动态光散射随机过程的自回归(AR)模型, 利用Levison-Durbin递推算法确定模型参数, 并给出了单峰、双峰分布颗粒信号模拟的...
  • 采用东北林业大学帽儿山实验林场1990年和2004年的固定样地调查数据及一元生物量预估模型,计算得到林场内各样地单位面积生物量,并运用地理信息...通过回归分析,得到生物量与海拔高度的回归方程,并通过了统计检验。
  • 一、动态CoVaR模型介绍 ...里面包含了数据、代码、步骤,可以方便的利用这个手册解决大部分利用分位数回归计算动态CoVaR的论文的模型实现问题。即从数据下载到模型实现一整条操作步骤。 关键词:【动态Co...

    关注公众号卧新实验室,并回复关键数字获取本文帮助文档。例如:20003

    原文链接:https://www.cctalk.com/m/group/89602495?xh_fshareuid=60953990

    CCtalk课程购买后使用说明:下载CCtalk手机端或者电脑端,进入'文件'列表获取主要资料,同时课时和讨论帖会提供更多增值服务。

    相关链接:https://bbs.pinggu.org/thread-8019214-1-1.html


    一、动态CoVaR模型介绍

    二、资料简介

    实现对相关期刊论文进行论文重现,解决实证分析和论文写作中的技术操作问题。里面包含了数据、代码、步骤,可以方便的利用这个手册解决大部分利用分位数回归计算动态CoVaR的论文的模型实现问题。即从数据下载到模型实现一整条操作步骤。
    关键词:【动态CoVaR】【分位数回归】【状态变量】

    资料见原文链接,部分代码示例,获取统计值:

    '一、查看数据
    group gv v* s '将所用v开头的序列和序列s组成一个组,并命名为gv
    gv.stats '查看组gv的描述性统计

    三、解决问题

    ① 实现从最初录入数据到最后完成
    ② 利用分位数回归技术,引入状态变量,建立模型和处理数据
    ③ 计算时变VaR、CoVaR、ΔCoVaR

    四、案例介绍

    以我国16个主要上市银行和申万银行指数作为样本,运用分位数回归构建商业银行与系统间的动态CoVaR模型,来研究商业银行系统性风险及其溢出效应。

    五、操作结果

    结果之一的动态delta CoVaR图形:

    参考文献

    [1]王周伟,吕思聪,茆训诚.基于风险溢出关联特征的CoVaR计算方法有效性比较及应用[J].经济评论,2014(04):148-160. 
    [2]邓周贵.基于静态与动态CoVaR方法银行系统性风险研究[D].南京大学,2017.
    [3]许晔.基于尾部风险网络的中国金融机构重要性研究[J].宏观经济研究,2019(11):102-111.
    [4]白雪梅,石大龙.中国金融体系的系统性风险度量[J].国际金融研究,2014(06):75-85.
    [5]李志辉,樊莉.中国商业银行系统性风险溢价实证研究[J].当代经济科学,2011,33(06):13-20+122.
    [6]陈守东,王妍.我国金融机构的系统性金融风险评估——基于极端分位数回归技术的风险度量[J].中国管理科学,2014,22(07):10-17.

    展开全文
  • 针对一类非线性严格反馈系统,提出一种基于自适应支持向量回归动态面控制方法.首先,将支持向量回归的核函数在核宽度以及支持向量估计值处进行一阶泰勒展开,使其能够对核宽度和支持向量进行线性化表示;然后,利用支持...
  • ATM现金流量动态分析

    2010-05-30 08:52:14
    根据ATM 现金流量时间序列分析ATM 的取款量变化规律. 用Matlab 作为建模和分 析工具通过模型识别和参数估计建立自回归滑动平均模型刻画ATM 上现金流的变化规律 检验模型的正确性. 在此基础上可预测未来10 天的ATM ...
  • 为了加速模型在线更新的速度以更好地适应实际工业过程的动态变化,通过在已有递推主元分析(PCA)算法的基础上简化了自相关矩阵的递推公式,从而改进了基于秩1更新的递推PCA算法,把原来需要进行2次秩l更新的步骤简化...
  • 首先对我国1978―2007年间的生态足迹进行了测算,然后对城市化与生态足迹进行单位根检验及协整检验,最后建 立向量自回归模型,利用广义脉冲响应函数法对其关系进行了实证分析。研究结果表明,我国的快速城市化导致生态...
  • 采用黑箱模型理论建立了船舶多功能舱室动态负荷数学模型,经分析求解,获得了某典型欧亚远洋航线上的船舶动态负荷变化规律.结果表明:船舶空调负荷随...此外,运用回归分析知,可变舱室负荷的91. 72%受室外温度变化的影响.
  • 场景:节日客流量预测季节销量预测实时股价预测案例:客流量预测解读:通过实际值和预测值的对比可直观看出预测的准确程度原理:时间序列回归(TSR)是一种动态数据处理的统计方法,研究随机时间序列数据遵循的统计...
  • 针对实际交通系统时变复杂的特征和交通流变化的不确定性,基于模式识别的思想,提出了一种小波分析和K近邻非参数回归相结合的交通流组合预测模型。模型首先应用小波分析理论,对原始交通数据进行了消噪处理,使消噪后的...
  • 首先通过主成分分析,寻找出影响越冬幼虫种群数量变动的关键因子主要是越冬幼虫生境的温度和空气中的相对湿度.在此基础上,通过主成分回归建立数学模型,预测越冬幼虫种群数量,为制定油松毛虫防治策略提供准确的虫情...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 756
精华内容 302
关键字:

动态回归分析