简介《Leslie人口增长模型》是一份面向人口统计学、数学建模学习者与竞赛参赛者的文档围绕中国人口总量及年龄结构预测展开重点解决Logistic阻滞增长模型与Leslie矩阵模型在中期、长期预测中的建模与比较问题。压缩包内含1个doc文件大小约988KB便于直接查阅完整推导、数据整理与结果分析。文档以1980—2005年人口数据建立Logistic模型给出2010、2020、2033年总量预测又按年龄分布构造Leslie矩阵讨论劳动年龄人口、老年人口、抚养比、老龄化及育龄妇女人数变化并完成残差分析、优缺点评价与推广。读者可据此理解两类模型的假设、参数设置、MATLAB实现思路和预测指标口径也能参考其数据组织与论文式写作框架。目前已有5157人学习适合需要人口预测案例、数学建模论文范本或课程作业参考的读者。1. 从“预测一个数”到“预测一张年龄表”这道题真正要交付什么拿到人口增长预测这类题目多数人的第一反应是找条曲线把历年总人口拟合出来交一个 2030 年的数字就收工。我第一次也是这么做的直到把题目翻到第二问才发现不对老龄化、人口抚养比、劳动年龄人口、育龄妇女人数这些指标没有一个是“总人口”能推出来的。Leslie 人口增长模型 解决的正是这件事——它不预测一个数而是预测一整个年龄分布再从这个分布里派生所有结构指标。这套方案适合两类人要交数学建模课设、统计建模毕设的学生以及需要用年龄结构做中长期测算的从业者。下面按我实际做下来的顺序拆数据怎么对齐口径Logistic 怎么定参数Leslie 矩阵怎么组装最后怎么验收答辩。2. 数据底账与路线分工把千万、亿和抽样比先对齐2.1 三份数据的量级差在哪这道题的数据其实有三层量级完全不同混在一起算必然出错。第一层是历年总人口表1954 年到 2005 年逐年给出单位是千万比如 1954 年 60.2、1980 年 98.705、2005 年 130.756换算成亿就是 6.02 亿、9.8705 亿、13.0756 亿。第二层是 2001 年的人口抽样调查数据分市、镇、乡给出男女人数城市男 147907、城市女 147465、镇男 80279、镇女 77976、乡男 394690、乡女 372242六项加起来 1220559 人。第三层是抽样数据里的各种比率分年龄女性占比、分年龄生育率、分年龄死亡率、出生性别比全是比率没有绝对数。关键在第一层和第二层之间。1220559 是抽样人数全国 2001 年总人口是 127.627 千万也就是 12.7627 亿两者差三个数量级。通常的做法是先用抽样人数算出市、镇、乡各自占抽样的比重再乘全国总人口得到三段各自的全国总量。按上面这组数算城市约占 24.20%、镇约占 12.97%、乡约占 62.83%对应全国 3.089 亿、1.655 亿、8.019 亿。这个折算步骤一定要单独写成一小节因为它同时是后面所有分年龄人数计算的入口口径错一步Leslie 矩阵整个就是错的。2.2 两条建模路线各自回答什么问题维度模型Ⅰ Logistic模型Ⅱ Leslie状态量总人口一个标量分年龄女性人口向量核心参数环境容量 K、内禀增长率 r生育女儿数 b、存活率 s数据需求历年总人口序列分年龄生育率、死亡率、性别比能回答总量中短期趋势总量、劳动年龄人口、老龄化、抚养比主要风险外推边界不清数据质量敏感、参数修正争议两条线不是二选一是互相校验。Logistic 参数少、可解释性强但推不出任何结构信息Leslie 能派生全套指标可它对生育率的准确性极其敏感稍有偏差峰值年份就能漂十年。我的做法是让两条线都算总人口差值控制在 1 个百分点以内就互相当背书差太多就回去查数据而不是硬写结论。2.3 假设清单要写到“能被追问”的程度原题给了四条假设社会稳定不发生重大灾害和战争90 岁以上妇女统一按 90 岁计较短时间内平均年龄变化较小可认为不变不考虑移民。这四条不能只是罗列每条后面都得跟一句它对模型的实际影响。第一条决定了 Logistic 的 K 在整个预测期内是常数一旦中途出现大的外部冲击K 就得重估。第二条是为了把年龄组截断在 91 组否则矩阵维度不封闭代价是高龄段的死亡信息被压缩对老龄化指标的高龄部分会有轻微低估。第三条约束的是生育率和死亡率不随时间变化这直接导致后面峰值年份可能偏早——因为真实场景里生育率是持续下行的。第四条省掉了迁移项对全国口径影响不大但如果换成省市口径这套模型就直接失效。这四条写清楚答辩时被问到“你的假设合理吗”就有话可接。3. 模型Ⅰ的落地Logistic 三段拟合与可决系数选优3.1 阻滞增长方程的推导与参数含义Logistic 的出发点是把指数增长里的常数增长率改成一个随人口数量下降的函数。设人口为 x(t)最大容量为 K则增长率写成 r(1 - x/K)微分方程为dx/dt r·x·(1 - x/K)分离变量积分后得到解析解x(t) K / (1 (K/x₀ - 1)·e^(-r·t))三个参数各管一件事K 是环境能容纳的人口上限曲线最终会贴着它走r 决定上升段的陡峭程度r 越大越早接近 Kx₀ 是初始年份的人口把曲线整体平移。拟合的本质就是用最小二乘去搜这三个参数让曲线和实测点残差平方和最小。判断拟合好坏用可决系数 R² 1 - Σ(残差²)/Σ((x - x̄)²)越接近 1 越好。另一个更直观的指标是残差绝对值之和 Σ|残差|单位跟人口一样是千万能直接看出平均偏了多少。3.2 nlinfit 的初值怎么给才收敛nlinfit做的是非线性最小二乘它不保证全局收敛初值给偏了要么报错要么收敛到局部极小。可行的办法是先从曲线上挑两个时间跨度较大的点反解出 K 和 r 作为初值。下面这段是 1954 年起点那组的写法思路三段通用只是换 x₀ 和起止年份% 模型Ⅰ1954—2005 年总人口 Logistic 拟合 t 0:51; % 1954 记为 t0 x [60.2 61.5 62.8 64.6 66 67.2 66.2 65.9 67.3 69.1 ... 70.4 72.5 74.5 76.3 78.5 80.7 83 85.2 87.1 89.2 ... 90.9 92.4 93.7 95 96.259 97.5 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]; % 单位千万 % 用两个远端点反解初值t5 对应 67.2t20 对应 90.9 x0 x(1); syms c d eq1 c/(1(c/x0-1)*exp(-5*d)) 67.2; eq2 c/(1(c/x0-1)*exp(-20*d)) 90.9; sol solve([eq1, eq2], [c, d]); b0 [double(sol.c), double(sol.d)]; % 初始参数 fun (b,t) b(1)./(1(b(1)/x0-1).*exp(-b(2).*t)); [b1, r1] nlinfit(t, x, fun, b0); % b1 为拟合参数r1 为残差 Rsq 1 - sum(r1.^2) / sum((x-mean(x)).^2); % 可决系数 W sum(abs(r1)); % 残差绝对值之和几点说明。第一行t 0:51里 0 对应 1954 年所以 2005 年是 t51共 52 个点和 x 的长度必须一致少一个 MATLAB 直接报维度不匹配。syms那三行是反解初值新版 MATLAB 的solve必须先声明符号变量老版本可以直接传字符串这里按新语法写。nlinfit返回三个值第三个是雅可比矩阵实际用不上只取前两个。Rsq这里对残差平方和取了sum如果照抄某些写法直接写1 - r1.^2/(x-mean(x)).^2得到的是一个向量那是个典型翻车点后面会讲。1954 年这组跑出来 K≈180.9871、r≈0.0336残差绝对值之和 57.9992。3.3 三个起点为什么结论差这么多换起点重跑同一套代码1963 年起点得到 K≈151.4513、r≈0.0484残差绝对值之和 27.80461980 年起点残差绝对值之和降到 10.1699可决系数 0.9987。三组结果放在一张表里看拟合起点数据跨度残差绝对值之和可决系数判断195452 年57.9992未单列残差非正态拟合不可靠196343 年27.8046未单列残差大致对称效果较好198026 年10.16990.9987最优采用差距的根源不在算法在数据本身。1954 到 1962 这一段前期有一次出生高峰中间几年人口数据出现明显回落随机误差压根不服从正态分布而最小二乘法恰恰依赖这个前提所以拟合再漂亮也不能用。1963 年之后增长基本遵循自然规律误差分布接近对称但那时段的生育行为和后面差别太大混在一起会把曲线拉偏。1980 年以后生育行为进入相对稳定的阶段没有大的外部扰动残差围绕零轴上下波动图形基本对称这才是最小二乘能发挥的前提。提示换起点不是为了凑一个好看的可决系数而是为了让“随机误差服从正态分布”这个前提成立。先画残差图再决定用哪段数据顺序不能反。3.4 外推边界与专家报告对表用 1980 年那组参数外推得到 2010 年 13.55357 亿、2020 年 14.18440 亿、2033 年 14.70172 亿。附件 1 的研究报告给出的参照值是 2010 年 13.6 亿、2020 年 14.5 亿、2033 年前后达峰 15 亿左右。2010 年差 0.05 亿2020 年差 0.32 亿2033 年差 0.3 亿相对误差都在 2% 出头。这个误差量级是可以接受的但必须说清楚它的性质Logistic 给的是趋势上限不是年度精确值。它的强项是告诉你“大概什么时候增速会明显放缓”弱项是它完全看不到年龄结构一旦生育行为在预测期内发生跳变曲线就只会在错误的 K 上平移。所以这个结果在方案里的定位是交叉校验项真正的结构指标要靠下一个模型。4. 模型Ⅱ的落地Leslie 矩阵组装、迭代与结构指标派生4.1 年龄组划分与女性状态向量Leslie 的核心是把人口按年龄切成等宽的小段只跟踪女性。这个选择不是偷懒决定下一代数量的是育龄妇女的人数和她生几个女儿男性数量不直接进入生育方程用女性单性别模型就能闭环。男性人口靠出生性别比和对应存活率另算或者直接用女性占比反推总人口后者简单但会损失一点精度。划分上按 1 岁一组切 0 到 90 岁90 岁以上统一并入最后一组一共 91 个年龄组。状态向量 v(t) 的第 i 个分量表示 t 时刻第 i 年龄组的女性人数时间步长取 1 年和年龄组宽度一致。为什么不按 5 岁或 10 岁分组因为育龄妇女的高峰年龄段集中在 20 到 29 岁组宽一旦到 5 岁这个峰的形态就被抹平了而后面判断“生育旺盛期育龄妇女峰值出现在哪一年”恰恰依赖这个峰的细节。4.2 生育率折算从“生育率”到“平均生育女儿数”附件给的是分年龄生育率含义是某年龄组每个妇女平均生育的孩子数这里面男女都有。Leslie 矩阵第一行要的是“每个女性平均生育的女儿数”中间差一个出生性别比的折算。% 1) 生育率折算为“每个女性平均生育的女儿数” % fr(i): 第 i 年龄组的分年龄生育率含男婴有效区间为 15~49 岁 % sr(i): 第 i 年龄组的出生性别比口径为“女100 时的男婴数” girl_ratio 100 ./ (100 sr); % 女婴占出生人数的比例 b_raw fr .* girl_ratio; % 每个女性平均生育的女儿数 % 2) 与更替水平对齐做整体修正 tfr sum(fr); % 原始总和生育率 scale 1.8 / tfr; % 目标是更替水平 1.8 b b_raw * scale; % 3) 补零到 91 维只有 15~49 岁非零 b_full zeros(1, 91); b_full(16:50) b; % 索引 16 对应 15 岁这段的关键在第二步。按原始生育率算出来的总和生育率明显低于 1.8直接拿去迭代人口会以不合理的速度塌下去。更替水平 1.8 是外部给定的参照把整条生育率曲线按比例缩放到这个水平是常见的修正做法。但修正要有边界缩放是等比例的意味着假设各年龄组生育率被同等程度低估这在数据整体偏低时勉强成立如果只是某个年龄段异常就得逐段修而不是整体乘系数。这一点在答辩时很容易被追问。注意b_full(16:50) b这个索引对应关系必须和后面计算抚养比时的年龄切分严格一致错一位整个结果都不可信。索引 1 代表 0 岁索引 16 代表 15 岁这个约定要在代码开头写死。4.3 存活率与 Leslie 矩阵的组装存活率等于 1 减死亡率市、镇、乡三套数据按人口占比加权合并% s(i): 第 i 年龄组女性活到 i1 岁的存活率 s_city 1 - dr_city; s_town 1 - dr_town; s_vil 1 - dr_vil; w [P_city, P_town, P_vil] / (P_city P_town P_vil); % 三段人口权重 s w(1)*s_city w(2)*s_town w(3)*s_vil; % 组装 Leslie 矩阵91×91 n 91; L zeros(n); L(1, :) b_full; % 第一行各年龄组女性的生育女儿数 for i 2:n L(i, i-1) s(i-1); % 次对角线上一组活到下一组的存活率 end矩阵的结构很固定第一行全是生育项次对角线全是存活项其余位置全零。合法性条件是所有 b ≥ 0、所有 s 落在 0 到 1 之间且至少有一个 b 大于零满足这三条它才是一个合格的 Leslie 矩阵否则迭代出来的人数会出现负数。组装完可以用sum(L(1,:))快速核对总和生育率有没有落在合理区间。按月或按岁迭代就是把矩阵反复左乘初始向量v v0; % 2001 年女性分年龄人数91×1 列向量 T 49; % 预测到 2050 年 V zeros(n, T1); V(:,1) v; for k 1:T V(:,k1) L * V(:,k); % 逐年推进 end female_share 0.4897; % 2001 年女性占总人口比例 total sum(V, 1) / female_share; % 反推总人口单位人v0的来源是把 4.2 里的分年龄女性占比乘上三段各自的全国人口再合并这一步涉及的中间表比较长通常用 Excel 先整理成 91 行再导进 MATLAB比在脚本里硬拼可读性好得多。female_share取 0.4897 是按抽样数据里女性人数 597683 除以总抽样人数 1220559 得来的用它作常数反推总人口是简化处理误差在 1% 量级写进假设里就行。4.4 结构指标派生老龄化、抚养比与育龄妇女有了逐年分年龄女性人数题目要的所有指标都能从同一个矩阵里切出来for k 1:T1 vk V(:,k); child sum(vk(1:15)); % 0~14 岁 labor sum(vk(16:65)); % 15~64 岁 old60 sum(vk(61:end)); % 60 岁及以上 old65 sum(vk(66:end)); % 65 岁及以上 dep(k) (child old65) / labor; % 总抚养比 ratio60(k) old60 / sum(vk); % 60 岁以上占比 ratio65(k) old65 / sum(vk); % 65 岁以上占比 fertile(k) sum(vk(16:50)); % 15~49 岁育龄妇女 peak(k) sum(vk(21:30)); % 20~29 岁生育旺盛期 end跑出来的结果总人口 2010 年 14.2609 亿、2020 年 14.9513 亿、2023 年达峰 14.985 亿、2033 年回落到 14.7455 亿。15 到 64 岁劳动年龄人口 2010 年 10.4421 亿2013 年达到高峰 10.4852 亿后转降。老龄化方面2001 年 60 岁以上 1.5538 亿占 11.5693%2020 年升到 2.907 亿占 19.443%65 岁以上 2020 年 2.0628 亿占 13.797%本世纪 40 年代中后期进入老龄高峰平台60 岁以上达 4.45 亿占 33.277%65 岁以上达 3.51 亿占 25.53%。抚养比全程呈上升趋势。这里有个必须解释的偏差Leslie 给出的峰值年份比附件报告早了大约十年。排查下来有两条原因一是出生性别比里女性占比偏小二是反算出的总和生育率只有 1.42 左右离专家给的 1.8 差得远说明原始分年龄生育率数据本身偏低修正后峰值自然前移。这个偏差要在报告里主动写出来而不是藏起来。4.5 生育率灵敏度k 取 1.6 到 2.2 会怎样把所有分年龄生育率整体乘上一个系数让总和生育率分别等于 1.6、1.8、2.0、2.2重跑四遍迭代能看出政策的敏感区间for k [1.6, 1.8, 2.0, 2.2] Lk L; Lk(1,:) b_full * (k / 1.8); % 按目标总和生育率整体缩放 Vk zeros(n, T1); Vk(:,1) v; for j 1:T Vk(:,j1) Lk * Vk(:,j); end total_k sum(Vk,1) / female_share; % 同一套循环里顺手算老龄化和抚养比存到不同列 endk1.6 时人口增长缓慢达峰后很快转入较明显的负增长同期老龄化速度最快k2.2 时总量一路膨胀峰值推后且回落平缓年龄结构反而更稳。只有 k 落在 1.8 附近总量和结构才同时处在可接受区间。这组对比是整篇里最有说服力的部分因为它直接回答了“政策该往哪个方向调”——只看总量控制会把老龄化推快只看老龄化放任增长又会让资源环境承压中间那个平衡点就是靠这四条曲线夹出来的。顺着这个思路还能往下改一步把矩阵第一行写成 b_i β·h_i其中 β 是平均生育胎数、h_i 是归一化后的生育模式通过调整结婚年龄和两胎间隔去改 h_i 的形状就能在不改总量的前提下微调年龄结构。这一步属于模型推广写进报告的“改进方向”里比硬塞进主模型更合适。5. 避坑与排查五个让预测结果翻车的典型场景5.1 建模阶段的三个坑坑一可决系数算出来是一个向量。现象是Rsq打印出来一片小数几百个数看着像出错又不像。原因是照抄了1 - r1.^2/(x-mean(x)).^2这种向量化写法MATLAB 按元素逐个相除得到的当然是向量。解决是把分子分母都聚合成标量1 - sum(r1.^2)/sum((x-mean(x)).^2)。这个坑的隐蔽之处在于向量里的数看起来也像那么回事不检查维度根本发现不了。坑二换起点后参数不收敛报“迭代次数超限”。现象是nlinfit直接抛错或者给出明显离谱的 K比如负数。原因几乎都是初值给偏了尤其 K 的初值如果比实测最大值还小函数会在迭代中撞到奇异点。解决是先用两个远端数据点反解初值或者干脆把 K 的初值设成实测最大值的 1.2 到 1.5 倍r 给 0.02 到 0.05 之间再让算法自己找。坑三Leslie 迭代几轮之后人数变成负数。现象是V里出现负值后面所有指标全废。原因通常是存活率算错了比如把死亡率当成存活率直接用或者某年龄组死亡率因为数据缺失被填成了大于 1 的值。解决是在组装矩阵前加一道断言assert(all(s 0 s 1) all(b_full 0))把非法值挡在迭代之外。另外 90 岁以上合并那一组的存活率要单独设不能沿用普通组的公式。5.2 实现与结果解读的两个坑坑四年龄组索引整体错一位。现象是老龄化比例看起来偏低或偏高但曲线形状又很合理很难一眼看出问题。原因是“索引 1 代表 0 岁”这个约定在生育率补零、抚养比切分、育龄妇女统计三处没有统一某处用了 1 代表 1 岁。解决是把年龄切分写成一组常量放在脚本开头所有地方引用常量而不是写死数字比如IDX_CHILD 1:15; IDX_LABOR 16:65;改一处全局生效。坑五拿 Logistic 的年度值去和 Leslie 的年度值逐点比较。现象是两条曲线在个别年份差了零点几亿就被判定为“模型有严重问题”。原因是两个模型的性质根本不同Logistic 是在平滑趋势上外推Leslie 是在年龄结构上做递推后者会因为某一年的出生高峰在二十年后传导出一个劳动力高峰前者完全看不到这种波动。正确的比较口径是看长期趋势和达峰年份或者看两者在 2020、2030 这类节点上的相对偏差是否在 5% 以内。提示这五条里前三条会让程序跑不出结果后两条会让结果看起来正常但结论是错的。后者更危险因为没有人会去复查一个“跑通了”的程序。6. 验收与答辩用三张表把模型的可信度讲清楚验收这类方案我一般不看代码有多长只看三张表能不能拿出来。第一张是参数表。Logistic 那边列清楚三个起点的 K、r、残差绝对值之和、可决系数Leslie 那边列清楚总和生育率修正前后的值、女性占比、矩阵维度和合法性检查结果。这张表的作用是证明“我的每个参数都有来源”而不是随手填的。第二张是预测对照表。把两个模型在 2010、2020、2030、2033、2040 这几个节点上的总人口预测值并列再把附件报告给的参照值放在第三列最右边加一列相对偏差。偏差超过 3% 的年份要能当场解释原因比如“这个年份 Leslie 偏高是因为 1985 到 1990 年的出生高峰在二十年后传导成了育龄妇女高峰”。第三张是结构指标表。60 岁以上占比、65 岁以上占比、总抚养比、劳动年龄人口、育龄妇女人数每个指标给 2001 年实测、2020 年预测、峰值年份预测三列。这张表是评委最爱追问的地方因为它直接对应题目第二问把这张表讲透基本就赢了一半。答辩环节最常见的四个追问提前准备好答案为什么选 1980 年作起点——因为要保证随机误差服从正态分布前两段数据里有明显的外部扰动可决系数 0.9987 是不是过拟合——26 个数据点拟合 2 个参数自由度足够而且残差图对称不是靠加参数堆出来的Leslie 为什么只用女性——生育方程只依赖育龄妇女男性靠性别比和存活率另算生育率整体缩放修正合理吗——合理的前提是各年龄组被同等程度低估这一点要主动说明是假设并给出灵敏度分析作为佐证。还有一个技巧值得单独说把“两模型总人口预测差值”做成一张对照图答辩时直接摊开讲。差值小的地方说明两条独立路线互相印证差值大的地方就是模型分歧点主动指出分歧比等评委指出来强得多。我吃过一次亏当时把一个 5% 的偏差藏在了附录里结果被翻出来问了十分钟从那以后我每次做多模型对照都强制把差值单独画一张图放在正文宁可自己先承认也不给别人挖的机会。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?