サンプル・プログラムの実行例

サンプル・プログラム
population.php | サンプル・プログラム本体。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
population2011.csv | 統計データ 2011年版 |
population2017.csv | 統計データ 2017年版 |
population2018.csv | 統計データ 2018年版 |
population2019.csv | 統計データ 2019年版 |
population2020.csv | 統計データ 2020年版 |
population2021.csv | 統計データ 2021年版 |
population2022.csv | 統計データ 2022年版 |
population2023.csv | 統計データ 2023年版 |
バージョン | 更新日 | 内容 |
---|---|---|
2.6.0 | 2025/06/07 | calcFertilityRatio21()関数を追加 |
2.5.4 | 2025/01/19 | データを2023年版に更新,PHP8.4対応 |
2.5.3 | 2023/12/20 | データを2022年版に更新,pahooInputData導入 |
2.5.2 | 2023/05/05 | グラフにフッタを追加 |
2.5.1 | 2023/02/12 | データを2021年に更新 |
バージョン | 更新日 | 内容 |
---|---|---|
1.8.1 | 2025/03/15 | validRegexPattern() -- debug |
1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
1.7.0 | 2024/10/09 | validURL() validEmail() 追加 |
1.6.0 | 2024/10/07 | isButton() -- buttonタグに対応 |
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
解説:準備
population.php
66: // 元となるCSVデータファイル名
67: // 人口・死亡率:2023年 https://www.stat.go.jp/data/nenkan/74nenkan/02.html
68: // 出生率:2022年 https://www.ipss.go.jp/syoushika/tohkei/Popular/Popular2024.asp?chap=4
69: define('FILE_DATA', './population2023.csv');
70:
71: // 推計開始年(元データの年次)
72: define('YEAR_START', 2021);

