Shadow Academy トップ > 我流・物理数学 > 多変量解析 > 重回帰分析


重回帰分析

ファイル等から、コピーする場合は、
以下のテキストエリアに貼り付ける。
( xi , yi , zi , wi )の 各データセットは改行毎に、
xiyiziwi の データ間は半角コンマ、タブ、または、
半角スペースで、区切られることに注意。

サンプルデータ


半角コンマ タブ 半角スペース

データ数:n
a
b
c
d
xyの相関係数:rxy
xzの相関係数:rxz
yzの相関係数:ryz
xwの相関係数:rxw
ywの相関係数:ryw
zwの相関係数:rzw



waxbyczdの場合

前回の重回帰分析は、目的変量に対し説明変量として
2個の変量を考えてきたが、説明変量は2個だけとは限らない。
そこで、説明変量が3個のときの重回帰分析について述べる。
この時、重回帰式は、

であり、定数項d は、

で与えられる。

i 番目の残差(d は既に使われているので、ei で表す)は、

となり、残差の二乗:ei2は、

となる。残差平方和S は、

と計算される。ここで、x の分散、y の分散、z の分散に加えて、
w の分散をそれぞれ、データを母集団とみなす場合、

データを標本とみなす場合、

と表すことにする。また、xyの共分散、xzの共分散、
yzの共分散に加えて、xwの共分散、
ywの共分散、zwの共分散をそれぞれ、
データを母集団とみなす場合、

データを標本とみなす場合、

と表すことにする。これらの分散・共分散を使って、残差平方和S は、

と書き直すことが出来る。

次に、この残差平方和Sabcに対し、それぞれ偏微分する。
偏微分とは、微分する数(ここではabbc) 以外を定数と見なして微分することである。
Sa,b,cに対して最小値をとるのだから、 それらの偏導関数は当然ゼロでなくてはならない。

これを行列を用いて書き直すと、

の様に表せる。ここで、クラメル(Cramer)の公式より、

また、各相関係数に関しては、 「最小二乗法による線形回帰」の記事で述べた通り、

で与えられるが、前回の重回帰分析の記事で述べた様に、
説明変量が多くなると、マルチコがそれだけ起きやすくなるので、
説明変量間の相関が強くないかどうかを確かめながら、説明変量を選ぶ必要がある。




ソースコード(旧版)

linest5.html

<form name="linest5">
<textarea name="sample" cols="40" rows="20">
</textarea><br>
<table border="5" frame="void" rules="none"
 style="margin-left:auto;margin-right:auto;text-align:center;">
<tr>
<td align="center" colspan="2">
<input type="radio" name="separator" value="csv">半角コンマ
<input type="radio" name="separator" value="tsv">タブ
<input type="radio" name="separator" value="ssv">半角スペース
<br>
<input type="button" value="データを母集団として計算する" onclick="calc1()">
<input type="button" value="データを標本として計算する" onclick="calc2()">
</td>
</tr>
<tr>
<td align="center" colspan="2"><hr></td>
</tr>
<tr>
<td align="right">データ数:<i>n</i>=</td>
<td align="left"><input type="text" id="n"></td>
</tr>
<tr>
<td align="right"><i>a</i>=</td>
<td align="left"><input type="text" id="a"></td>
</tr>
<tr>
<td align="right"><i>b</i>=</td>
<td align="left"><input type="text" id="b"></td>
</tr>
<tr>
<td align="right"><i>c</i>=</td>
<td align="left"><input type="text" id="c"></td>
</tr>
<tr>
<td align="right"><i>d</i>=</td>
<td align="left"><input type="text" id="d"></td>
</tr>
<tr>
<td align="right"><i>x</i>と<i>y</i>の相関係数:<i>r<sub>xy</sub></i>=</td>
<td align="left"><input type="text" id="rxy"></td>
</tr>
<tr>
<td align="right"><i>x</i>と<i>z</i>の相関係数:<i>r<sub>xz</sub></i>=</td>
<td align="left"><input type="text" id="rxz"></td>
</tr>
<tr>
<td align="right"><i>y</i>と<i>z</i>の相関係数:<i>r<sub>yz</sub></i>=</td>
<td align="left"><input type="text" id="ryz"></td>
</tr>
<tr>
<td align="right"><i>x</i>と<i>w</i>の相関係数:<i>r<sub>xw</sub></i>=</td>
<td align="left"><input type="text" id="rxw"></td>
</tr>
<tr>
<td align="right"><i>y</i>と<i>w</i>の相関係数:<i>r<sub>yw</sub></i>=</td>
<td align="left"><input type="text" id="ryw"></td>
</tr>
<tr>
<td align="right"><i>z</i>と<i>w</i>の相関係数:<i>r<sub>zw</sub></i>=</td>
<td align="left"><input type="text" id="rzw"></td>
</tr>
</table>
</form>

