FC2ブログ

# 決定係数 Coefficient of Determination
# 引数 期間 値 ($Period, $Price, $Index)
# 戻り値 hash {'r2'} {'adjr2'} (%r2)
sub R2{
my ($Period, $Price, $Index) = @_;
my %r2 = ();
my $N_p_1 = $Period - 1 - 1;
my $N_1 = $Period - 1;
my $count = @$Price - $Period;

# 期間と配列数の確認
if(($Period <= 0) || ($count < 0) || (@$Price != @$Index)){
return 0;
}

# 計算
for(my $i = $count; $i >= 0; $i--){
# 平均
my $avg_x = 0;
my $avg_y = 0;
for(my $j = 0; $j < $Period; $j++){
$avg_x += $$Price[$i + $j];
$avg_y += $$Index[$i + $j];
}
$avg_x = $avg_x / $Period;
$avg_y = $avg_y / $Period;

# 分散と共分散
my $num = 0;
my $den_x = 0;
my $den_y = 0;
for(my $j = 0; $j < $Period; $j++){
my $tmp_x = ($$Price[$i + $j] - $avg_x);
my $tmp_y = ($$Index[$i + $j] - $avg_y);

$num += $tmp_x * $tmp_y;
$den_x += $tmp_x * $tmp_x;
$den_y += $tmp_y * $tmp_y;
}
# 相関係数
my $cc = $num / sqrt($den_x * $den_y);

# 決定係数 Coefficient of Determination
$r2{'r2'}->[$i] = $cc * $cc;

# 自由度調整済みの決定係数 Adjusted R2
$r2{'adjr2'}->[$i] = 1 - ((1 - $r2{'r2'}->[$i]) * ($N_1 / $N_p_1));
}

return %r2;
}



# 決定係数 Coefficient of Determination
# 引数 期間 値 ($Period, $Price)
# 戻り値 決定係数 (@r2)
sub R2{
my ($Period, $Price) = @_;
my @r2 = ();
my $count = @$Price - $Period;

# 期間と配列数の確認
if(($Period <= 0) || ($count < 0)){
return 0;
}

# 計算
for(my $i = $count; $i >= 0; $i--){
# 平均
my $avg = 0;
for(my $j = 0; $j < $Period; $j++){
$avg += $$Price[$i + $j];
}
$avg = $avg / $Period;

# 合計
my $P_Lin = 0;
my $P_Avg = 0;
my @linear = &iLinearReg($Period, $Price, $i);
for(my $j = 0; $j < $Period; $j++){
my $tmp1 = $$Price[$i + $j] - $linear[$j];
my $tmp2 = $$Price[$i + $j] - $avg;

$P_Lin += $tmp1 * $tmp1;
$P_Avg += $tmp2 * $tmp2;
}

# 決定係数 Coefficient of Determination
$r2[$i] = 1 - ($P_Lin / $P_Avg);
}

return @r2;
}



# 自由度調整済みの決定係数 Adjusted R2
# 引数 期間 値 ($Period, $Price)
# 戻り値 自由度調整済みの決定係数 (@adjr2)
sub ADJR2{
my ($Period, $Price) = @_;
my @adjr2 = ();
my $N_p_1 = $Period - 1 - 1;
my $N_1 = $Period - 1;
my $count = @$Price - $Period;

# 期間と配列数の確認
if(($Period <= 0) || ($count < 0)){
return 0;
}

# 計算
for(my $i = $count; $i >= 0; $i--){
# 平均
my $avg = 0;
for(my $j = 0; $j < $Period; $j++){
$avg += $$Price[$i + $j];
}
$avg = $avg / $Period;

# 合計
my $P_Lin = 0;
my $P_Avg = 0;
my @linear = &iLinearReg($Period, $Price, $i);
for(my $j = 0; $j < $Period; $j++){
my $tmp1 = $$Price[$i + $j] - $linear[$j];
my $tmp2 = $$Price[$i + $j] - $avg;

$P_Lin += $tmp1 * $tmp1;
$P_Avg += $tmp2 * $tmp2;
}

# 自由度調整済みの決定係数 Adjusted R2
$adjr2[$i] = 1 - (($P_Lin / $N_p_1) / ($P_Avg / $N_1));
}
return @adjr2;
}



# i線形回帰トレンド
# 引数 期間 値 配列の位置 ($Period, $Price, $i)
# 戻り値 i線形回帰トレンド (@linear_reg)
sub iLinearReg{
my ($Period, $Price, $i) = @_;
my @linear_reg = ();
my $count = @$Price - ($Period + $i);

# 期間と配列数の確認
if(($Period <= 0) || ($count < 0)){
return 0;
}

# 計算
my $avg_y = 0;
my $avg_x = (($Period * ($Period + 1)) / 2) / $Period;
for(my $j = 0; $j < $Period; $j++){
$avg_y += $$Price[$i + $j];
}
$avg_y = $avg_y / $Period;

# ∑[(i-n日平均日数)×(i日目終値-n日終値平均値)] / ∑(i-n日平均日数)^2
my $num = 0;
my $den = 0;
for(my $j = 1; $j <= $Period; $j++){
$num += (($j - $avg_x) * ($$Price[$i + $j - 1] - $avg_y));
$den += (($j - $avg_x) * ($j - $avg_x));
}

# 線形回帰トレンド
my $b = $num / $den;
my $a = $avg_y - ($b * $avg_x);
for(my $j = 1; $j <= $Period; $j++){
$linear_reg[$j - 1] = $a + ($b * $j);
}

return @linear_reg;
}


参考URL
決定係数 - Wikipedia
決定係数とは,重相関係数,自由度調整済決定係数
オンライン コンパイラ/インタプリタ
テクニカル分析
プロフィール

Author:雨宮
Firefoxを使用しているので気づかなかったけど、IE6でソースコードを上手くコピーできない

5/3
携帯用ならIE6でもソースコードをコピーできる
携帯用

検索フォーム


あわせて読みたいブログパーツ
一寸先は闇 RSS