"population2023.csv" の各列の構造は以下の通り。いずれも2023年時点の値である。
- 年齢
- その年齢における男性の死亡率(千人あたり)
- その年齢における女性の死亡率(千人あたり)
- その年齢における出生率(女性一人あたり)
- その年齢における男性人口(千人)
- その年齢における女性人口(千人)
population.php
90: // 従業者規模別民営事業所数(2016年)
91: // http://www.stat.go.jp/data/nihon/07.html
92: // num=事業所数, color=描画色
93: $tableCompany = array(
94: '1-4人' => array('num'=>3047110,'color'=>'#006600'),
95: '5-9人' => array('num'=>1057293,'color'=>'#00AA00'),
96: '10-19人' => array('num'=>649836, 'color'=>'#00CC00'),
97: '20-29人' => array('num'=>232601, 'color'=>'#00FF00'),
98: '30-49人' => array('num'=>163074, 'color'=>'#00FF44'),
99: '50-99人' => array('num'=>100428, 'color'=>'#00FF88'),
100: '100-199人' => array('num'=>39002, 'color'=>'#00FFAA'),
101: '200-299人' => array('num'=>10454, 'color'=>'#00FFCC'),
102: '300人以上' => array('num'=>12223, 'color'=>'#00FFFF')
103: );
解説:出生率
population.php
207: /**
208: * 出生率の推計関数:推計開始年から一定
209: * @param array $items 推計表
210: * @return なし
211: */
212: function calcFertilityRatio1(&$items) {
213: global $MaxAge;
214:
215: for ($i = 1; $i < PERIOD; $i++) {
216: $year = YEAR_START + $i;
217: for ($age = 0; $age <= $MaxAge; $age++) {
218: $items[$year][$age]['fertility'] = $items[$year - 1][$age]['fertility'];
219: }
220: }
221: }
population.php
223: /**
224: * 出生率の推計関数:毎年1%ずつ減少,0.9で一定
225: * @param array $items 推計表
226: * @return なし
227: */
228: function calcFertilityRatio2(&$items) {
229: global $MaxAge;
230:
231: $d = (-0.01); // 毎年増分
232: $t2 = 0.9; // 下限値
233: for ($i = 1; $i < PERIOD; $i++) {
234: $year = YEAR_START + $i;
235: $total = 0;
236: for ($age = 0; $age <= $MaxAge; $age++) {
237: $items[$year][$age]['fertility'] = $items[$year - 1][$age]['fertility'] * (1 + $d);
238: $total += $items[$year][$age]['fertility'];
239: }
240: if ($total <= $t2) $d = 0;
241: }
242: }
population.php
244: /**
245: * 出生率の推計関数:毎年3%ずつ減少,0.7で一定
246: * @param array $items 推計表
247: * @return なし
248: */
249: function calcFertilityRatio21(&$items) {
250: global $MaxAge;
251:
252: $d = (-0.03); // 毎年増分
253: $t2 = 0.7; // 下限値
254: for ($i = 1; $i < PERIOD; $i++) {
255: $year = YEAR_START + $i;
256: $total = 0;
257: for ($age = 0; $age <= $MaxAge; $age++) {
258: $items[$year][$age]['fertility'] = $items[$year - 1][$age]['fertility'] * (1 + $d);
259: $total += $items[$year][$age]['fertility'];
260: }
261: if ($total <= $t2) $d = 0;
262: }
263: }
population.php
265: /**
266: * 出生率の推計関数:毎年1%ずつ増加,1.8で一定
267: * @param array $items 推計表
268: * @return なし
269: */
270: function calcFertilityRatio3(&$items) {
271: global $MaxAge;
272:
273: $d = 0.01; // 毎年増分
274: $t1 = 1.8; // 上限値
275: for ($i = 1; $i < PERIOD; $i++) {
276: $year = YEAR_START + $i;
277: $total = 0;
278: for ($age = 0; $age <= $MaxAge; $age++) {
279: $items[$year][$age]['fertility'] = $items[$year - 1][$age]['fertility'] * (1 + $d);
280: $total += $items[$year][$age]['fertility'];
281: }
282: if ($total >= $t1) $d = 0;
283: }
284: }
population.php
286: /**
287: * 出生率の推計関数:0.9と1.8の間で増減
288: * @param array $items 推計表
289: * @return なし
290: */
291: function calcFertilityRatio4(&$items) {
292: global $MaxAge;
293:
294: $sign = (-1); // 増減符号
295: $d = 0.01; // 毎年増分
296: $t1 = 1.8; // 上限値
297: $t2 = 0.9; // 下限値
298: for ($i = 1; $i < PERIOD; $i++) {
299: $year = YEAR_START + $i;
300: $total = 0;
301: for ($age = 0; $age <= $MaxAge; $age++) {
302: $items[$year][$age]['fertility'] = $items[$year - 1][$age]['fertility'] * (1 + $d * $sign);
303: $total += $items[$year][$age]['fertility'];
304: }
305: if ($total >= $t1) $sign = (-1);
306: if ($total <= $t2) $sign = (+1);
307: }
308: }

