<Xデータ> TAB <Yデータ> 改行 形式のデータセットから直線回帰(単回帰)を求めるスクリプトです。
Y = α * X + β 式の α、βを求めます。
"kaiki.vvs":
//----------------------------------------------------------------------
//
// File: "kaiki.vvs"
// Author: Nobuhide Tsuda
// Created: 11-Jun-2004
// Description: 直線回帰を計算するスクリプト
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// 使用方法:
// <Xデータ> TAB <Yデータ> 改行
// 上記形式のデータ行を選択し、スクリプト実行
//
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//
// 計算式:
// α = Σ(X[i] - ave(X)) * (Y[i] - ave(Y)) / Σ(X(i) - ave(X))^2
// β = ave(Y) - α * ave(X)
//
//----------------------------------------------------------------------
function main()
{
var line1 = 1;
var line2 = thisView.getLineCount();
if( thisView.isSelected() ) {
var range = thisView.getSelectedRange();
//writeln(range);
line1 = range.line1;
line2 = range.line2;
if( range.offset2 == 0 )
line2 -= 1;
}
var nData = 0;
var xVect, yVect;
var xSum = 0.0;
var ySum = 0.0;
for(var line = line1; line <= line2; ++line) {
var text = thisView.getLineString(line);
if( text =~ /(\S+)\s+(\S+)/ ) {
var x = double($1);
var y = double($2);
writeln("x = " + x + ", y = ", y);
xVect[nData] = x;
yVect[nData] = y;
xSum += x;
ySum += y;
nData += 1;
}
}
if( nData == 0 ) {
writeln("No valid data.");
return;
}
var aveX = xSum / nData;
var aveY = ySum / nData;
writeln(format("ave(X) = %f, ave(Y) = %f", aveX, aveY));
var num = 0.0; // 分子
var den = 0.0; // 分母
for(var i = 0; i < nData; ++i) {
num += (xVect[i] - aveX) * (yVect[i] - aveY);
den += (xVect[i] - aveX) * (xVect[i] - aveX);
}
var alpha = num / den;
var beta = aveY - alpha * aveX;
writeln(format("alpha = %f, beta = %f", alpha, beta));
}
データ:
0 56 25 69 115 119 140 136
実行結果:
x = 0, y = 56 x = 25, y = 69 x = 115, y = 119 x = 140, y = 136 ave(X) = 70.000000, ave(Y) = 95.000000 alpha = 0.566787, beta = 55.324910