目次
サンプル・プログラムの実行例
ここで注意してほしいことがある――婚姻率や離婚率と出生率の間に相関関係があるからといっても、それは、婚姻は離婚が原因で出生率が低下しているという結果(因果関係)になっているわけではない。つまり、相関関係と因果関係は別物であるということだ。
2つのデータ集合X, Yがあり、Xが変化すればYも変化することを相関関係という。
これに対し、X(原因)→Y(結果)という一方通行の関係が因果関係である。相関関係は因果関係の必要条件になり得るが、十分条件ではないのである。
サンプル・プログラム
correlation.php | サンプル・プログラム本体 |
birthrate.csv | 統計表 |
pahooStat.php | 統計に関わるクラス pahooStat。 使い方は「PHPで相関係数と回帰直線を表示」などを参照。include_path が通ったディレクトリに配置すること。 |
解説:準備
35: //jqPlotのあるフォルダ
36: define('JQPLOT', '../../../../common/jqplot/');
37:
38: //統計表
39: define('FILE_CSV', 'birthrate.csv');
40:
41: //CSVデリミタ
42: define('CSV_DELIMITER', ',');
43:
44: //グラフの幅、高さ
45: define('GRAPH_WIDTH', 600);
46: define('GRAPH_HEIGHT', 350);
47:
48: //婚姻率、離婚率、合計特殊出生率 推移グラフの名前
49: define('GRAPH_PROGRESS', 'jqPlot_progress');
50:
51: //合計特殊出生率=婚姻率 相関グラフの名前
52: define('GRAPH_MARRIAGE', 'jqPlot_marriage');
53:
54: //合計特殊出生率=離婚率 相関グラフの名前
55: define('GRAPH_DIVORCE', 'jqPlot_divorce');
56:
57: //合計特殊出生率=初婚年齢 相関グラフの名前
58: define('GRAPH_1STMARRIAGE', 'jqPlot_1stmarriage');
59:
60: //統計に関わるクラス:include_pathが通ったディレクトリに配置
61: require_once('pahooStat.php');
jqPlot の入手方法、インストール方法については、「PHPでNHK政治意識月例調査をグラフ表示」を参照してほしい。
相関係数は PECL の統計ライブラリを導入すれば計算できるが、今回は、自前のクラスを用意することにした。
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」で解説している。
クラスファイル "pahooStat.php" は、組み込み関数 require_once を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。
pahooStat クラスの内容については後述する。
毎年の婚姻率、離婚率、合計特殊出生率は、厚生労働省「令和2年 人口動態統計の年間推計について」をExcelに入力し、統計表ファイル FILE_CSV(CSV形式ファイル)として保存してある。また、平均初婚年齢(妻)は、厚生労働省「令和2年 人口動態統計月報年計(概数)の概況」を利用した。
これらのデータを参照し、各種グラフを描いてゆく。
解説:データの検査
解説:相加平均
解説:分散
解説:標準偏差
解説:共分散
解説:相関係数
解説:相関の強さ
相関係数 r | 相関の強さ |
---|---|
-1.0 ≦ r < -0.7 | 強い負の相関 |
-0.7 ≦ r < -0.4 | 負の相関 |
-0.4 ≦ r < -0.2 | 弱い負の相関 |
-0.2 ≦ r < +0.2 | ほとんど相関がない |
+0.2 ≦ r < +0.4 | 弱い正の相関 |
+0.4 ≦ r < +0.7 | 正の相関 |
+0.7 ≦ r ≦ +1.0 | 強い正の相関 |
解説:回帰直線
Excelの SLOPE関数、INTERCEPT関数に相当する。
回帰直線を とするとき、a, b は次の式によって求める。
解説:散布図
298: /**
299: * jqPlot用のスクリプト:散布図
300: * @param array $x, $y データ配列
301: * @param string $label_x, $label_y 軸ラベル
302: * @param string $name オブジェクト名
303: * @return string スクリプト/FALSE
304: */
305: function plotScatter($x, $y, $label_x, $label_y, $name) {
306: //相関係数、回帰直線
307: $pst = new pahooStat();
308: $r = $pst->correl($x, $y); //相関係数
309: if ($pst->iserror()) return FALSE;
310: $st = $pst->correl_strength($r);
311: $r = sprintf('%4.3f (%s)', $r, $st);
312: list($a, $b) = $pst->slope($x, $y); //回帰係数、切片
313: if ($pst->iserror()) return FALSE;
314: $x0 = min($x);
315: $y0 = $a * $x0 + $b;
316: $x1 = max($x);
317: $y1 = $a * $x1 + $b;
318: $pst = NULL;
319:
320: //系列の生成
321: $series = '';
322: $n = min(count($x), count($y));
323: for ($i = 0; $i < $n; $i++) {
324: $series .= sprintf('[%f, %f], ', $x[$i], $y[$i]);
325: }
326:
327: $width = GRAPH_WIDTH;
328: $height = GRAPH_HEIGHT;
329: $js =<<< EOT
330: <script>
331: jQuery(function() {
332: jQuery.jqplot('{$name}',
333: [
334: [ {$series} ]
335: ],
336: {
337: //タイトル
338: title: {
339: text: '{$label_x}={$label_y}<br /><span style="font-size:small; color:blue;">相関係数 = {$r}</span>',
340: show: true,
341: fontSize: '20px',
342: textAlign: 'center',
343: textColor: 'black'
344: },
345: //散布図
346: seriesDefaults: {
347: showLine: false,
348: color: 'green',
349: markerOptions: { size: 4 }
350: },
351: //回帰直線
352: canvasOverlay: {
353: show: true,
354: objects: [
355: {
356: line: {
357: lineWidth: 3,
358: color: 'blue',
359: shadow: false,
360: lineCap: 'round',
361: start: [ {$x0}, {$y0} ],
362: stop: [ {$x1}, {$y1} ]
363: }
364: }]
365: },
366: //軸
367: axes: {
368: xaxis: {
369: label: '{$label_x}',
370: tickOptions: { formatString: '%.1f' }
371: },
372: yaxis: {
373: label: '{$label_y}',
374: tickOptions: { formatString: '%.1f' }
375: }
376: }
377: }
378: );
379: });
380: </script>
381: <div id="{$name}" style="width:{$width}px; height:{$height}px;"></div>
382:
383: EOT;
384:
385: return $js;
386: }
回帰直線は、X軸の最小値を始点とし、同じく最大値を終点とする直線で、jqPlotプラグインの「jqplot.dateAxisRenderer.js」(グラフに描き加える線)で行う。
解説:年次推移グラフ
197: /**
198: * jqPlot用のスクリプト:年次推移グラフ
199: * @param array $items データ配列
200: * @param array $labels ラベル配列
201: * @param string $name オブジェクト名
202: * @param string $title グラフ・タイトル
203: * @return string スクリプト
204: */
205: function plotProgress($items, $labels, $name, $title) {
206: //系列の生成
207: $series = array();
208: $n = count($labels);
209: for ($i = 1; $i < $n; $i++) {
210: $series[$i] = '';
211: foreach ($items[$i] as $key=>$val) {
212: $series[$i] .= sprintf('[%d, %f], ', $items[0][$key], $val);
213: }
214: }
215: $s1 = '';
216: $s2 = '';
217: foreach ($series as $key=>$val) {
218: $s1 .= "[ {$val} ], ";
219: if (max($items[$key]) > 20) {
220: $s2 .=<<< EOT
221: {
222: label: '{$labels[$key]}',
223: yaxis: 'y2axis'
224: },
225:
226: EOT;
227: } else {
228: $s2 .=<<< EOT
229: {
230: label: '{$labels[$key]}'
231: },
232:
233: EOT;
234: }
235: }
236:
237: $width = GRAPH_WIDTH;
238: $height = GRAPH_HEIGHT;
239: $js =<<< EOT
240: <script>
241: jQuery(function() {
242: jQuery.jqplot('{$name}',
243: [
244: {$s1}
245: ],
246: {
247: //タイトル
248: title: {
249: text: '{$title}',
250: show: true,
251: fontSize: '20px',
252: textAlign: 'center',
253: textColor: 'black'
254: },
255: //ラベル
256: series: [
257: {$s2}
258: ],
259: legend: {
260: show: true,
261: placement: 'inside',
262: location: 'ne',
263: renderer: $.jqplot.EnhancedLegendRenderer,
264: rendererOptions: { numberRows: 1 }
265: },
266: //グラフ
267: seriesDefaults: {
268: showLine: true,
269: rendererOptions: { smooth: false },
270: markerOptions: { size: 0 },
271: },
272: //軸
273: axes: {
274: xaxis: {
275: label: '{$labels[0]}',
276: tickOptions: { formatString: '%d' }
277: },
278: yaxis: {
279: label: '率',
280: tickOptions: { formatString: '%.1f' }
281: },
282: y2axis: {
283: label: '年齢',
284: tickOptions: { formatString: '%d' }
285: }
286: }
287: }
288: );
289: });
290: </script>
291: <div id="{$name}" style="width:{$width}px; height:{$height}px;"></div>
292:
293: EOT;
294:
295: return $js;
296: }
参考サイト
- PHPでNHK政治意識月例調査をグラフ表示:ぱふぅ家のホームページ
- jqPlot:アルファシス
- Sci-pursuit
- 「相関関係」と「因果関係」の違いを理解すれば根拠のない通説にだまされなくなる!:ダイヤモンド・オンライン
なぜ出生率は上昇しないのか――婚姻率の低下と離婚率の上昇が関係しているのではないかと考え、それを確かめるため、高校数学で習った相関係数を求めてみることにする。
あわせて、データ集合の散布図と回帰曲線を描いてみる。
(2022年4月17日)統計表を更新,PHP8対応,リファラ・チェック改良。