出生率の変動によって人口推計結果が大幅に変わるので、適宜関数を用意してみてほしい。
解説:死亡率
population.php
321: /**
322: * 死亡率の推計関数:推計開始年から一定
323: * @param array $items 推計表
324: * @return なし
325: */
326: function calcDeathRatio1(&$items) {
327: global $MaxAge;
328:
329: for ($i = 1; $i < PERIOD; $i++) {
330: $year = YEAR_START + $i;
331: for ($age = 0; $age <= $MaxAge; $age++) {
332: $items[$year][$age]['death_male'] = $items[$year - 1][$age]['death_male'];
333: $items[$year][$age]['death_female'] = $items[$year - 1][$age]['death_female'];
334: }
335: }
336: }
population.php
338: /**
339: * 死亡率の推計関数:推計開始年から毎年4‰ずつ減少
340: * @param array $items 推計表
341: * @return なし
342: */
343: function calcDeathRatio2(&$items) {
344: global $MaxAge;
345:
346: $d = (-0.004); // 毎年増分
347: for ($i = 1; $i < PERIOD; $i++) {
348: $year = YEAR_START + $i;
349: for ($age = 0; $age <= $MaxAge; $age++) {
350: $items[$year][$age]['death_male'] = $items[$year - 1][$age]['death_male'] * (1 + $d);
351: $items[$year][$age]['death_female'] = $items[$year - 1][$age]['death_female'] * (1 + $d);
352: }
353: }
354: }
population.php
356: /**
357: * 死亡率の推計関数:推計開始年から毎年4‰ずつ減少
358: * @param array $items 推計表
359: * @return なし
360: */
361: function calcDeathRatio3(&$items) {
362: global $MaxAge;
363:
364: $d = (+0.004); // 毎年増分
365: for ($i = 1; $i < PERIOD; $i++) {
366: $year = YEAR_START + $i;
367: for ($age = 0; $age <= $MaxAge; $age++) {
368: $items[$year][$age]['death_male'] = $items[$year - 1][$age]['death_male'] * (1 + $d);
369: $items[$year][$age]['death_female'] = $items[$year - 1][$age]['death_female'] * (1 + $d);
370: }
371: }
372: }

死亡率の変動によって人口推計結果が大幅に変わるので、適宜関数を用意してみてほしい。
解説:事業所数
population.php
374: /**
375: * 事業所数の推計関数:推計開始年から生産年齢人口に応じて変化
376: * @param array $items 推計表
377: * @return なし
378: */
379: function calcCompany(&$items) {
380: global $tableCompany;
381:
382: // 初年度の生産年齢人口
383: $worker0 = 0;
384: for ($age = WORKER_AGE_MIN; $age <= WORKER_AGE_MAX; $age++) {
385: $worker0 += $items[YEAR_START][$age]['male'] + $items[YEAR_START][$age]['female'];
386: }
387:
388: // 推計
389: for ($i = 0; $i < PERIOD; $i++) {
390: $year = YEAR_START + $i;
391: $worker = 0;
392: for ($age = WORKER_AGE_MIN; $age <= WORKER_AGE_MAX; $age++) {
393: $worker += $items[$year][$age]['male'] + $items[$year][$age]['female'];
394: }
395: foreach ($tableCompany as $key=>$arr) {
396: $items[$year]['company'][$key] = $arr['num'] * ($worker / $worker0);
397: }
398: }
399: }
解説:人口推計
population.php
401: /**
402: * 人口推計+事業所数推計
403: * @param string $opt1 オプション1(出生率の推計関数名)
404: * @param string $opt2 オプション2(死亡率の推計関数名)
405: * @param string $opt3 オプション3(事業所数の推計関数名)
406: * @return array 人口推計結果/FALSE:データファイルがないなど
407: */
408: function calcPopulation($opt1, $opt2, $opt3) {
409: global $MaxAge;
410:
411: $items = array();
412:
413: // 元となるデータファイルを読み込む
414: $infp = fopen(FILE_DATA, 'r');
415: if ($infp == FALSE) return FALSE;
416: fgetcsv($infp, 9999, ',', '"', '\\'); // ラベル行をスキップ
417: while (! feof($infp)) {
418: $arr = fgetcsv($infp, 9999, ',', '"', '\\');
419: if ($arr == FALSE) break;
420: if (! is_numeric($arr[1])) continue;
421: $age = $arr[0];
422: $items[YEAR_START][$age]['death_male'] = $arr[1] / 1000; // 年齢別死亡率(男性)
423: $items[YEAR_START][$age]['death_female'] = $arr[2] / 1000; // 年齢別死亡率(女性)
424: $items[YEAR_START][$age]['fertility'] = $arr[3]; // 年齢別出生率
425: $items[YEAR_START][$age]['male'] = $arr[4] / 10; // 男性人口(単位:万人)
426: $items[YEAR_START][$age]['female'] = $arr[5] / 10; // 女性人口(単位:万人)
427: }
428: fclose($infp);
429: $MaxAge = $age; // 最高齢
430: $opt1($items); // 出生率の推計
431: $opt2($items); // 死亡率の推計
432:
433: // 人口推計
434: for ($i = 1; $i < PERIOD; $i++) {
435: $year = YEAR_START + $i;
436:
437: // 0歳
438: $items[$year][0]['male'] = 0;
439: $items[$year][0]['female'] = 0;
440: for ($age = 0; $age <= $MaxAge; $age++) {
441: $n = $items[$year - 1][$age]['female'] * $items[$year - 1][$age]['fertility']; // 出生数
442: $items[$year][0]['male'] += ($n / 2);
443: $items[$year][0]['female'] += ($n / 2);
444: }
445:
446: // 1歳~$MaxAge歳
447: for ($age = 1; $age <= $MaxAge; $age++) {
448: $items[$year][$age]['male'] = $items[$year - 1][$age - 1]['male'] * (1 - $items[$year][$age]['death_male']);
449: $items[$year][$age]['female'] = $items[$year - 1][$age - 1]['female'] * (1 - $items[$year][$age]['death_female']);
450: }
451: }
452: $opt3($items); // 事業所数の推計
453:
454: return $items;
455: }

