欢迎光临散文网 会员登陆 & 注册

菜鸟入坑:美国人口预测模型(1),取自司守奎《数学建模算法与应用》

2021-02-02 12:29 作者:光电面壁人  | 我要投稿

1、导入数据,输出类型选为数值矩阵,命名为A

单位:百万人

2010、2020年的人口数据用以验证。

t=A(:,1);%年份是A的第一列

x=A(:,2);%人口数是A的第二列

t0=t(1);%初始时间是向量t的第一个元素

x0=x(1);%同上

然后,用曲线拟合工具箱,

线性拟合

线性拟合太飞了,换一个,比如e指数拟合:

话说a=66.77,b=0.9236,那带入t=10^3的玩意那不指数爆炸了?真是令人疑惑,然后

原来是勾选了“center and scale”,


引用自https://blog.csdn.net/qq_44207723/article/details/107935435

问题不大,就当是正路上的一滩积水坑了,继续前进

嗯发现貌似拟合得还可以,评价拟合得好坏具体指标见左侧Results框里的指标:

最大头的是RMSE,0.9859说明拟合得还可以,验证一下2010、2020

而事实上是美国人口2010为3.087(历史性突破3亿)、2020为3.32亿。说明这个模型不太准,小改一下:使用双平方后,貌似曲线又起飞了……

结果大同小异,也是奔4亿去了

可见美国人口实际上是在指数减速的,不是J型曲线增长而是S型曲线增长,发达国家一般都是S到饱和,即很可能是人口负增长,而美国是个例外,它的人口容量远未到达上限,指数减速才刚开始不久,未来还会强力增长很长一段时间。

在曲线拟合工具箱中,虽然一次函数拟合得飞了,二次函数、三次函数的拟合虽然拟合得非常准确,但我觉得不能为了拟合而拟合,那会偏向于傅里叶展开,将淹没人口增长模型。

3、正式建模

我们虑logistic模型即阻滞增长模型,设x(t)为t年增长人口,人口年增长率r(x)为x的线性函数,r(x)=r-sx,生存环境条件所能容纳的最大人口数为xm,当x=xm时,人口增长率为0.

很明显这是非线性的,于是我们用这个函数:

lsqcurvefit要求先定义一个fun,根据书中的原文适当添加我的理解:

t=A(:,1);%年份是A的第一列

x=A(:,2);%人口数是A的第二列

t0=t(1);%初始时间是向量t的第一个元素

x0=x(1);%同上

%初始

%非线性曲线拟合是已知输入向量xdata、输出向量ydata和函数关系ydata=F(x,xdata),但不清楚系数向量x

%可以使用函数curvefit解决

fun=@(cs,td)cs(1)./(1+(cs(1)/x0-1)*exp(-cs(2)*(td-t0)));%cs(1)=xm,cs(2)=r,td应该就是t,换了个名

%fun返回的是个xhat

cs=lsqcurvefit(fun,rand(2,1),t(2:end),x(2:end),zeros(2,1))%rand(2,1)为初始解向量,zeros(2,1)为下界

%lsqcurvefit的返回值是xdata的系数,

%初始解向量的意思是cs(1)=xm、cs(2)=r,都是0-1之间的随机数,这是个合理的假设

T=[t;2010;2020];%把后两年接上

xhat=fun(cs,[t;2010;2020]);%预测人口2010、2020年美国人口

xhat’%横着打印方便截图,不然竖着是个大长长

plot(T,xhat),xlabel('年份'),ylabel('人口数量'),title('美国人口增长曲线阻滞模型')

figure(2);

plot(T,xhat,t,x),xlabel('年份'),ylabel('人口数量'),legend('拟合','实际'),title('美国人口增长曲线')

运行脚本后,

可以看出,大致是个s型曲线,但预测的仍和现实有出入:

尤其是迈入新世纪时,拟合过于保守,拟合在2000年时才为2.68亿,而实际上美国人口在1990-2000的增长比1980-1990时强势加速,人口达到了2.81亿;美国人口2010为3.087、2020为3.32亿,拟合差不多落后了10多年,拟合在2020时美国人口仍未突破三亿。

司守奎《数学建模算法与应用》中还介绍了线性最小二乘法的向前差分、向后差分,但我认为不如非线性最小二乘法估计好,也就是说,xm、r的在样本数据中的参数估计差不多到头了,我们得考虑现实因素引入对模型进行一些修正。


菜鸟入坑:美国人口预测模型(1),取自司守奎《数学建模算法与应用》的评论 (共 条)

分享到微博请遵守国家法律