☰
人口预测复现:Logistic与Leslie模型及MATLAB实现
2026/10/31 12:18:59 网站建设 项目流程

简介:《Leslie人口增长模型》是一份面向人口统计、数学建模学习者及参加相关赛题读者的文档型资料,重点解决中国人口总量与年龄结构的中长期预测问题。压缩包内共1个doc文件,约988KB,内容以完整论文/报告形式组织,便于直接阅读、引用和二次整理。资源围绕Logistic阻滞增长模型与按年龄分布的Leslie矩阵模型展开,包含参数设定、数据拟合、MATLAB实现思路,以及对总人口、劳动年龄人口、老年人口、人口抚养比和育龄妇女人数的预测分析,并附模型残差比较、优缺点评价与推广讨论。已有5156人学习,适合需要理解人口预测建模流程、复现实验或撰写课程论文的读者参考。

1. 人口预测复现包:先别急着跑拟合,起始年份决定一半结果

拿到一份人口预测的建模复现包,多数人的第一反应是把总人口序列丢进函数拟一遍,看到可决系数 0.99 就收工。翻车往往发生在后面:拿 1954 年起始的数据和 1980 年起始的数据分别拟合,同一个 Logistic 公式,2033 年的预测值能差出一个多亿。这份资源包的价值不在公式本身,它把「用哪段数据、抽样调查怎么还原成年龄分布向量、算出的总和生育率跟专家给的更替水平对不上怎么修」这些决定成败的环节全摊开了。Logistic 人口模型和 Leslie 人口模型从两个粒度切入——前者盯总量拐点,后者盯年龄结构,配一套 MATLAB 脚本。适合做人口与资源类预测、需要复现建模报告的从业者,也适合想把矩阵迭代预测流程真正落地的人。

2. Logistic 阻滞增长模型:三段起始年份的拟合差异与参数取舍

2.1 从指数增长到阻滞增长:微分方程与解析解

人口在资源无限时按指数增长,这是 Malthus 模型的核心假设,短时间内吻合、长时间必然发散。Logistic 模型在它上面加了一件事:把增长率视为人口数的减函数,人口越多增长越慢,最终逼近环境承载力 K。微分方程为 dx/dt = r·x·(1 − x/K),解析解是 x(t) = K / (1 + (K/x₀ − 1)·exp(−r·t))。

三个参数里,x₀ 是初始人口,由数据给定;K 是最大人口容量;r 是内禀增长率。真正要拟合的是 K 和 r。这里有个高频误区——不少人把 x₀ 也当自由参数放开拟合,结果曲线整体偏移。正确做法是把 x₀ 钉死在起始年份的实测值上,只放开 K 和 r 两个自由度。

参数的量级也要心里有数。K 的单位跟数据一致,数据是千万,K 就是千万;样本里 1954 年起始拟合出的 K 约 181 千万(18.1 亿),1980 年起始拟合出的 K 约 150 千万。r 落在 0.03 到 0.05 之间。这两个参数不独立:K 给大了,r 会跟着变小来补偿,样本内拟合优度可能看着一样,但外推到 2033 年就差出几千万。这就是为什么同样的数据换个初值,远期预测能差一大截。

2.2 起始年份怎么选:三组数据的残差对照

原项目分别从 1954、1963、1980 三个起点建模,都预测到 2005 年,比的是可决系数和残差绝对值之和,不是比谁的数据新。

第一段 1954—2005,残差绝对值和约 57.9992。原因清楚:1959—1961 三年困难期人口波动剧烈,随机误差不服从正态分布,而最小二乘拟合恰恰以误差正态为隐含前提,前提一破,结果就不可信。

第二段 1963—2005,残差绝对值和降到约 27.8046。这一段基本按自然规律增长,外部干扰少,拟合明显优于第一段。

第三段 1980—2005,残差绝对值和约 10.1699,可决系数 0.9987。这一段是生育政策稳定执行的时期,政策变量本身平稳,随机误差近似正态,最小二乘的前提成立。

所以选 1980 作起点的理由不是「数据更新」,而是「这一段的外部干预稳定且持续」——这恰好对应 Logistic 模型里「环境条件稳定」的隐含假设。这个判断比反复调参重要得多,也是选型时最该先想清楚的一件事。

代码实现用 MATLAB 的 nlinfit 做非线性最小二乘:

% 1980-2005 样本总人口序列(单位:千万) t = 0:25; x = [98.705 100.1 101.654 103.008 104.357 105.851 107.5 109.3 ... 111.026 112.704 114.333 115.823 117.171 118.517 119.85 ... 121.121 122.389 123.626 124.761 125.786 126.743 127.627 ... 128.453 129.227 129.988 130.756]; % 解析解匿名函数:b(1)=K,b(2)=r,x(1) 固定为初始人口 logiFun = @(b,t) b(1)./(1+(b(1)/x(1)-1).*exp(-b(2).*t)); b0 = [150 0.04]; % 初值:K约150千万,r约0.04 [bFit,resid] = nlinfit(t,x,logiFun,b0); K = bFit(1); r = bFit(2); R2 = 1 - sum(resid.^2)/sum((x-mean(x)).^2); fprintf('K=%.4f r=%.4f R2=%.6f\n',K,r,R2);

