PHPで合計特殊出生率と婚姻率等との相関関係を求める

(1/1)
PHPで相関係数と回帰直線を表示」では、あらかじめ要した統計表ファイルを読み込んで、「合計特殊出生率と婚姻率」「合計特殊出生率と離婚率」「合計特殊出生率と妻の平均初婚年齢」の散布図と相関係数を求めた。
今回は、「e-Stat 政府の統計窓口」から都道府県別のデータを取りだし、より多数のデータを散布図上にプロットこすることで、相関関係を求めるPHPプログラムを作ってみることにする。また、「合計特殊出生率と夫の平均初婚年齢」を追加した。

目次

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

PHPで合計特殊出生率と婚姻率等との相関関係を求める

サンプル・プログラムのダウンロード

圧縮ファイルの内容
birthRate.phpサンプル・プログラム
.pahooEnvクラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。
使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
pahooCache.phpキャッシュ処理に関わるクラス pahooCache。
キャッシュ処理に関わるクラスの使い方は「PHPで天気予報を求める」を参照。include_path が通ったディレクトリに配置すること。
pahooStat.php統計に関わる暮らす。
使い方は「PHPで相関係数と回帰直線を表示」「PHPで太陽黒点相対数の周期変化を描く」などを参照。include_path が通ったディレクトリに配置すること。
birthRate.php 更新履歴
バージョン 更新日 内容
1.0.0 2026/01/12 初版
pahooInputData.php 更新履歴
バージョン 更新日 内容
2.0.1 2025/08/11 getParam() bug-fix
2.0.0 2025/08/11 pahooLoadEnv() 追加
1.9.0 2025/07/26 getParam() 引数に$trim追加
1.8.1 2025/03/15 validRegexPattern() debug
1.8.0 2024/11/12 validRegexPattern() 追加
pahooCache.php 更新履歴
バージョン 更新日 内容
1.3.0 2025/12/06 PHP8.5対応:curl_closeを使わない
1.2.0 2025/09/06 cLoad() HTTPヘッダを送信できるようにした
1.1.3 2025/08/10 var→public
1.1.2 2023/07/22 bug-fix
1.1.1 2023/02/11 コメント追記
pahooStat.php 更新履歴
バージョン 更新日 内容
1.2.1 2025/11/29 PHP8.5対応:double→float 対象コメント変更
1.2 2020/08/14 LSM()追加
1.1 2018/04/22 simple_moving_average() 追加
1.0 2018/04/07 初版

準備:PHP の https対応

クラウド連携や相手先サイトのデータを読み込むのに https通信を使うため、PHPに OpenSSLモジュールが組み込まれている必要がある。関数  phpinfo  を使って、下図のように表示されればOKだ。
OpenSSL - PHP
そうでない場合は、次の手順に従ってOpenSSLを有効化し、PHPを再起動させる必要がある。

Windowsでは、"php.ini" の下記の行を有効化する。
extension=php_openssl.dll
Linuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順

これで準備は完了だ。

準備:pahooInputData 関数群

PHPのバージョンや入力データのバリデーションなど、汎用的に使う関数群を収めたファイル "pahooInputData.php" が同梱されているが、include_path が通ったディレクトリに配置してほしい。他のプログラムでも "pahooInputData.php" を利用するが、常に最新のファイルを1つ配置すればよい。

また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。

準備:pahooCache クラス