linest5.js

function calc1(){
    var xsum=0; /* 測定値xの総和を格納する変数xsumを宣言 */
    var ysum=0; /* 測定値yの総和を格納する変数ysumを宣言 */
    var zsum=0; /* 測定値zの総和を格納する変数zsumを宣言 */
    var wsum=0; /* 測定値wの総和を格納する変数wsumを宣言 */
    var xave=0; /* 測定値xの平均を格納する変数xaveを宣言 */
    var yave=0; /* 測定値yの平均を格納する変数yaveを宣言 */
    var zave=0; /* 測定値zの平均を格納する変数zaveを宣言 */
    var wave=0; /* 測定値wの平均を格納する変数waveを宣言 */

    var dataset = document.linest5.sample.value.split("\n");
    var n = dataset.length /* データ数を算出する */
    var eachdata;

    var x=new Array(n); /* n個の測定値を格納する配列xを宣言 */
    var y=new Array(n); /* n個の測定値を格納する配列yを宣言 */
    var z=new Array(n); /* n個の測定値を格納する配列zを宣言 */
    var w=new Array(n); /* n個の測定値を格納する配列wを宣言 */
    var xd=new Array(n); /* n個のxの残差の二乗を格納する配列xdを宣言 */
    var yd=new Array(n); /* n個のyの残差の二乗を格納する配列ydを宣言 */
    var zd=new Array(n); /* n個のzの残差の二乗を格納する配列zdを宣言 */
    var wd=new Array(n); /* n個のwの残差の二乗を格納する配列wdを宣言 */
    var xyd=new Array(n); /* n個のxの残差とyの残差との積を格納する配列xydを宣言 */
    var xzd=new Array(n); /* n個のxの残差とzの残差との積を格納する配列xzdを宣言 */
    var yzd=new Array(n); /* n個のyの残差とzの残差との積を格納する配列yzdを宣言 */
    var xwd=new Array(n); /* n個のxの残差とwの残差との積を格納する配列xwdを宣言 */
    var ywd=new Array(n); /* n個のyの残差とwの残差との積を格納する配列ywdを宣言 */
    var zwd=new Array(n); /* n個のzの残差とwの残差との積を格納する配列zwdを宣言 */

    var xdsum=0; /* xの残差の二乗の総和を格納する変数xdsumを宣言 */
    var ydsum=0; /* yの残差の二乗の総和を格納する変数ydsumを宣言 */
    var zdsum=0; /* zの残差の二乗の総和を格納する変数zdsumを宣言 */
    var wdsum=0; /* wの残差の二乗の総和を格納する変数wdsumを宣言 */
    var xydsum=0; /* xの残差とyの残差との積の総和を格納する変数xydsumを宣言 */
    var xzdsum=0; /* xの残差とzの残差との積の総和を格納する変数xzdsumを宣言 */
    var yzdsum=0; /* yの残差とzの残差との積の総和を格納する変数yzdsumを宣言 */
    var xwdsum=0; /* xの残差とwの残差との積の総和を格納する変数xwdsumを宣言 */
    var ywdsum=0; /* yの残差とwの残差との積の総和を格納する変数ywdsumを宣言 */
    var zwdsum=0; /* zの残差とwの残差との積の総和を格納する変数zwdsumを宣言 */

    var sx2=0; // xの分散
    var sy2=0; // yの分散
    var sz2=0; // zの分散
    var sw2=0; // wの分散
    var sxy=0; // xとyの共分散
    var sxz=0; // xとzの共分散
    var syz=0; // yとzの共分散
    var sxw=0; // xとwの共分散
    var syw=0; // yとwの共分散
    var szw=0; // zとwの共分散
    var rxy=0; // xとyの相関係数
    var rxz=0; // xとzの相関係数
    var ryz=0; // yとzの相関係数
    var rxw=0; // xとwの相関係数
    var ryw=0; // yとwの相関係数
    var rzw=0; // zとwの相関係数

    for(i=0;i<n;++i){
        if(document.linest5.separator[0].checked == true){
            var eachdata = dataset[i].split(",");
        }
        if(document.linest5.separator[1].checked == true){
            var eachdata = dataset[i].split("\t");
        }
        if(document.linest5.separator[2].checked == true){
            var eachdata = dataset[i].split(" ");
        }
        x[i]=parseFloat(eachdata[0]);
        y[i]=parseFloat(eachdata[1]);
        z[i]=parseFloat(eachdata[2]);
        w[i]=parseFloat(eachdata[3]);

        xsum=xsum+x[i];
        ysum=ysum+y[i];
        zsum=zsum+z[i];
        wsum=wsum+w[i];
    }

    xave=xsum/n;
    yave=ysum/n;
    zave=zsum/n;
    wave=wsum/n;

    for(i=0;i<n;++i){
        xd[i]=Math.pow((x[i]-xave),2);
        /* i番目のxの残差の二乗をxd[i]に代入 */
        yd[i]=Math.pow((y[i]-yave),2);
        /* i番目のyの残差の二乗をyd[i]に代入 */
        zd[i]=Math.pow((z[i]-zave),2);
        /* i番目のzの残差の二乗をzd[i]に代入 */
        wd[i]=Math.pow((w[i]-wave),2);
        /* i番目のwの残差の二乗をwd[i]に代入 */
        xyd[i]=(x[i]-xave)*(y[i]-yave);
        /* i番目のxの残差とyの残差との積をxyd[i]に代入 */
        xzd[i]=(x[i]-xave)*(z[i]-zave);
        /* i番目のxの残差とzの残差との積をxzd[i]に代入 */
        yzd[i]=(y[i]-yave)*(z[i]-zave);
        /* i番目のyの残差とzの残差との積をyzd[i]に代入 */
        xwd[i]=(x[i]-xave)*(w[i]-wave);
        /* i番目のxの残差とwの残差との積をxwd[i]に代入 */
        ywd[i]=(y[i]-yave)*(w[i]-wave);
        /* i番目のyの残差とwの残差との積をywd[i]に代入 */
        zwd[i]=(z[i]-zave)*(w[i]-wave);
        /* i番目のzの残差とwの残差との積をzwd[i]に代入 */

        xdsum=xdsum+xd[i];
        ydsum=ydsum+yd[i];
        zdsum=zdsum+zd[i];
        wdsum=wdsum+wd[i];
        xydsum=xydsum+xyd[i];
        xzdsum=xzdsum+xzd[i];
        yzdsum=yzdsum+yzd[i];
        xwdsum=xwdsum+xwd[i];
        ywdsum=ywdsum+ywd[i];
        zwdsum=zwdsum+zwd[i];
    }

    sx2=xdsum/n;
    sy2=ydsum/n;
    sz2=zdsum/n;
    sw2=wdsum/n;
    sxy=xydsum/n;
    sxz=xzdsum/n;
    syz=yzdsum/n;
    sxw=xwdsum/n;
    syw=ywdsum/n;
    szw=zwdsum/n;

    det0=sx2*(sy2*sz2-syz*syz)+sxy*(syz*sxz-sxy*sz2)+sxz*(sxy*syz-sy2*sxz);
    det1=sxw*(sy2*sz2-syz*syz)+sxy*(syz*szw-syw*sz2)+sxz*(syw*syz-sy2*szw);
    det2=sx2*(syw*sz2-syz*szw)+sxw*(syz*sxz-sxy*sz2)+sxz*(sxy*szw-syw*sxz);
    det3=sx2*(sy2*szw-syw*syz)+sxy*(syw*sxz-sxy*szw)+sxw*(sxy*syz-sy2*sxz);

    a=det1/det0;
    b=det2/det0;
    c=det3/det0;
    d=wave-(a*xave+b*yave+c*zave)
    rxy=sxy/(Math.sqrt(sx2*sy2));
    rxz=sxz/(Math.sqrt(sx2*sz2));
    ryz=syz/(Math.sqrt(sy2*sz2));
    rxw=sxw/(Math.sqrt(sx2*sw2));
    ryw=syw/(Math.sqrt(sy2*sw2));
    rzw=szw/(Math.sqrt(sz2*sw2));

    document.getElementById("n").value=parseFloat(""+n);
    document.getElementById("a").value=parseFloat(""+a);
    document.getElementById("b").value=parseFloat(""+b);
    document.getElementById("c").value=parseFloat(""+c);
    document.getElementById("d").value=parseFloat(""+d);
    document.getElementById("rxy").value=parseFloat(""+rxy);
    document.getElementById("rxz").value=parseFloat(""+rxz);
    document.getElementById("ryz").value=parseFloat(""+ryz);
    document.getElementById("rxw").value=parseFloat(""+rxw);
    document.getElementById("ryw").value=parseFloat(""+ryw);
    document.getElementById("rzw").value=parseFloat(""+rzw);
}

