Last active
June 26, 2019 04:42
-
-
Save komasaru/9ca1b80c699105a7d5f3 to your computer and use it in GitHub Desktop.
Ruby script to calculate a multiple regression function.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/local/bin/ruby | |
#********************************************* | |
# Ruby script to calculate a multiple regression function. | |
#********************************************* | |
# | |
class Array | |
def reg_multi(y) | |
# 元の数、変量内のサンプル数 | |
e_size, s_size = self.size, y.size | |
# 以下の場合は例外スロー | |
# - 引数の配列が Array クラスでない | |
# - 自身配列が空 | |
# - 配列サイズが異なれば例外 | |
raise "Argument is not a Array class!" unless y.class == Array | |
raise "Self array is nil!" if e_size == 0 | |
raise "Argument array size is invalid!" unless self[0].size == s_size | |
1.upto(e_size - 1) do |i| | |
raise "Argument array size is invalid!" unless self[0].size == self[i].size | |
end | |
x1, x2 = self | |
sum_x1 = x1.sum | |
sum_x2 = x2.sum | |
sum_y = y.sum | |
sum_x1x1 = x1.map { |a| a * a }.sum | |
sum_x1x2 = x1.zip(x2).map { |a, b| a * b }.sum | |
sum_x1y = x1.zip(y).map { |a, b| a * b }.sum | |
sum_x2x1 = sum_x1x2 | |
sum_x2x2 = x2.map { |a| a * a }.sum | |
sum_x2y = x2.zip(y).map { |a, b| a * b }.sum | |
mtx = [ | |
[s_size, sum_x1 , sum_x2 , sum_y ], | |
[sum_x1, sum_x1x1, sum_x1x2, sum_x1y], | |
[sum_x2, sum_x2x1, sum_x2x2, sum_x2y] | |
] | |
# 連立方程式を解く (ガウスの消去法) | |
return gauss_e(mtx) | |
end | |
private | |
# ガウスの消去法 | |
def gauss_e(ary) | |
# 行数 | |
n = ary.size | |
# 前進消去 | |
0.upto(n - 2) do |k| | |
(k + 1).upto(n - 1) do |i| | |
if ary[k][k] == 0 | |
puts "解けない!" | |
exit 1 | |
end | |
d = ary[i][k] / ary[k][k].to_f | |
(k + 1).upto(n) do |j| | |
ary[i][j] -= ary[k][j] * d | |
end | |
end | |
end | |
# 後退代入 | |
(n - 1).downto(0) do |i| | |
if ary[i][i] == 0 | |
puts "解けない!" | |
exit 1 | |
end | |
d = ary[i][n] | |
(i + 1).upto(n - 1) do |j| | |
d -= ary[i][j] * ary[j][n] | |
end | |
ary[i][n] = d / ary[i][i].to_f | |
end | |
return ary.map { |a| a[-1] } | |
end | |
end | |
# 説明(独立)変数と目的(従属)変数 | |
ary_x = [ | |
[17.5, 17.0, 18.5, 16.0, 19.0, 19.5, 16.0, 18.0, 19.0, 19.5], | |
[30, 25, 20, 30, 45, 35, 25, 35, 35, 40] | |
] | |
ary_y = [45, 38, 41, 34, 59, 47, 35, 43, 54, 52] | |
# 重回帰式算出(b0, b1, b2, ...) | |
reg_multi = ary_x.reg_multi(ary_y) | |
# 結果出力 | |
ary_x.each_with_index do |x, i| | |
puts "説明変数 X#{i + 1} = {#{ary_x[i].join(', ')}}" | |
end | |
puts "目的変数 Y = {#{ary_y.join(', ')}}" | |
puts "---" | |
p reg_multi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment