前提・実現したいこと
Rubyのプログラムについてです。
Pythonで数値解析を行う本を読んでいるのですが、
並行して勉強しているRubyでも同様のことができるか試してみたくなり、
daruを用いて、まずはデータの簡単なスケーリングを行ってみました。
発生している問題・エラーメッセージ
データフレーム各列の平均が0, 標準偏差が1となるよう、
スケーリングするプログラムを作成しました。
目的の行列は出力できたように思いますが、
DataFrame#meanで出力した平均のうち、0列目のものが0と表示されません。
一方、自分で直に計算した平均値はほぼ0となっています。
以下のプログラムに誤りありますでしょうか。
もしかすると、daruのバグによるものかとも(勝手に)疑っているのですが、
回避する方法などありますでしょうか。
よろしくお願い致します。
該当のソースコード
Ruby
1 2require 'daru' 3 4module Preprocessing 5 6 module_function 7 8 # 二次元配列からデータフレームを生成 9 def getDF(squareArray) 10 tr=squareArray.transpose 11 hashSource = {} 12 13 tr.each_with_index {|childArray, i| 14 hashSource["col#{i}"]=childArray } 15 Daru::DataFrame.new(hashSource) 16 end 17 18 # スケーリング(各列の平均が0、標準偏差1となるよう変換) 19 def scaling(dataFrame) 20 stdev=dataFrame.std 21 mean=dataFrame.mean 22 23 return convertDataFrame(dataFrame) {|col, lin, value| 24 (value-mean[col])/stdev[col] } 25 end 26 27 def convertDataFrame(dataFrame) 28 ans=dataFrame 29 linsize, colsize = dataFrame.shape 30 31 (0...colsize).each do |col| 32 (0...linsize).each do |lin| 33 value = dataFrame[col][lin] 34 ans[col][lin] = yield(col, lin, value) 35 end 36 end 37 38 ans 39 end 40 41 42end 43 44 45# Main Program------------------ 46 47# 元となる二次元配列 48test=[[5.1, -2.9, 3.3], 49 [-1.2, 7.8, -6.1], 50 [3.9, 0.4, 2.1], 51 [7.3, -9.9, -4.5]] 52 53df = Preprocessing::getDF(test) 54puts "Source Data is:" 55p df 56 57#スケーリング実施 58scaled = Preprocessing.scaling(df) 59puts "Scaled Data is:" 60p scaled 61p scaled.mean #!! 62p scaled.std 63 64#!! の部分の出力が 65#<Daru::Vector(3)> 66# mean 67# col0 8.326672684688674e-1 68# col1 0.0 69# col2 0.0 70# となり、column[0]の平均が0でないように見える。 71 72# 確認で直に平均計算 73cal_mean=0.0 74scaled[0].each {|c0_item| cal_mean += c0_item} 75puts "Calculated mean of col[0] is:" 76puts cal_mean/scaled.shape[1] 77# 出力は 1.1102230246251565e-16 と、ほぼ0になっている。 78
補足情報(FW/ツールのバージョンなど)
バージョン情報
ruby 2.6.3p62 (2019-04-16 revision 67580)
daru (0.2.2, 0.1.2)
出力結果
Source Data is:
Daru::DataFrame(4x3)
col0 col1 col2
0 5.1 -2.9 3.3
1 -1.2 7.8 -6.1
2 3.9 0.4 2.1
3 7.3 -9.9 -4.5
Scaled Data is:
Daru::DataFrame(4x3)
col0 col1 col2
0 0.36773647 -0.2380493 0.98072329
1 -1.3807463 1.21745234 -1.0233634
2 0.03469212 0.21084370 0.72488243
3 0.97831780 -1.1902467 -0.6822422
Daru::Vector(3)
mean
col0 8.326672684688674e-1
col1 0.0
col2 0.0
Daru::Vector(3)
std
col0 1.0
col1 1.0
col2 0.9999999999999999
Calculated mean of col[0] is:
1.1102230246251565e-16
あなたの回答
tips
プレビュー