Skip to content

Instantly share code, notes, and snippets.

@DSCF-1224
Created May 4, 2020 03:05
Show Gist options
  • Save DSCF-1224/6d40955be52211f8a37bd3b66cb5bf29 to your computer and use it in GitHub Desktop.
Save DSCF-1224/6d40955be52211f8a37bd3b66cb5bf29 to your computer and use it in GitHub Desktop.
ガウス過程と機械学習 第1章 lm.py version 01
# ==================================================================================================================================
# ISBN 978-4-06-152926-7
# ガウス過程と機械学習
#
# [reference]
# http://chasen.org/~daiti-m/gpbook/python/lm.py
# http://chasen.org/~daiti-m/gpbook/data/nonlinear.dat
# https://nbviewer.jupyter.org/gist/genkuroki/a37894d5669ad13b4cd27da16096bfd2
# https://github.com/JuliaData/CSV.jl/issues/371 <- `ignorerepeated = true`
#
# [How to execute]
# Base.cd("?\\GitHub\\ISBN9784061529267\\julia\\chap01")
# Base.MainInclude.include("?\\GitHub\\ISBN9784061529267\\julia\\chap01\\lm_v03.jl")
# ==================================================================================================================================
module ISBN9784061529267
import CSV # v0.6.1
import HTTP # v0.8.14
import Printf
export main
struct ObservedData
size :: Core.Int64
inpt :: Base.Vector{Core.Float64} # observed input
otpt :: Base.Vector{Core.Float64} # observed output
end
struct RegressionDegree
poly :: Core.Int64
trig :: Core.Int64
end
struct RegressionWeight
degree :: RegressionDegree
value :: Base.Vector{Core.Float64}
end
mutable struct EstimatedData
size :: Core.Int64
inpt :: Base.Vector{Core.Float64} # input to estimate
otpt :: Base.Vector{Core.Float64} # estimated output
end
function read_data(file_path)
# STEP.01
# get the sample data from online
# obj_CSV = CSV.read("../../downloaded/chap01/nonlinear.dat"; delim=' ', ignorerepeated = true, header=[:inpt, :otpt], footerskip=1) # access to local file
obj_CSV = CSV.read(HTTP.get(file_path).body; delim=' ', ignorerepeated = true, header=[:inpt, :otpt], footerskip=1) # access to online file
# STEP.02
# convert the read data to the array on Julia
data_size = Base.size(obj_CSV.inpt, 1)
buffer_inpt = Base.zeros(data_size)
buffer_otpt = Base.zeros(data_size)
for itr in 1:1:data_size
buffer_inpt[itr] = obj_CSV.inpt[itr]
buffer_otpt[itr] = obj_CSV.otpt[itr]
end
# STEP.END
# return `ObservedData` instance which is generated from read data
return ObservedData(data_size, buffer_inpt, buffer_otpt)
end
function compute_weight(degree::RegressionDegree, observed_data::ObservedData)
# STEP.01
# prepare the array to store the design matrix
design_matrix = Base.ones(Core.Float64, observed_data.size, degree.poly + 2 * degree.trig + 1)
# STEP.02
# compute the polynominal part of the design matrix
for itr_cl in 2:1:(degree.poly + 1)
design_matrix[:, itr_cl] = design_matrix[:, itr_cl - 1] .* observed_data.inpt[:]
end
# STEP.03
# compute the trigonometric function part of the design matrix
for itr_cl in 1:1:degree.trig
design_matrix[:, (degree.poly + 1) + (2 * itr_cl - 1)] = Base.cos.(itr_cl * observed_data.inpt)
design_matrix[:, (degree.poly + 1) + (2 * itr_cl )] = Base.sin.(itr_cl * observed_data.inpt)
end
# STEP.04
# generate the transposed design matrix
design_matrix_transposed = Base.transpose(design_matrix)
# STEP.END
# compute the weight of regression
# return `RegressionWeight` instance
return RegressionWeight( degree, Base.inv( design_matrix_transposed * design_matrix ) * design_matrix_transposed * observed_data.otpt )
end
function estimate_output(size::Core.Int64, observed_data::ObservedData, regression_weight::RegressionWeight)
# STEP.01
# compute the input
buffer_extrema = Base.extrema(observed_data.inpt)
buffer_input = Base.range( buffer_extrema[1]; length = size, stop = buffer_extrema[2] )
# STEP.02
# compute the output (polynominal part)
itr_degree = regression_weight.degree.poly
buffer_output = regression_weight.value[itr_degree] .+ regression_weight.value[itr_degree + 1] .* buffer_input
while itr_degree > 1
itr_degree -= 1
buffer_output = buffer_input .* buffer_output .+ regression_weight.value[itr_degree]
end
# STEP.03
# compute the output (trigonometric function part)
for itr_degree in 1:1:regression_weight.degree.trig
buffer_output += regression_weight.value[ (regression_weight.degree.poly + 1) + (2 * itr_degree - 1) ] * Base.cos.(itr_degree * buffer_input)
buffer_output += regression_weight.value[ (regression_weight.degree.poly + 1) + (2 * itr_degree ) ] * Base.sin.(itr_degree * buffer_input)
end
return EstimatedData(size, buffer_input, buffer_output)
end
function save_result(observed_data::ObservedData, regression_weight::RegressionWeight, estimated_data::EstimatedData)
obj_txt_result = Base.open("result.csv", "w")
Printf.@printf(obj_txt_result, "%s,%s\n", "degree", "weight")
for itr in 1:1:(regression_weight.degree.poly + 2 * regression_weight.degree.trig + 1)
Printf.@printf(obj_txt_result, "%d,%E\n", itr - 1, regression_weight.value[itr])
end
Printf.@printf(obj_txt_result, "\n")
Printf.@printf(obj_txt_result, "%s,%s\n", "input", "output (observed)")
for itr in 1:1:observed_data.size
Printf.@printf(obj_txt_result, "%E,%E\n", observed_data.inpt[itr], observed_data.otpt[itr])
end
Printf.@printf(obj_txt_result, "\n")
Printf.@printf(obj_txt_result, "%s,%s\n", "input", "output (estimated)")
for itr in 1:1:estimated_data.size
Printf.@printf(obj_txt_result, "%E,%E\n", estimated_data.inpt[itr], estimated_data.otpt[itr])
end
Base.close( obj_txt_result )
end
function main()
# STEP.01
# get the sample data from online
obj_observed_data = read_data("http://chasen.org/~daiti-m/gpbook/data/nonlinear.dat")
# STEP.02
# compute the weight for regression
obj_regression_weight = compute_weight( RegressionDegree(2, 1), obj_observed_data )
# STEP.03
# compute the estimated output using regression
obj_estimated_data = estimate_output(101, obj_observed_data, obj_regression_weight)
# STEP.04
# save the computed result
save_result(obj_observed_data, obj_regression_weight, obj_estimated_data)
end
end
# ==================================================================================================================================
@time ISBN9784061529267.main()
# ==================================================================================================================================
# EOF
# ==================================================================================================================================
# ==================================================================================================================================
# ISBN 978-4-06-152926-7
# ガウス過程と機械学習
#
# [reference]
# http://chasen.org/~daiti-m/gpbook/python/lm.py
# http://chasen.org/~daiti-m/gpbook/data/nonlinear.dat
# https://nbviewer.jupyter.org/gist/genkuroki/a37894d5669ad13b4cd27da16096bfd2
# https://github.com/JuliaData/CSV.jl/issues/371 <- `ignorerepeated = true`
# ==================================================================================================================================
set datafile separator comma
set key on outside right center vertical Left reverse
set format x '%3.1f'
set format y '%3.1f'
set xlabel 'input'
set ylabel 'output'
set xzeroaxis linetype -1
set yzeroaxis linetype -1
plot 'result.csv' using 1:2 every ::1:1::1 with points title 'observed' , \
'result.csv' using 1:2 every ::1:2::2 with lines title 'regression'
# ==================================================================================================================================
# EOF
# ==================================================================================================================================
degree weight
0 -9.542660E-02
1 7.232296E-02
2 2.420071E-02
3 -9.087541E-01
4 2.993996E-01
input output (observed)
2.761362E+00 7.812694E-01
-2.502037E+00 5.784024E-01
-6.534198E-01 -8.364839E-01
-5.093708E-01 -1.065994E+00
1.069812E+00 -5.053178E-01
1.244485E+00 6.569320E-02
-1.583863E-01 -1.713290E+00
-1.818896E+00 1.539270E-01
-3.612937E+00 1.044064E+00
-2.826306E+00 7.741641E-01
-1.020446E+00 -8.304516E-01
2.611304E-01 -1.320288E+00
-9.667795E-01 -1.083977E+00
4.701717E-01 -4.560080E-02
-7.279929E-01 -3.691600E-02
3.050133E-01 -1.170321E+00
3.901433E-01 -7.787978E-01
3.043049E+00 1.279998E+00
-1.630756E+00 -2.210154E-01
-3.516084E+00 5.724240E-01
-6.489837E+00 -4.126926E-01
1.820185E+00 9.120053E-01
-7.767629E-01 -8.371592E-01
-3.410699E+00 6.317732E-01
-9.195992E-01 -1.247660E+00
-1.124827E+00 -4.371627E-01
-1.511641E+00 -7.774516E-01
1.820330E+00 1.251691E+00
-1.118554E+00 -1.622740E+00
input output (estimated)
-6.489837E+00 -4.963564E-01
-6.394508E+00 -5.047257E-01
-6.299179E+00 -5.041520E-01
-6.203851E+00 -4.948439E-01
-6.108522E+00 -4.770853E-01
-6.013193E+00 -4.512327E-01
-5.917864E+00 -4.177122E-01
-5.822535E+00 -3.770155E-01
-5.727206E+00 -3.296957E-01
-5.631877E+00 -2.763616E-01
-5.536548E+00 -2.176730E-01
-5.441220E+00 -1.543342E-01
-5.345891E+00 -8.708772E-02
-5.250562E+00 -1.670757E-02
-5.155233E+00 5.600776E-02
-5.059904E+00 1.302426E-01
-4.964575E+00 2.051714E-01
-4.869246E+00 2.799663E-01
-4.773918E+00 3.538049E-01
-4.678589E+00 4.258771E-01
-4.583260E+00 4.953930E-01
-4.487931E+00 5.615901E-01
-4.392602E+00 6.237397E-01
-4.297273E+00 6.811540E-01
-4.201944E+00 7.331924E-01
-4.106616E+00 7.792666E-01
-4.011287E+00 8.188470E-01
-3.915958E+00 8.514666E-01
-3.820629E+00 8.767257E-01
-3.725300E+00 8.942956E-01
-3.629971E+00 9.039212E-01
-3.534642E+00 9.054236E-01
-3.439313E+00 8.987017E-01
-3.343985E+00 8.837329E-01
-3.248656E+00 8.605739E-01
-3.153327E+00 8.293593E-01
-3.057998E+00 7.903010E-01
-2.962669E+00 7.436863E-01
-2.867340E+00 6.898750E-01
-2.772011E+00 6.292960E-01
-2.676683E+00 5.624441E-01
-2.581354E+00 4.898746E-01
-2.486025E+00 4.121992E-01
-2.390696E+00 3.300794E-01
-2.295367E+00 2.442216E-01
-2.200038E+00 1.553698E-01
-2.104709E+00 6.429921E-02
-2.009381E+00 -2.819070E-02
-1.914052E+00 -1.212837E-01
-1.818723E+00 -2.141539E-01
-1.723394E+00 -3.059737E-01
-1.628065E+00 -3.959208E-01
-1.532736E+00 -4.831861E-01
-1.437407E+00 -5.669807E-01
-1.342078E+00 -6.465435E-01
-1.246750E+00 -7.211474E-01
-1.151421E+00 -7.901066E-01
-1.056092E+00 -8.527827E-01
-9.607630E-01 -9.085900E-01
-8.654342E-01 -9.570016E-01
-7.701053E-01 -9.975533E-01
-6.747765E-01 -1.029849E+00
-5.794476E-01 -1.053562E+00
-4.841187E-01 -1.068442E+00
-3.887899E-01 -1.074312E+00
-2.934610E-01 -1.071076E+00
-1.981321E-01 -1.058715E+00
-1.028033E-01 -1.037287E+00
-7.474416E-03 -1.006932E+00
8.785445E-02 -9.678654E-01
1.831833E-01 -9.203769E-01
2.785122E-01 -8.648297E-01
3.738410E-01 -8.016560E-01
4.691699E-01 -7.313531E-01
5.644988E-01 -6.544792E-01
6.598276E-01 -5.716481E-01
7.551565E-01 -4.835237E-01
8.504854E-01 -3.908140E-01
9.458142E-01 -2.942646E-01
1.041143E+00 -1.946520E-01
1.136472E+00 -9.277653E-02
1.231801E+00 1.054493E-02
1.327130E+00 1.144864E-01
1.422459E+00 2.182201E-01
1.517787E+00 3.209245E-01
1.613116E+00 4.217910E-01
1.708445E+00 5.200319E-01
1.803774E+00 6.148872E-01
1.899103E+00 7.056319E-01
1.994432E+00 7.915821E-01
2.089761E+00 8.721015E-01
2.185089E+00 9.466070E-01
2.280418E+00 1.014574E+00
2.375747E+00 1.075542E+00
2.471076E+00 1.129117E+00
2.566405E+00 1.174978E+00
2.661734E+00 1.212874E+00
2.757063E+00 1.242636E+00
2.852391E+00 1.264167E+00
2.947720E+00 1.277454E+00
3.043049E+00 1.282559E+00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment