Shadow Academy トップ > 我流・物理数学 > 誤差論・統計解析 > 最小二乗法による二次回帰


最小二乗法による二次回帰

データ数:n

データ数を入力後、「決定」ボタンを押すと、ここにデータ入力欄が生成される。


a
b



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

データ数:n
a
b



yax2bxの場合

最小二乗法を適用出来るのは、勿論、線形回帰の場合に限らない。
今回は、物理量として2つの変数x, yが二次式:

で表される場合を仮定する。前回と同様に残差:

を考え、データ数をn個として、それらの二乗の総和を

と定義する。やはり、abに対して、
それぞれ偏微分し、それらの偏導関数がゼロとなるようにする。

これは、二元連立一次方程式:

として表せる。各総和記号を

と置くと、より簡潔に

と表せる。これを行列に直すと、

となるので、クラメル(Cramer)の公式より、

元に戻すと、




ソースコード(旧版)

linest2.html

<form>
データ数:<i>n</i>=<input type="text" id="n">
<input type="button" value="決定" onclick="make()">
</form>

<hr>

<form>
<div id="datafield">
<p id="datalist">
データ数を入力後、「決定」ボタンを押すと、ここにデータ入力欄が生成される。<br>
<input id="CalcStart" type="button" value="計算する" onclick="calc()">
</p>
</div>
</form>

<hr>

<form>
<table border="5" frame="void" rules="none"
 style="margin-left:auto;margin-right:auto;text-align:center;">
<tr>
<td align="left"><i>a</i>=<input type="text" id="a"></td>
</tr>
<tr>
<td align="left"><i>b</i>=<input type="text" id="b"></td>
</tr>
</table>
</form>

<script language="JavaScript">
<!--
CalcButton=document.getElementById("CalcStart");
document.getElementById("datalist").removeChild(CalcButton);
//-->
</script>

<br><hr><br>

ファイル等から、コピーする場合は、<br>
以下のテキストエリアに貼り付ける。<br>
( <i>x<sub>i</sub></i> , <i>y<sub>i</sub></i> )の各データセットは改行毎に、<br>
<i>x<sub>i</sub></i> と<i>y<sub>i</sub></i> のデータ間は半角スペースで、<br>
区切られることに注意。<br>
<form name="linest2">
<textarea name="sample" cols="40" rows="20">
</textarea><br>
<input type="button" value="計算する" onclick="calc2()">
<table border="5" frame="void" rules="none"
 style="margin-left:auto;margin-right:auto;text-align:center;">
<tr>
<td align="right">データ数:<i>n</i>=</td>
<td align="left"><input type="text" id="n_2"></td>
</tr>
<tr>
<td align="right"><i>a</i>=</td>
<td align="left"><input type="text" id="a_2"></td>
</tr>
<tr>
<td align="right"><i>b</i>=</td>
<td align="left"><input type="text" id="b_2"></td>
</tr>
</table>
</form>

linest2.js

var n=0; /* データ数を格納する変数nを宣言 */
var CalcButton;

function make(){
    var datafield=document.getElementById("datafield");
    datafield.removeChild(document.getElementById("datalist"));
    var datalist=document.createElement("form");
    datalist.setAttribute('id', "datalist");

    n=parseInt(document.getElementById("n").value);
    for(i=0;i<n;++i){
        var eachdatax=document.createElement("input");
        eachdatax.setAttribute('type', "text");
        eachdatax.setAttribute('id', "x"+i);
        var eachdatay=document.createElement("input");
        eachdatay.setAttribute('type', "text");
        eachdatay.setAttribute('id', "y"+i);
        datalist.appendChild(document.createTextNode("x"+(i+1)+"="));
        datalist.appendChild(eachdatax);
        datalist.appendChild(document.createTextNode("y"+(i+1)+"="));
        datalist.appendChild(eachdatay);
        datalist.appendChild(document.createElement("br"));
    }
    datalist.appendChild(document.createElement("br"));
    datalist.appendChild(CalcButton);
    datafield.appendChild(datalist);
}

function calc(){
    var S2=0; /* 測定値xの二乗の総和を格納する変数S2を宣言 */
    var S3=0; /* 測定値xの三乗の総和を格納する変数S3を宣言 */
    var S4=0; /* 測定値xの四乗の総和を格納する変数S4を宣言 */
    var xysum=0; /* xとyの積の総和を格納する変数xysumを宣言 */
    var x2ysum=0; /* xの二乗とyの積の総和を格納する変数xysumを宣言 */

    var x=new Array(n); /* n個の測定値を格納する配列xを宣言 */
    var y=new Array(n); /* n個の測定値を格納する配列yを宣言 */

    for(i=0;i<n;++i){
        x[i]=parseFloat(document.getElementById("x"+i).value);
        /* i番目のxに入力された数値をx[i]に代入 */
        y[i]=parseFloat(document.getElementById("y"+i).value);
        /* i番目のyに入力された数値をy[i]に代入 */
        
        S2=S2+Math.pow(x[i],2);
        S3=S3+Math.pow(x[i],3);
        S4=S4+Math.pow(x[i],4);
        xysum=xysum+x[i]*y[i];
        x2ysum=x2ysum+Math.pow(x[i],2)*y[i];
    }

    a=(x2ysum*S2-S3*xysum)/(S4*S2-Math.pow(S3,2));
    b=(S4*xysum-x2ysum*S3)/(S4*S2-Math.pow(S3,2));

    document.getElementById("a").value=parseFloat(""+a);
    document.getElementById("b").value=parseFloat(""+b);
}

function calc2(){
    var S2=0; /* 測定値xの二乗の総和を格納する変数S2を宣言 */
    var S3=0; /* 測定値xの三乗の総和を格納する変数S3を宣言 */
    var S4=0; /* 測定値xの四乗の総和を格納する変数S4を宣言 */
    var xysum=0; /* xとyの積の総和を格納する変数xysumを宣言 */
    var x2ysum=0; /* xの二乗とyの積の総和を格納する変数xysumを宣言 */

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

    var x=new Array(n); /* n個の測定値を格納する配列xを宣言 */
    var y=new Array(n); /* n個の測定値を格納する配列yを宣言 */

    for(i=0;i<n;++i){
        eachdata = dataset[i].split(" ");
        x[i]=parseFloat(eachdata[0]);
        y[i]=parseFloat(eachdata[1]);
        
        S2=S2+Math.pow(x[i],2);
        S3=S3+Math.pow(x[i],3);
        S4=S4+Math.pow(x[i],4);
        xysum=xysum+x[i]*y[i];
        x2ysum=x2ysum+Math.pow(x[i],2)*y[i];
    }

    a=(x2ysum*S2-S3*xysum)/(S4*S2-Math.pow(S3,2));
    b=(S4*xysum-x2ysum*S3)/(S4*S2-Math.pow(S3,2));

    document.getElementById("n_2").value=parseFloat(""+n);
    document.getElementById("a_2").value=parseFloat(""+a);
    document.getElementById("b_2").value=parseFloat(""+b);
}



Shadow Academy トップへ戻る

inserted by FC2 system