这段的逻辑是:nlinfit 接收观测时间 t、观测值 x 和函数句柄,返回拟合参数与残差。初值 b0 不是随手填——K 的量级可以从数据最大值往上估,r 可以从数据中期的年均增长率粗估。初值离真值太远,nlinfit 可能收敛到局部极小,残差就会呈现明显的不对称。拟合完先看 R2,再把残差画出来看是否关于零轴上下对称,两条都过再做外推。

参数上要盯住三处:K 是承载力上限,不等于「某年的预测人口」,它只是模型的渐近值;r 是内禀增长率;x(1) 必须钉死为起始年份实测值。外推时把 t 换成对应年份差,预测 2010 年就令 t = 2010 − 1980 = 30。

2.3 预测结果与可决系数的正确读法

用 1980—2005 拟合外推,得到 2010、2020、2033 年总人口分别约 13.55357 亿、14.18440 亿、14.70172 亿。三条曲线横向对比,这条最贴近参考报告给出的预测区间。

可决系数 0.9987 该怎么读?它只说明样本内拟合得好,不代表外推准。K 和 r 的联合不确定性会放大到远期预测上。所以我一般会补两个动作:把残差序列画出来看有没有系统性偏离;把 K 固定在不同值上做敏感性扫描,看预测结果对 K 有多敏感。这两步在最后一章展开。

还有一个细节:1954 年起拟合出的 K 约 181 千万,1980 年起是约 150 千万,同一份数据、同一个模型,起点一变 K 就变。这不矛盾——K 本来就是特定历史阶段下的等效容量,跨阶段直接比较 K 的绝对值没有意义,能比的只有趋势和拐点。

3. Leslie 矩阵模型:从抽样数据到年龄结构转移矩阵

3.1 年龄分组、生育率、存活率三要素

Leslie 模型把人口按年龄离散成组,时间步长等于组距。设 t 时刻第 i 组女性人数为 xᵢ(t),下一时刻的递推关系只有两条:0 岁组来自各育龄组女性的生育,i+1 组来自 i 组的存活。写成矩阵就是 x(t+1) = L·x(t),L 即 Leslie 矩阵。

矩阵的第一行是生育项:L(1,i) = fᵢ · s₀ · pᵢ。fᵢ 是第 i 组女性的生育率(含男女),s₀ 是新生儿存活到统计时刻的比例,pᵢ 是出生婴儿中女婴占比。次对角线是存活项:L(i,i−1) = sᵢ,表示第 i−1 组存活到第 i 组的比例。

最容易出错的是生育率的口径。如果 fᵢ 定义为「每个女性平均生育子女数、含男孩」,那必须再乘女婴占比才得到「生育女儿数」;如果数据给的已经是「生育女儿数」,就不能再乘。原项目用的是分市、镇、乡给出育龄妇女生育率、再乘女婴出生比例,这套转换要盯死。口径错一次,新生儿数就偏一倍。

3.2 市镇乡分层还原全国年龄分布向量

原项目的 2001 年数据是抽样调查,按市、镇、乡三层给出。要还原成全国女性年龄分布向量,分三步走。

第一步,算三层各自人口占全国的比例。用抽样数据分别求市、镇、乡女性占抽样女性的份额。

第二步,用全国总人口乘以各层比例得到各层总人口,再乘各年龄女性占比,得到各层每个年龄的女性数。原项目里 2001 年全国总人口 127.627 千万,按抽样比率分到三层。

第三步,三层逐年龄相加,得到全国女性分布向量。代码上就是三个同长向量直接相加,再用各层女性人数加权合并生育率:

% city/town/rural: 长度 n 的女性年龄分布向量(单位:万人) female2001 = city + town + rural; % 生育率按各层女性人数加权合并,不能简单取算术平均 fert = (city.*fertCity + town.*fertTown + rural.*fertRural) ./ female2001; fert(isnan(fert)) = 0; % 无女性年龄组避免 0/0

加权合并的意义在于城市和乡村生育率差异很大,直接算术平均会让城市被乡村拉平、结果失真。isnan处理的是某些高龄组女性人数为 0 导致除零的情况,这些组本来生育率就该是 0。参数上要确认三点:city/town/rural 必须同组距、同单位;fertCity 等若给的是 5 岁一组的生育率,要先插值或重采样到 1 岁一组,否则矩阵维度和人口向量对不上——这是复现时最常见的对齐错误,跑到矩阵乘法才报错。