まず、冒頭で紹介した初期値データ・ファイル FILE_DATA を読み込む。そして、選択された関数により出生率と死亡率を計算し、推計表 $items に代入する。
次に、このデータを元に、毎年の年齢別人口を計算していく。
0歳人口は、年齢毎に前年の女性人口と出生率を乗算し、男女半数ずつに分けて代入する。
1歳以降の人口は、年齢毎に前年の男女別人口と男女別死亡率を乗算し、代入する。
考察
ただ、国立社会保障・人口問題研究の推計では50年後の男性の平均寿命が84歳(現在79歳)、女性が91歳(現在86歳)となっており、いくらなんでも長生きし過ぎなのではないかと感じる。
そこで本プログラムでは、死亡率が毎年4‰増加(平均寿命が縮む)というオプションを用意してみた。この場合、50~100年後には高齢者比率が減少する。
本プログラムでは各年齢の死亡率が一律に減少/増加するような関数しか用意していないが、高齢者ほど死亡率が高くなるようにすると、高齢者比率の減少は早く訪れる。

出生率については、当たり前のことだが、いま急に増やすことができたとしても、その効果が現れるのは数十年後になる。死亡率や出生率を多少変化させたところで、40~50年後に高齢者割合が極大になる事態は避けられない。
むしろ出生率を急に増やすと、一時的に生産年齢人口が低下するため、現役世代への負担が重くなるという事態に陥る。

余談
年金財政は、基礎年金勘定、国民年金勘定、厚生年金勘定に加え、各共済組合などの帳簿があるので、計算はかなり複雑になる。基礎数値は「厚生労働省年金局 年金財政ホームページ」が参考になる。

簡単に試算したところでは、団塊ジュニアが65歳以上になる25年後から財政が急激に悪化することが確認できた。
ただ、このまま婚姻率が上がらないと、3号被保険者の数がそれほど増えない一方、出生率も極端に低下するだろうから、推計のブレ幅はかなり大きいと言える。
参考書籍
参考サイト
- 日本の将来推計人口:国立社会保障・人口問題研究所
- 日本統計年鑑:総務省統計局
- PHPとJpGraphで人口ピラミッドを表示する:ぱふぅ家のホームページ
そこで今回は、PHPを使って人口の推計を行うシミュレーション・プログラムを作ってみることにする。
(2025年6月7日)コロナ禍以降出生率が急減していることから,出生率が毎年3%ずつ減少,0.7で一定とするシナリオを追加
(2025年1月19日)データを2023年版に更新,PHP8.4対応