function calc2(){
    var xsum=0; /* 測定値xの総和を格納する変数xsumを宣言 */
    var ysum=0; /* 測定値yの総和を格納する変数ysumを宣言 */
    var zsum=0; /* 測定値zの総和を格納する変数zsumを宣言 */
    var wsum=0; /* 測定値wの総和を格納する変数wsumを宣言 */
    var xave=0; /* 測定値xの平均を格納する変数xaveを宣言 */
    var yave=0; /* 測定値yの平均を格納する変数yaveを宣言 */
    var zave=0; /* 測定値zの平均を格納する変数zaveを宣言 */
    var wave=0; /* 測定値wの平均を格納する変数waveを宣言 */

    var dataset = document.linest5.sample.value.split("\n");
    var n = dataset.length /* データ数を算出する */
    var eachdata;

    var x=new Array(n); /* n個の測定値を格納する配列xを宣言 */
    var y=new Array(n); /* n個の測定値を格納する配列yを宣言 */
    var z=new Array(n); /* n個の測定値を格納する配列zを宣言 */
    var w=new Array(n); /* n個の測定値を格納する配列wを宣言 */
    var xd=new Array(n); /* n個のxの残差の二乗を格納する配列xdを宣言 */
    var yd=new Array(n); /* n個のyの残差の二乗を格納する配列ydを宣言 */
    var zd=new Array(n); /* n個のzの残差の二乗を格納する配列zdを宣言 */
    var wd=new Array(n); /* n個のwの残差の二乗を格納する配列wdを宣言 */
    var xyd=new Array(n); /* n個のxの残差とyの残差との積を格納する配列xydを宣言 */
    var xzd=new Array(n); /* n個のxの残差とzの残差との積を格納する配列xzdを宣言 */
    var yzd=new Array(n); /* n個のyの残差とzの残差との積を格納する配列yzdを宣言 */
    var xwd=new Array(n); /* n個のxの残差とwの残差との積を格納する配列xwdを宣言 */
    var ywd=new Array(n); /* n個のyの残差とwの残差との積を格納する配列ywdを宣言 */
    var zwd=new Array(n); /* n個のzの残差とwの残差との積を格納する配列zwdを宣言 */

    var xdsum=0; /* xの残差の二乗の総和を格納する変数xdsumを宣言 */
    var ydsum=0; /* yの残差の二乗の総和を格納する変数ydsumを宣言 */
    var zdsum=0; /* zの残差の二乗の総和を格納する変数zdsumを宣言 */
    var wdsum=0; /* wの残差の二乗の総和を格納する変数wdsumを宣言 */
    var xydsum=0; /* xの残差とyの残差との積の総和を格納する変数xydsumを宣言 */
    var xzdsum=0; /* xの残差とzの残差との積の総和を格納する変数xzdsumを宣言 */
    var yzdsum=0; /* yの残差とzの残差との積の総和を格納する変数yzdsumを宣言 */
    var xwdsum=0; /* xの残差とwの残差との積の総和を格納する変数xwdsumを宣言 */
    var ywdsum=0; /* yの残差とwの残差との積の総和を格納する変数ywdsumを宣言 */
    var zwdsum=0; /* zの残差とwの残差との積の総和を格納する変数zwdsumを宣言 */

    var sx2=0; // xの分散
    var sy2=0; // yの分散
    var sz2=0; // zの分散
    var sw2=0; // wの分散
    var sxy=0; // xとyの共分散
    var sxz=0; // xとzの共分散
    var syz=0; // yとzの共分散
    var sxw=0; // xとwの共分散
    var syw=0; // yとwの共分散
    var szw=0; // zとwの共分散
    var rxy=0; // xとyの相関係数
    var rxz=0; // xとzの相関係数
    var ryz=0; // yとzの相関係数
    var rxw=0; // xとwの相関係数
    var ryw=0; // yとwの相関係数
    var rzw=0; // zとwの相関係数

    for(i=0;i<n;++i){
        if(document.linest5.separator[0].checked == true){
            var eachdata = dataset[i].split(",");
        }
        if(document.linest5.separator[1].checked == true){
            var eachdata = dataset[i].split("\t");
        }
        if(document.linest5.separator[2].checked == true){
            var eachdata = dataset[i].split(" ");
        }
        x[i]=parseFloat(eachdata[0]);
        y[i]=parseFloat(eachdata[1]);
        z[i]=parseFloat(eachdata[2]);
        w[i]=parseFloat(eachdata[3]);

        xsum=xsum+x[i];
        ysum=ysum+y[i];
        zsum=zsum+z[i];
        wsum=wsum+w[i];
    }

    xave=xsum/n;
    yave=ysum/n;
    zave=zsum/n;
    wave=wsum/n;

    for(i=0;i<n;++i){
        xd[i]=Math.pow((x[i]-xave),2);
        /* i番目のxの残差の二乗をxd[i]に代入 */
        yd[i]=Math.pow((y[i]-yave),2);
        /* i番目のyの残差の二乗をyd[i]に代入 */
        zd[i]=Math.pow((z[i]-zave),2);
        /* i番目のzの残差の二乗をzd[i]に代入 */
        wd[i]=Math.pow((w[i]-wave),2);
        /* i番目のwの残差の二乗をwd[i]に代入 */
        xyd[i]=(x[i]-xave)*(y[i]-yave);
        /* i番目のxの残差とyの残差との積をxyd[i]に代入 */
        xzd[i]=(x[i]-xave)*(z[i]-zave);
        /* i番目のxの残差とzの残差との積をxzd[i]に代入 */
        yzd[i]=(y[i]-yave)*(z[i]-zave);
        /* i番目のyの残差とzの残差との積をyzd[i]に代入 */
        xwd[i]=(x[i]-xave)*(w[i]-wave);
        /* i番目のxの残差とwの残差との積をxwd[i]に代入 */
        ywd[i]=(y[i]-yave)*(w[i]-wave);
        /* i番目のyの残差とwの残差との積をywd[i]に代入 */
        zwd[i]=(z[i]-zave)*(w[i]-wave);
        /* i番目のzの残差とwの残差との積をzwd[i]に代入 */

        xdsum=xdsum+xd[i];
        ydsum=ydsum+yd[i];
        zdsum=zdsum+zd[i];
        wdsum=wdsum+wd[i];
        xydsum=xydsum+xyd[i];
        xzdsum=xzdsum+xzd[i];
        yzdsum=yzdsum+yzd[i];
        xwdsum=xwdsum+xwd[i];
        ywdsum=ywdsum+ywd[i];
        zwdsum=zwdsum+zwd[i];
    }

    sx2=xdsum/(n-1);
    sy2=ydsum/(n-1);
    sz2=zdsum/(n-1);
    sw2=wdsum/(n-1);
    sxy=xydsum/(n-1);
    sxz=xzdsum/(n-1);
    syz=yzdsum/(n-1);
    sxw=xwdsum/(n-1);
    syw=ywdsum/(n-1);
    szw=zwdsum/(n-1);

    det0=sx2*(sy2*sz2-syz*syz)+sxy*(syz*sxz-sxy*sz2)+sxz*(sxy*syz-sy2*sxz);
    det1=sxw*(sy2*sz2-syz*syz)+sxy*(syz*szw-syw*sz2)+sxz*(syw*syz-sy2*szw);
    det2=sx2*(syw*sz2-syz*szw)+sxw*(syz*sxz-sxy*sz2)+sxz*(sxy*szw-syw*sxz);
    det3=sx2*(sy2*szw-syw*syz)+sxy*(syw*sxz-sxy*szw)+sxw*(sxy*syz-sy2*sxz);

    a=det1/det0;
    b=det2/det0;
    c=det3/det0;
    d=wave-(a*xave+b*yave+c*zave)
    rxy=sxy/(Math.sqrt(sx2*sy2));
    rxz=sxz/(Math.sqrt(sx2*sz2));
    ryz=syz/(Math.sqrt(sy2*sz2));
    rxw=sxw/(Math.sqrt(sx2*sw2));
    ryw=syw/(Math.sqrt(sy2*sw2));
    rzw=szw/(Math.sqrt(sz2*sw2));

    document.getElementById("n").value=parseFloat(""+n);
    document.getElementById("a").value=parseFloat(""+a);
    document.getElementById("b").value=parseFloat(""+b);
    document.getElementById("c").value=parseFloat(""+c);
    document.getElementById("d").value=parseFloat(""+d);
    document.getElementById("rxy").value=parseFloat(""+rxy);
    document.getElementById("rxz").value=parseFloat(""+rxz);
    document.getElementById("ryz").value=parseFloat(""+ryz);
    document.getElementById("rxw").value=parseFloat(""+rxw);
    document.getElementById("ryw").value=parseFloat(""+ryw);
    document.getElementById("rzw").value=parseFloat(""+rzw);
}



Shadow Academy トップへ戻る

inserted by FC2 system