pahooCache.php

  13: class pahooCache {
  14:     const LIFE_CACHE = (2 * 60);        // キャッシュ保持時間(デフォルト;分)
  15:     const DEF_DIRCACHE = './pcache/';   // キャッシュ・ディレクトリ(デフォルト)
  16: 
  17:     public $lifeCache;      // キャッシュ保持時間(分)(0:キャッシュしない)
  18:     public $dirCache;       // キャッシュ用ディレクトリ
  19:     public $httpHeader;     // HTTPヘッダ(空文字の時は何も送らない)
  20:     public $error;          // エラーフラグ
  21:     public $errmsg;         // エラーメッセージ
  22:     public $debug;          // デバッグ用ファイル名
  23: 
  24: /**
  25:  * コンストラクタ
  26:  * 参考サイト https://www.pahoo.org/e-soul/webtech/php06/php06-72-01.shtm
  27:  * @param   int    $life キャッシュ保持時間(分)(省略可能)
  28:  * @param   string $dir キャッシュ・ディレクトリ(省略可能)
  29:  * @param   array  $httpHeader httpヘッダに渡す配列(省略可能)
  30:  *          USER AGENT偽装に用いることを想定
  31:  *          (例)
  32:  *           array(
  33:  *              'User-Agent: Mozilla/5.0(Windows NT 10.0; Win64; x64) pahooAppy/pahoo.org AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
  34:  *              'Accept-Language: ja-JP'
  35:  *          );
  36:  * @return  なし
  37: */
  38: function __construct($life=self::LIFE_CACHE, $dir=self::DEF_DIRCACHE, $httpHeader=NULL) {
  39:     if ($life < 0) {
  40:         $life = 0;
  41:     }
  42:     if (preg_match('/\/$/ui', $dir) == 0) {
  43:         $dir = $dir . '/';
  44:     }
  45:     $this->error      = FALSE;
  46:     $this->errmsg     = '';
  47:     $this->debug      = '';
  48:     $this->lifeCache  = $life;
  49:     $this->dirCache   = $dir;
  50:     $this->httpHeader = $httpHeader;
  51: 
  52:     // PHP5以上であることを調べる.
  53:     if (! $this->isphp5over()) {
  54:         $this->error   = TRUE;
  55:         $this->errmsg  = '動作にはPHP5以上が必要です';
  56:         return;
  57:     }
  58: 
  59:     // キャッシュ・ディレクトリが無ければ作成する.
  60:     if (! is_dir($this->dirCache)) {
  61:         $res = mkdir($this->dirCache, 0744);
  62:         if ($res == FALSE) {
  63:             $this->error   = TRUE;
  64:             $this->errmsg  = 'キャッシュ・ディレクトリ "' . $this->$dirCache . '" の作成に失敗しました';
  65:             return;
  66:         }
  67:     }
  68: }

クラウド連携や相手先サイトの公開データを利用する際、こちらのアプリを起動する都度、APIを呼び出したりデータをダウンロードするのでは、相手サーバに負荷をかけてしまう。
そこで、頻繁に変更がないデータについては、一度取り込んだら、こちら側のサーバのローカルストレージにキャッシュしておく仕組みを用意した。それが pahooCacheクラス である。同梱のクラス・ファイル "pahooCache.php" は include_path が通ったディレクトリに配置してほしい。他のプログラムでも pahooCacheクラス を利用するが、常に最新のクラス・ファイルを1つ配置すればよい。

pahooCacheクラス の注意ポイントは、キャッシュ時間(単位:分)とキャッシュを保存するディレクトリをコンストラクタで指定している点だ。これらはプログラムによって変わるものである。インスタンス化するときの値は、pahooCacheクラス を利用するメイン・プログラムの方で解説する。

サイトによっては、User-Agent などを必要とすることがあるだろう。そこで、第3引数に HTTPヘッダ として送信するデータを配列で渡すことができるようにした。配列の構造はコメントを参照していただきたい。

PHPのクラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

準備:各種定数など

birthRate.php

  56: // 各種定数(START) ===========================================================
  57: 
  58: // jqPlotのあるフォルダ
  59: define('JQPLOT', '../../../../common/jqplot/');
  60: 
  61: // グラフの幅、高さ
  62: define('GRAPH_WIDTH',  600);
  63: define('GRAPH_HEIGHT', 350);
  64: 
  65: // 婚姻率、離婚率、合計特殊出生率 推移グラフの名前
  66: define('GRAPH_PROGRESS', 'jqPlot_progress');
  67: 
  68: // 合計特殊出生率=婚姻率 相関グラフの名前
  69: define('GRAPH_MARRIAGE', 'jqPlot_marriage');
  70: 
  71: // 合計特殊出生率=離婚率 相関グラフの名前
  72: define('GRAPH_DIVORCE', 'jqPlot_divorce');
  73: 
  74: // 合計特殊出生率=初婚年齢(相関グラフの名前
  75: define('GRAPH_1STMARRIAGE_WIFE', 'jqPlot_1stmarriageWife');
  76: 
  77: // 合計特殊出生率=初婚年齢(相関グラフの名前
  78: define('GRAPH_1STMARRIAGE_HUSBAND', 'jqPlot_1stmarriageHusband');
  79: 
  80: // キャッシュ保持時間(分) 0:キャッシュしない
  81: // 政府統計 e-Stat へのアクセス負荷軽減
  82: define('LIFE_CACHE_DATA', (60 * 24 * 10));
  83: 
  84: // キャッシュ・ディレクトリ
  85: // 書き込み可能で,外部からアクセスされないディレクトリを指定してください.
  86: define('DIR_CACHE_DATA',   './pcache_estat/');
  87: 
  88: // APPID
  89: if (isset($_ENV['PAHOO_ESTAR_APIKEY'])) {
  90:     define('ESTAT_APPID', $_ENV['PAHOO_ESTAR_APIKEY']);
  91: else {
  92:     define('ESTAT_APPID', '');
  93: }
  94: 
  95: // 各種定数(END) ===============================================================

各種パラメータは定数を defineしている。とくに記載のないものは、適宜変更してかまわない。

今回は、e-Stat 政府の統計窓口の API を使ってデータを引き出すため、APPID が必要となる。無料で取得できる。取得方法は、「e-Stat 政府統計の総合窓口 - 各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。

birthRate.php

  97: // e-Stat:平均初婚年齢表のカテゴリ【変更不可】
  98: define('CAT_HUSBAND',   '00100');   // 
  99: define('CAT_WIFE',      '00110');   // 
 100: 
 101: // データ項目名と e-Stat 統計表ID の対応表【変更不可】
 102: $TableID = array(
 103: 'totalFertilityRate'    => array('0003411598', '', '合計特殊出生率'),
 104: 'marriageRate'          => array('0003411835', '', '婚姻率(人口千対)'), 
 105: 'divorceRate'           => array('0003411861', '', '離婚率(人口千対)'),
 106: 'firstMattiageWife'     => array('0003411845', CAT_WIFE, '平均初婚年齢(妻)'),
 107: 'firstMattiageHusband'  => array('0003411845', CAT_HUSBAND, '平均初婚年齢(夫)'),
 108: );

あらかじめ、データ項目名と e-Stat 統計表ID の対応表を配列 $TableID に、平気初婚年齢表で使う夫と妻のカテゴリIDを定数 CAT_HUSBAND, CAT_WIFE に用意しておく。これらは【変更不可】である。

解説:e-Stat API を使ってデータを取得する

birthRate.php

 181: /**
 182:  * 政府統計 e-Stat API を使ってデータを取得する
 183:  * @param   string $appid  APPID
 184:  * @param   string $dataID データのID
 185:  * @return  array 取得データ(XML形式)/FALSE:取得失敗
 186: */
 187: function getEstatData($appid, $dataID) {
 188:     $url = "https://api.e-stat.go.jp/rest/3.0/app/getStatsData?appId={$appid}&statsDataId={$dataID}";
 189: 
 190:     // インスタンス生成
 191:     $pcc = new pahooCache(LIFE_CACHE_DATA, DIR_CACHE_DATA);
 192:     // データ取得
 193:     $xml = $pcc->load($url);
 194:     // インスタンス解放
 195:     $pcc = NULL;
 196:     // エラーチェック
 197:     if ($xml === FALSEreturn FALSE;
 198: 
 199:     // XMLデコード
 200:     return $xml;
 201: }

e-Stat 政府の統計窓口 API を使ってデータを得るのがユーザー関数 getEstatData である。API に負荷をかけないよう、pahooCacheクラスを使ってデータ取得する。
得られた XML形式データを文字列として返す。

birthRate.php

 203: /**
 204:  * 政府統計 e-Stat の XML形式データを連想配列に格納する
 205:  * @param   string $xmlString XML形式データ
 206:  * @param   string $name      格納する要素名
 207:  * @param   array  $items     格納する連想配列
 208:  * @return  int 格納したデータ件数
 209: */
 210: function xml2array($xmlString, $name, &$items) {
 211:     global $TableID;
 212: 
 213:     $cnt = 0;
 214:     $xml = @simplexml_load_string($xmlString);
 215: 
 216:     // 構文エラーチェック
 217:     if (($xml === FALSE|| ! isset($xml->STATISTICAL_DATA->DATA_INF->VALUE)) {
 218:         return $cnt;
 219:     }
 220: 
 221:     // データを連想配列に格納する
 222:     foreach ($xml->STATISTICAL_DATA->DATA_INF->VALUE as $value) {
 223:         $attr = $value->attributes();
 224:         if ($attr === NULL)     continue;
 225:         // 都道府県
 226:         if (! isset($attr['area']))     continue;
 227:         $area = (int)substr((string)$attr['area'], 0, 2);
 228:         // 西暦年
 229:         if (! isset($attr['time'])) continue;
 230:         $time = (int)substr((string)$attr['time'], 0, 4);
 231:         // カテゴリID
 232:         $cat = $TableID[$name][1];
 233:         // 
 234:         if ($cat === '') {
 235:             $items[$area][$time][$name] = (float)$value;
 236:             $cnt++;
 237:         } else if ($cat === CAT_HUSBAND) {
 238:             if ((string)$attr['cat01'] === CAT_HUSBAND) {
 239:                 $items[$area][$time][$name] = (float)$value;
 240:                 $cnt++;
 241:             }
 242:         } else if ($cat === CAT_WIFE) {
 243:             if ((string)$attr['cat01'] === CAT_WIFE) {
 244:                 $items[$area][$time][$name] = (float)$value;
 245:                 $cnt++;
 246:             }
 247:         }
 248:     }
 249: }

この XML形式データを、配列 $TableID を参照しながら連想配列に格納するのがユーザー定義関数 xml2array である。

解説:配列を散布図用に展開する

birthRate.php

 251: /**
 252:  * 政府統計 e-Stat の連想配列を散布図用に配列に展開する
 253:  * @param   array  $items  e-Statデータの連想配列
 254:  * @param   string $xName  X軸方向の要素名
 255:  * @param   string $yName  Y軸方向の要素名
 256:  * @param   array  $xList  X軸方向の配列
 257:  * @param   array  $yList  Y軸方向の配列
 258:  * @param   string $xCat   X軸方向のカテゴリ
 259:  *                          ('':無し, CAT_HUSBAND:夫, CAT_WIFE:妻)
 260:  * @return  int 展開したデータ件数
 261: */
 262: function array2xyList($items, $xName, $yName, &$xList, &$yList,) {
 263:     $cnt = 0;
 264:     foreach ($items as $areaList) {
 265:         foreach ($areaList as $timeList) {
 266:             if (isset($timeList[$xName]) && isset($timeList[$yName])) {
 267:                 if (((float)$timeList[$xName> 0&& ((float)$timeList[$yName> 0)) {
 268:                     $xList[$cnt] = (float)$timeList[$xName];
 269:                     $yList[$cnt] = (float)$timeList[$yName];
 270:                     $cnt++;
 271:                 }
 272:             }
 273:         }
 274:     }
 275:     return $cnt;
 276: }

前述の xml2array で得られた連想配列を、散布図用にXY配列に展開するユーザー定義関数が array2xyList である。

なお、散布図をプロットするユーザー定義関数 plotScatter は、「PHPで相関係数と回帰直線を表示」のものと同じなので解説をを割愛する。

解説:メイン・プログラム

birthRate.php

 424: // メイン・プログラム ======================================================
 425: $items  = array();
 426: $graphs = array();
 427: 
 428: // e-Statからデータを読み込む
 429: foreach ($TableID as $name=>$idList) {
 430:     $xmlString = getEstatData(ESTAT_APPID, $idList[0]);
 431:     xml2array($xmlString, $name, $items);
 432: }
 433: 
 434: // 散布図作成
 435: $xList  = array();
 436: $yList  = array();
 437: array2xyList($items, 'marriageRate', 'totalFertilityRate', $xList, $yList);
 438: $graphs[] = plotScatter($xList, $yList, $TableID['marriageRate'][2],
 439:                 $TableID['totalFertilityRate'][2, GRAPH_MARRIAGE);
 440: 
 441: $xList  = array();
 442: $yList  = array();
 443: array2xyList($items, 'divorceRate', 'totalFertilityRate', $xList, $yList);
 444: $graphs[] = plotScatter($xList, $yList, $TableID['divorceRate'][2],
 445:                 $TableID['totalFertilityRate'][2, GRAPH_DIVORCE);
 446: 
 447: $xList  = array();
 448: $yList  = array();
 449: array2xyList($items, 'firstMattiageWife', 'totalFertilityRate', $xList, $yList);
 450: $graphs[] = plotScatter($xList, $yList, $TableID['firstMattiageWife'][2],
 451:                 $TableID['totalFertilityRate'][2, GRAPH_1STMARRIAGE_WIFE);
 452: 
 453: $xList  = array();
 454: $yList  = array();
 455: array2xyList($items, 'firstMattiageHusband', 'totalFertilityRate', $xList, $yList);
 456: $graphs[] = plotScatter($xList, $yList, $TableID['firstMattiageHusband'][2],
 457:                 $TableID['totalFertilityRate'][2, GRAPH_1STMARRIAGE_HUSBAND);
 458: 
 459: // 表示HTML作成
 460: $HtmlBody = makeCommonBody($graphs, $errmsg);
 461: 
 462: // 表示処理
 463: echo $HtmlHeader;
 464: echo $HtmlBody;
 465: echo $HtmlFooter;
 466: 
 467: /*

メイン・プログラムでは、配列 $TableID を参照しながら、getEstatData 関数を使って複数の e-Stat API にアクセスし、データを一気に連想配列 $items に格納する。

次に、散布図のプロットで必要になるXYの組み合わせを、連想配列 $items から array2xyList を使って展開し、plotScatter 関数を使ってグラフを生成する。生成したグラフは、いったん、配列 $graphs に格納し、最後の表示処理で順番に画面に出力する。

参考サイト

(この項おわり)
header