3.3 更替水平修正与矩阵迭代

原项目里有个关键动作值得单独说:按 2001 年数据算出的总和生育率只有约 1.42(5 年均值),而专家给出的更替水平是 1.8。这个差距说明抽样数据偏低,直接拿去迭代会把人口峰值提前约 10 年。修正办法是把各年龄生育率同比例放大,使总和生育率等于 1.8。

总和生育率的定义是 TFR = Σfᵢ(按 1 岁一组),修正系数就是 1.8 / TFR,各年龄生育率同乘这个系数。扣完这一步再构造矩阵:

TFR_raw = sum(fert); scale = 1.8 / TFR_raw; % 目标更替水平 1.8 fert_adj = fert * scale; n = length(female2001); L = zeros(n,n); femaleShare = 100./(100+sexRatio); % 出生婴儿中女婴占比 L(1,:) = fert_adj .* sr(1) .* femaleShare; % 第一行:生育项 for i = 2:n L(i,i-1) = sr(i); % 次对角线:存活项 end

逻辑上,fert_adj 是修正后的生育率,填入矩阵第一行;sr(1) 是新生儿存活到统计时刻的比例,若数据已扣除婴儿死亡可取 1;次对角线按年龄顺序填存活率。参数说明:sexRatio 是出生性别比(以女婴 100 计的男婴数),femaleShare = 100/(100+sexRatio) 是女婴占比,正常出生性别比在 103 至 107 之间,女婴占比约 0.48 到 0.49;sr(i) 是第 i 组女性存活到下一组的比例,等于 1 减去该组死亡率。

迭代部分就是纯矩阵连乘,2001 到 2050 年一共 50 步:

years = 2001:2050; popF = zeros(n,length(years)); popF(:,1) = female2001; for k = 2:length(years) popF(:,k) = L * popF(:,k-1); end

单位要一致,female2001 是万人,迭代结果也是万人。这一步跑完拿到的是逐年女性年龄分布,总人口、劳动年龄人口、老年人口都从这张表切片求和得到。

4. MATLAB 落地:数据清洗、指标计算与结果核对

4.1 数据对齐与单位统一

Leslie 模型的输入向量必须严格同长、同组距、同单位。常见的数据源是统计年鉴抽样表,年龄按 5 岁一组、人口单位万人、生育率千分率,落到矩阵前要统一:组距统一到 1 岁(或明确选定 5 岁),人口统一到万人,生育率统一到「每女性平均生育数」而不是千分数。

对齐的检查办法很土但有效:打印四个输入向量的长度、总量,看是否互相吻合、是否与已知总人口对得上。这一步花十分钟,往往能省掉后面两小时的调试:

assert(length(female2001)==length(fert), '女性向量与生育率长度不一致'); assert(length(sr)==length(female2001), '存活率向量长度不一致'); fprintf('女性总数=%.1f 万人\n', sum(female2001));

assert 在长度不一致时直接中断,比跑到矩阵乘法才报维度错要早;打印女性总数是为了跟年鉴里的全国女性人口比对,差得太多说明分层还原那步有问题,得回去查抽样比例。

4.2 老龄化、抚养比、育龄妇女指标怎么算

所有指标都是在迭代结果 popF 上做年龄切片求和。老龄人口取 60 岁或 65 岁以上;总抚养比按非劳动年龄人口除以劳动年龄人口,劳动年龄取 15 至 64 岁;育龄妇女取 15 至 49 岁;生育旺盛期育龄妇女取 20 至 29 岁。

age = (0:n-1)'; old60 = sum(popF(age>=60,:),1); old65 = sum(popF(age>=65,:),1); labor = sum(popF(age>=15 & age<=64,:),1); child = sum(popF(age<=14,:),1); depRatio = (old65 + child)./labor; % 总抚养比 old60Pct = old60./sum(popF,1); % 60岁以上占比

每一列对应一个年份,切片求和就得到该指标的时间序列。抚养比分子里老年人口用 65 岁以上还是 60 岁以上,要和报告里的定义保持一致,原项目用的是 0 至 14 岁加 65 岁以上,再除以 15 至 64 岁。参数上要注意 age 必须和 popF 的行一一对应,若 popF 只含女性,算出来的指标是女性口径,换算总人口要乘女性占比的倒数,或者干脆用分层人口序列各自加总。

4.3 出图核对:三条曲线与参考值对照

跑完迭代至少要出三张图核对:总人口曲线看拐点和峰值年份,老龄化占比曲线看斜率是否逐渐走陡,抚养比曲线看有没有异常的阶跃。原项目的预测结果可以作为对照基准:总人口 2010 年约 14.2609 亿,2020 年约 14.9513 亿,2023 年达到峰值约 14.985 亿,2033 年回落到约 14.7455 亿;60 岁以上老年人口在本世纪 40 年代中后期达到约 4.45 亿、占比约 33.277%,65 岁以上约 3.51 亿、占比约 25.53%。

核对不能只看自己的曲线,要把参考报告里的预测值画在同一张图上,看两条线的相对位置和拐点年份差多少。偏早通常意味着生育率偏低没修正,偏晚通常是生育率被高估或存活率填错。这一步是发现参数错误最快的办法,比逐行读代码高效得多。

5. 避坑排查:五处让预测峰值与人口数翻车的记录

这几条都是复现时真实踩出来的,按「现象 → 原因 → 解决」列清楚,照着排能少走不少弯路。

第一处:起始年份混用,K 值不可比。现象是用 1954 年拟合的 K 去解释 1980 年起点的预测,2033 年总人口多出几千万。原因是不同历史阶段的外部条件不同,K 只是该阶段的等效承载力,跨阶段比绝对值没有意义。解决办法是同一份报告里只用一条曲线的 K,跨阶段只比趋势和拐点,不比绝对数值。这条血泪经验来自一次把两条曲线参数混到一张表的返工。

第二处:总和生育率没修正,人口峰值提前。现象是迭代到 2023 年前后峰值就到,比参考值早了约十年。原因是抽样数据算出的 TFR 只有约 1.42,低于专家给出的更替水平 1.8。解决办法是按 1.8 / TFR_raw 同比例放大各年龄生育率再构造矩阵,放大后要重新检查总和生育率是不是真的等于 1.8。

第三处:生育率口径混用,新生儿数偏大一倍。现象是 0 岁组人数明显高于预期。原因是 fᵢ 本来是含男女的生育率,乘了女婴占比之后又被当成女儿数再处理了一遍,或者反过来漏乘。解决办法是先明确数据表里生育率的定义,含男女才乘女婴占比,只含女儿数就不乘。这条建议在构造矩阵前用一行注释把口径写死。

第四处:年龄组距与时间步长不一致。现象是矩阵维度崩溃,或者结果年际跳变。原因是数据是 5 岁一组,时间步长却设了 1 年。解决办法是重采样到统一组距,或把时间步长改成 5 年。组距一变,所有切片阈值(15、49、60、64)都要跟着对齐,别只改了矩阵忘了指标。

第五处:存活率未扣婴儿死亡,0 岁组偏大。现象是第一年新生儿数量偏高。原因是生育率里没扣婴儿死亡,又乘了 s₀。解决办法是先确认数据是否已扣婴儿死亡,已扣则 L(1,i) 里不再乘 s₀,或把 s₀ 置 1。这几处都属于「跑通了但结果不对」的隐性错误,最好像第 4 章那样用参考值反查,而不是靠肉眼读矩阵。

6. 敏感性扫描:把 k 值从 1.6 扫到 2.2,看结论稳不稳

Leslie 模型里能人为调控的旋钮只有一个——总和生育率 k。原项目把 k 设成 1.6、1.8、2.0、2.2 四档,分别跑总人口和老龄化两条曲线,看结论对 k 有多敏感。这段扫描最有价值的地方不是找到一个「最优 k」,而是回答「换个假设结论还成不成立」,也就是验证方法本身。

kList = [1.6 1.8 2.0 2.2]; popAll = zeros(length(years),length(kList)); for j = 1:length(kList) scale = kList(j)/TFR_raw; fertK = fert * scale; Lk = L; Lk(1,:) = fertK .* sr(1) .* femaleShare; popF = zeros(n,length(years)); popF(:,1) = female2001; for k = 2:length(years) popF(:,k) = Lk*popF(:,k-1); end popAll(:,j) = sum(popF,1); end

扫描结果的方向很明确:k 小则人口峰值低、老龄化推进得快;k 大则峰值高、老龄化平缓。这两条正好对应两种极端政策的后果——只盯总量控制会加速老龄化,只盯老龄化去放任增长会给资源环境带来压力,真正的着力点在两者之间找平衡。参数上注意每档 k 只改矩阵第一行,存活项保持不动,这样扫描结果才可归因到生育率本身。

验证我一般走三步:第一步,把总人口曲线和参考报告的预测值画在一张图上,拐点年份偏差是否在可接受范围内;第二步,看残差序列是否零均值、有无明显趋势;第三步,换一组年龄分组(比如 5 岁一组)重跑一遍,看结论方向是否一致而非数值是否相同。三步都过,才敢把这个模型的结果往外给。

这种把「参数扫描加多重验证」固化进流程的习惯,是这几年做复现最值钱的一部分——单条曲线的 R2 再高,也回答不了「换个假设还成立吗」这个问题。从那以后我每次交付人口预测,都强制把 k 值扫描和残差图走一遍,希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询