nysol-mining 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/mbopt.rb +522 -0
- data/bin/mburst.rb +716 -0
- data/bin/mgfeatures.rb +340 -0
- data/bin/mglmnet.rb +843 -0
- data/bin/mgnfeatures.rb +369 -0
- data/bin/mgpmetis.rb +449 -0
- data/bin/midxmine.rb +484 -0
- data/bin/mnb.rb +631 -0
- data/bin/mnetsimile.rb +572 -0
- data/bin/mnewman.rb +345 -0
- data/bin/msketchsort.rb +243 -0
- data/bin/msm.rb +172 -0
- data/ext/sketchsortrun/Main.cpp +161 -0
- data/ext/sketchsortrun/Main.hpp +24 -0
- data/ext/sketchsortrun/SketchSort.cpp +526 -0
- data/ext/sketchsortrun/SketchSort.hpp +138 -0
- data/ext/sketchsortrun/extconf.rb +26 -0
- data/ext/sketchsortrun/sketchsortrun.cpp +56 -0
- data/lib/nysol/mining.rb +24 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6d1059f408ce3e902e0aa15a401ef0fcbe4eed60
|
4
|
+
data.tar.gz: 89e81255c3704129808d1bca874ffded1d6d1b91
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 55e8338cf1ab4d7f7143e8b46e0131293a01774aa260158d3aecd018e34ca084843397673e209a2553ab3a20390c83b34daffca6482f73d8d0984fc6217ad29d
|
7
|
+
data.tar.gz: a6be4c34c4e850c3e089b259c46bacec8107bebba812a6c401553c4dc5d889f07ce77bf1de660e88c08115a331ae898333650ee1aa56843d057ff16373e05e03
|
data/bin/mbopt.rb
ADDED
@@ -0,0 +1,522 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
require "rubygems"
|
4
|
+
require "nysol/mcmd"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
# 1.0: first release: 2015/2/22
|
8
|
+
# 1.1: bug fix in running by ruby 1.8: 2015/3/17
|
9
|
+
# 1.2: add seed= parameter : 2015/7/18
|
10
|
+
# : bug fix in multi-processing mode
|
11
|
+
# 1.3: bug fix in building a null GP model : 2015/7/19
|
12
|
+
# 1.4: bug fix for directory path name and random seed: 2015/10/19
|
13
|
+
# 1.5: add log= parameter: 2015/11/22
|
14
|
+
# 2.0: change the order of parameters for optimization script: 2015/11/22
|
15
|
+
# : add continue mode,
|
16
|
+
# : change a default value for maxIter= and minImprove=
|
17
|
+
# : add history.csv in each iteration directory : 2015/11/22
|
18
|
+
# : add randomTrial= parameter
|
19
|
+
# 2.1: use abbsolute path for oFile
|
20
|
+
# : available for a int type parameter
|
21
|
+
# 3.0: add tgp for modeling, add optimum value on estimated surface 2017/06/20
|
22
|
+
# modification in visualization, remove log= parameter, etc
|
23
|
+
# disavailable for a int type parameter
|
24
|
+
$version="3.0"
|
25
|
+
$revision="###VERSION###"
|
26
|
+
|
27
|
+
def help
|
28
|
+
|
29
|
+
STDERR.puts <<EOF
|
30
|
+
----------------------------
|
31
|
+
mbopt.rb version #{$version}
|
32
|
+
----------------------------
|
33
|
+
概要) Gaussian Process Regressionを用いた最適化
|
34
|
+
特徴) 1) Rパッケージtgpを利用している。
|
35
|
+
用法) mbopt.rb scp= rsl= [mtype=] par= [basemax=] [splitmin=] [arg=]
|
36
|
+
[randomTrial=] [maxIter-] [-continue] O= [seed=] [-debug] [--help]
|
37
|
+
|
38
|
+
scp= : 目的関数プログラム名【必須】
|
39
|
+
: shellスクリプトでもrubyスクリプトでもCにより作成されたコマンドでも良い。
|
40
|
+
: mbopt.rb内部からコマンドとして起動される。その際のカレントパスは、実行時ディレクトリである。
|
41
|
+
: 引数は以下の通り、mbopt.rbから自動的に設定される。
|
42
|
+
: 1番目: プログラムが返す目的関数の値を保存するJSONファイル名(rsl=で指定した文字列)。
|
43
|
+
: 2番目から(1+p)番目: par=で指定したパラメータの値が、その順序で渡される。
|
44
|
+
:ここで、pはpar=で指定したパラメータ数。全て実数で渡される。
|
45
|
+
: (2+p)番目以降: arg=で指定した値
|
46
|
+
rsl= : 目的関数プログラムにより計算された値を格納したJSONファイル名【必須】
|
47
|
+
: 何らかの問題から目的関数が値を計算できない場合はnilを返す。
|
48
|
+
: そうすると、mboptは次にexpected improvementが大きなサンプル点をプログラムに渡して実行を継続する。
|
49
|
+
: 上位5つのサンプル点を与えても値が帰ってこない場合は、ランダムサンプリングによるサンプル点を渡す。
|
50
|
+
: さらにランダムサンプリングを10回繰り返しても値が帰ってこない場合は実行を中止する。
|
51
|
+
mtype= : 応答局面のモデル名。gp|tgp(gp:gaussian process regression,tgp:gp with tree)
|
52
|
+
: デフォルトはgp
|
53
|
+
par= : パラメータ名と定義域を指定する。【必須】
|
54
|
+
: パラメータの名称は結果出力におけるラベルとしてのみ使われるのでどのような名称でもよい。
|
55
|
+
: パラメータの指定順序は重要で、scp=で指定したスクリプトの2番目以降の引数として、その順序で渡される。
|
56
|
+
: ex. par=support:1:100,confidence:0.5:1.0
|
57
|
+
: 目的関数はsupportとconfidenceという名称の2つのパラメータをとり、
|
58
|
+
: それらの定義域は1〜100、および0.5〜1.0。
|
59
|
+
: mbopt.rbは、この定義域においてexpected improvementが最大となるサンプリング点を計算し、
|
60
|
+
: それらの値をscp=で指定したプログラムに与え実行する。
|
61
|
+
basemax= : par=の何番目までをgpモデルの変数として利用するか(最初の変数を1と数える)。
|
62
|
+
splitmin= : par=の何番目からをtreeのsplit変数のみに利用するか(最初の変数を1と数える)。
|
63
|
+
: basemax=5 splitmin=3の場合、par=の1,2番目の変数はGPのみに用いられ、
|
64
|
+
: 3,4,5番目の変数はGPとtreeの分岐の両方に利用され、
|
65
|
+
: 6番目から最後の変数まではtreeの分岐にのみ利用される。
|
66
|
+
: デフォルトは、basemax=最後の変数,splitmin=1、すなわち全変数をGP,分岐の両方に利用。
|
67
|
+
arg= : スクリプトに与えるその他の引数【オプション】
|
68
|
+
: par=で指定した引数の後ろにそのまま付加される。
|
69
|
+
: よって複数の引数を指定する場合はスペースで区切っておく。
|
70
|
+
randomTrial= : 最初にパラメータをランダムに決める回数【default:par=で指定した変数の数】
|
71
|
+
maxIter= : 最大繰り返し回数【default=20】
|
72
|
+
-continue : 既存の結果があれば、その続きから開始する。
|
73
|
+
: その時、maxIter=の値は、以前の実行結果を含む回数である。
|
74
|
+
O= : 出力パス【必須】
|
75
|
+
seed=: 乱数の種(0以上の整数)【オプション:指定がなければ時間依存】
|
76
|
+
-debug : Rの実行結果を表示
|
77
|
+
--help : ヘルプの表示
|
78
|
+
|
79
|
+
出力ファイル)
|
80
|
+
O=で指定したパス名の下に"iter_xxx"というディレクトリが生成され、その下に以下の7つのファイルが出力される。
|
81
|
+
ただし、randomTrialの時は、GPモデルが構築されないため2,3,5以外は出力されない。
|
82
|
+
1) pgr.png : 応答曲面(gpモデルの回帰超曲面)とexpected improvementの曲面のチャート
|
83
|
+
2) history.csv : これまでサンプリングされたパラメータとその目的関数の値、およびexpected improvement。
|
84
|
+
3) history.png : 目的関数の値とexpected improvementのこれまでの推移をチャート化したもの。
|
85
|
+
4) model.robj : Rで構築されたGPモデルのシリアライズ。
|
86
|
+
5) objVal.json : 目的関数プログラムが返した値のJSON。
|
87
|
+
6) optSurf.csv : 応答曲面における、expected improvement最大のサンプル点をスタート点にして、
|
88
|
+
: 最適化のアルゴリズムで計算された最適値およびそれに対応するパラメータの値
|
89
|
+
7) sampling.csv: expected improvementの上位5サンプルのパラメータの値。
|
90
|
+
|
91
|
+
必要なソフトウェア)
|
92
|
+
1) R
|
93
|
+
2) Rのtgpパッケージ(確認の取れているバージョン:2.4.14)
|
94
|
+
|
95
|
+
# Copyright(c) NYSOL 2012- All Rights Reserved.
|
96
|
+
EOF
|
97
|
+
exit
|
98
|
+
end
|
99
|
+
|
100
|
+
def ver()
|
101
|
+
$revision ="0" if $revision =~ /VERSION/
|
102
|
+
STDERR.puts "version #{$version} revision #{$revision}"
|
103
|
+
exit
|
104
|
+
end
|
105
|
+
|
106
|
+
help() if ARGV[0]=="--help" or ARGV.size <= 0
|
107
|
+
ver() if ARGV[0]=="--version"
|
108
|
+
|
109
|
+
args=MCMD::Margs.new(ARGV,"scp=,rsl=,mtype=,opt=,par=,basemax=,splitmin=,arg=,O=,randomTrial=,maxIter=,seed=,-continue,-debug,T=,-mcmdenv,T=","scp=,rsl=,par=,O=")
|
110
|
+
|
111
|
+
# mcmdのメッセージは警告とエラーのみ
|
112
|
+
ENV["KG_VerboseLevel"]="2" unless args.bool("-mcmdenv")
|
113
|
+
|
114
|
+
# Rライブラリ実行可能確認
|
115
|
+
exit(1) unless(MCMD::chkRexe("tgp"))
|
116
|
+
|
117
|
+
#ワークファイルパス
|
118
|
+
if args.str("T=")!=nil then
|
119
|
+
ENV["KG_TmpPath"] = args.str("T=").sub(/\/$/,"")
|
120
|
+
end
|
121
|
+
|
122
|
+
scp=args.str("scp=")
|
123
|
+
objVal=args.str("rsl=")
|
124
|
+
par=args.str("par=")
|
125
|
+
arg=args.str("arg=")
|
126
|
+
oPath=File.expand_path(args.file("O=","w"))
|
127
|
+
maxIter=args.int("maxIter=",20,1)
|
128
|
+
randomTrial=args.int("randomTrial=",1,1)
|
129
|
+
$debug=args.bool("-debug")
|
130
|
+
cont=args.bool("-continue")
|
131
|
+
seed=args.int("seed=")
|
132
|
+
srand(seed) if seed
|
133
|
+
|
134
|
+
mtype=args.str("mtype=","gp")
|
135
|
+
if mtype!="gp" and mtype!="tgp"
|
136
|
+
raise "#ERROR# mtype= must be 'gp' or 'tgp'"
|
137
|
+
end
|
138
|
+
|
139
|
+
# x1:-1:5,x2:-1:5
|
140
|
+
pars={}
|
141
|
+
pars["name"]=[]
|
142
|
+
pars["from"]=[]
|
143
|
+
pars["to"]=[]
|
144
|
+
|
145
|
+
psplit=par.split(",")
|
146
|
+
pars["size"]=psplit.size
|
147
|
+
psplit.each{|p|
|
148
|
+
pEle=p.split(":")
|
149
|
+
if pEle.size!=3 then
|
150
|
+
raise "#ERROR# each parameter on `par=' have to have four elements delimited by `:'"
|
151
|
+
end
|
152
|
+
pars["name"] << pEle[0]
|
153
|
+
pars["from"] << pEle[1].to_f
|
154
|
+
pars["to"] << pEle[2].to_f
|
155
|
+
}
|
156
|
+
|
157
|
+
randomTrial=pars["size"] if randomTrial < pars["size"]
|
158
|
+
pars["basemax"]=args.int("basemax=",pars["size"],1,pars["size"])
|
159
|
+
pars["splitmin"]=args.int("splitmin=",1,1,pars["size"])
|
160
|
+
|
161
|
+
def genRand(from,to)
|
162
|
+
#rand*(to-from)+from
|
163
|
+
rand(from..to)
|
164
|
+
end
|
165
|
+
|
166
|
+
def getRandParms(pars,iter)
|
167
|
+
pLists=[]
|
168
|
+
(0...iter).each{|iter|
|
169
|
+
pList=[]
|
170
|
+
(0...pars["size"]).each{|i|
|
171
|
+
from=pars["from"][i]
|
172
|
+
to =pars["to" ][i]
|
173
|
+
#pList << rand(from..to).to_s
|
174
|
+
pList << genRand(from,to).to_s
|
175
|
+
}
|
176
|
+
pList << nil # for improvement
|
177
|
+
pLists << pList
|
178
|
+
}
|
179
|
+
#puts "getRandParams"
|
180
|
+
#p pLists
|
181
|
+
return pLists
|
182
|
+
end
|
183
|
+
|
184
|
+
def getBestSample(iPath,pars,topK)
|
185
|
+
unless File.exist?("#{iPath}/sampling.csv")
|
186
|
+
return []
|
187
|
+
end
|
188
|
+
|
189
|
+
# sampling.csv
|
190
|
+
# x1,x2,x3,improv,rank
|
191
|
+
# 1.35059100005712,-1.78755048307456,1.70974605115513,1.38840388867507,4
|
192
|
+
# 1.72568620401257,-0.601321200708546,-1.06535568597386,1.37998186626775,2
|
193
|
+
wf=MCMD::Mtemp.new
|
194
|
+
xxbest=wf.file
|
195
|
+
f=""
|
196
|
+
f << "mnumber -q a=lineNo i=#{iPath}/sampling.csv |"
|
197
|
+
f << "mbest s=rank%n from=0 size=#{topK} o=#{xxbest}"
|
198
|
+
system(f)
|
199
|
+
|
200
|
+
# arrays for X variables for top K expected improvement
|
201
|
+
bestStr=`mcut f=x*,improv -nfno i=#{xxbest}`.strip.gsub("\n",",").split(",")
|
202
|
+
bestSamples=[]
|
203
|
+
(0...topK).each{|k|
|
204
|
+
array=[]
|
205
|
+
(0...pars['size']+1).each{|i|
|
206
|
+
array << bestStr[i].to_f
|
207
|
+
}
|
208
|
+
bestSamples << array
|
209
|
+
}
|
210
|
+
|
211
|
+
return bestSamples
|
212
|
+
end
|
213
|
+
|
214
|
+
def buildGPmodel(mtype,yVar,xVar,pars,seed,prevIterPath,oPath)
|
215
|
+
wf=MCMD::Mtemp.new
|
216
|
+
scp=wf.file #"xxscp"
|
217
|
+
xFile=wf.file #"xxY"
|
218
|
+
yFile=wf.file #"xxX"
|
219
|
+
File.open(yFile,"w"){|fpw| yVar.each{|v| fpw.puts(v)}}
|
220
|
+
File.open(xFile,"w"){|fpw| xVar.each{|v| fpw.puts(v.join(","))}}
|
221
|
+
|
222
|
+
rFile=wf.file # range for xVar
|
223
|
+
File.open(rFile,"w"){|fpw|
|
224
|
+
(0...pars["from"].size).each{|i|
|
225
|
+
fpw.puts "#{pars["from"][i]},#{pars["to"][i]}"
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
nFile=wf.file # names
|
230
|
+
File.open(nFile,"w"){|fpw|
|
231
|
+
pars["name"].each{|name|
|
232
|
+
fpw.puts "#{name}"
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
seedText=""
|
237
|
+
seedText="set.seed(#{seed})" if seed
|
238
|
+
|
239
|
+
r_scp = <<EOF
|
240
|
+
library('tgp')
|
241
|
+
|
242
|
+
#{seedText}
|
243
|
+
|
244
|
+
#### reading field names
|
245
|
+
fldName=read.csv("#{nFile}",header=F)
|
246
|
+
fldName=fldName[,1]
|
247
|
+
print(fldName)
|
248
|
+
|
249
|
+
#### reading data files
|
250
|
+
xvar=read.csv("#{xFile}",header=F) # training xVar
|
251
|
+
yvar=read.csv("#{yFile}",header=F) # training yVar
|
252
|
+
xvar=as.matrix(xvar)
|
253
|
+
yvar=as.vector(yvar)
|
254
|
+
|
255
|
+
#### random sampling
|
256
|
+
rect=read.csv("#{rFile}",header=F) # range for xVar
|
257
|
+
rect=as.matrix(rect, ncol = 2)
|
258
|
+
samp=lhs(length(rect)*20, rect)
|
259
|
+
|
260
|
+
#### optimum data point in the last iteration
|
261
|
+
if (file.exists("#{prevIterPath}/optSurf.csv")) {
|
262
|
+
prevOpt=read.csv("#{prevIterPath}/optSurf.csv",header=T)
|
263
|
+
prevOpt=prevOpt[,colnames(prevOpt)!="y"]
|
264
|
+
prevOpt=prevOpt[,colnames(prevOpt)!="iter"]
|
265
|
+
samp=rbind(samp,as.matrix(prevOpt,nrow=1))
|
266
|
+
}
|
267
|
+
|
268
|
+
#### GP regression
|
269
|
+
# generate a GP regression model with calculating top ten sampling points
|
270
|
+
model=try( b#{mtype}(X=xvar,Z=yvar,XX=samp,improv=c(1,5), basemax=#{pars["basemax"]}, splitmin=#{pars["splitmin"]}),silent=TRUE)
|
271
|
+
if(class(model)=="try-error"){
|
272
|
+
q()
|
273
|
+
}
|
274
|
+
png("#{oPath}/tree.png")
|
275
|
+
tgp.trees(model)
|
276
|
+
dev.off()
|
277
|
+
|
278
|
+
# write GP regression model
|
279
|
+
save(model ,file="#{oPath}/model.robj")
|
280
|
+
|
281
|
+
# write GP regression plot
|
282
|
+
xSize=ncol(xvar)
|
283
|
+
if(xSize==1){
|
284
|
+
png("#{oPath}/gpr.png")
|
285
|
+
par(mfrow=c(2,1))
|
286
|
+
plot(model,layout="surf" )
|
287
|
+
plot(model,layout="as",as="improv")
|
288
|
+
dev.off()
|
289
|
+
} else {
|
290
|
+
png("#{oPath}/gpr.png")
|
291
|
+
# plt: setting margines
|
292
|
+
par(mfrow=c(xSize*(xSize-1)/2,2),plt = c(0.02, 0.98, 0.02, 0.98))
|
293
|
+
for (i in 1:(xSize-1)) {
|
294
|
+
for (j in (i+1):xSize) {
|
295
|
+
plot(model,layout="surf" ,xlab=fldName[i],ylab=fldName[j], proj=c(i,j))
|
296
|
+
plot(model,layout="as",as="improv",xlab=fldName[i],ylab=fldName[j], proj=c(i,j))
|
297
|
+
}
|
298
|
+
}
|
299
|
+
dev.off()
|
300
|
+
}
|
301
|
+
|
302
|
+
#### calculate the optimum xvar and yvar in both xvar and samp
|
303
|
+
# get optimum for sampling point of xvar and yvar
|
304
|
+
optYvar=min(c(model$Zp.mean, model$ZZ.mean))
|
305
|
+
idx=which.min(c(model$Zp.mean, model$ZZ.mean))
|
306
|
+
both=rbind(xvar, samp)
|
307
|
+
optXvar=both[idx,]
|
308
|
+
#optSamp=data.frame(matrix(c(optXvar, optYvar), nrow = 1))
|
309
|
+
#names(optSamp)=c(paste("x", 1:nrow(rect), sep = ""), "y")
|
310
|
+
# output one line csv data like "x1,x2,...,y"
|
311
|
+
#write.csv(optSamp,"#{oPath}/optSamp.csv",quote=FALSE,row.names=F)
|
312
|
+
|
313
|
+
# explore the optimum point on the estimated GP surface starting from optXvar
|
314
|
+
optSurf=optim.ptgpf(optXvar, rect, model, "L-BFGS-B")
|
315
|
+
optSurf=data.frame(matrix(c(optSurf$par, optSurf$value), nrow = 1)) # optimum xvar and yvar on the surface
|
316
|
+
names(optSurf)=c(paste("x", 1:nrow(rect), sep = ""), "y")
|
317
|
+
# output one line csv data like "x1,x2,...,y"
|
318
|
+
write.csv(optSurf,"#{oPath}/optSurf.csv",quote=FALSE,row.names=F)
|
319
|
+
|
320
|
+
#### output next 5 sampling points with expected improvement for the next iteration
|
321
|
+
improv=model$improv
|
322
|
+
samp=data.frame(samp)
|
323
|
+
names(samp) <- c(paste("x", 1:nrow(rect), sep=""))
|
324
|
+
samp=samp[improv[,2] <= 5,] # choose by rank
|
325
|
+
samp=cbind(samp,improv[improv[,2] <= 5,])
|
326
|
+
write.csv(samp,"#{oPath}/sampling.csv",quote=FALSE,row.names=F)
|
327
|
+
EOF
|
328
|
+
|
329
|
+
# write R script, and run it
|
330
|
+
exePath=wf.file
|
331
|
+
MCMD::mkDir(exePath)
|
332
|
+
MCMD::mkDir(oPath)
|
333
|
+
File.open(scp,"w"){|fpw| fpw.write r_scp}
|
334
|
+
if $debug
|
335
|
+
system "cd #{exePath} ; R --vanilla -q < #{scp}"
|
336
|
+
else
|
337
|
+
system "cd #{exePath} ; R --vanilla -q < #{scp} &>/dev/null"
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def getLastIterNo(oPath)
|
342
|
+
last=-1
|
343
|
+
Dir["#{oPath}/iter_*"].each{|it|
|
344
|
+
no=it.sub(/^.*iter_/,"").to_i
|
345
|
+
last=no if no>last
|
346
|
+
}
|
347
|
+
return last
|
348
|
+
end
|
349
|
+
|
350
|
+
def readHistory(iFile,pars)
|
351
|
+
xVarHis=[]
|
352
|
+
yVarHis=[]
|
353
|
+
MCMD::Mcsvin.new("i=#{iFile}"){|iCSV|
|
354
|
+
iCSV.each{|flds|
|
355
|
+
yVal=flds["objValue"].to_f
|
356
|
+
yVarHis << yVal
|
357
|
+
xVar=[]
|
358
|
+
pars['name'].each{|name|
|
359
|
+
xVar << flds[name].to_f
|
360
|
+
}
|
361
|
+
xVarHis << xVar
|
362
|
+
}
|
363
|
+
}
|
364
|
+
return xVarHis,yVarHis
|
365
|
+
end
|
366
|
+
|
367
|
+
def sampling(pars,prevIterPath)
|
368
|
+
# sampling X variables with top 5 expected improvement
|
369
|
+
xVars1=getBestSample(prevIterPath,pars,5)
|
370
|
+
|
371
|
+
# sampling X variables at random
|
372
|
+
xVars2=getRandParms(pars,10)
|
373
|
+
|
374
|
+
return xVars1.concat(xVars2)
|
375
|
+
end
|
376
|
+
|
377
|
+
def execObjectiveFunction(xVars,scp,pars,arg,objVal,thisIterPath)
|
378
|
+
yVar=xVar=improv=nil
|
379
|
+
(0...xVars.size).each{|k|
|
380
|
+
## RUN the Objective Function Here!! ##
|
381
|
+
# delete_at(-1) : remove the element of EI
|
382
|
+
improv=xVars[k].delete_at(-1)
|
383
|
+
system "#{scp} #{objVal} #{xVars[k].join(' ')} #{arg}"
|
384
|
+
|
385
|
+
# copying objVal file as "objVal.json" which is generated in the optimization script
|
386
|
+
system "cp #{objVal} #{thisIterPath}/objVal.json"
|
387
|
+
|
388
|
+
# get the objective value returned from the scp
|
389
|
+
yVar = File.open(objVal){|fpr| JSON.load(fpr)}
|
390
|
+
|
391
|
+
if yVar
|
392
|
+
xVar=xVars[k]
|
393
|
+
break
|
394
|
+
end
|
395
|
+
MCMD::warningLog(" the objective function did not return a value.")
|
396
|
+
}
|
397
|
+
return yVar,xVar,improv
|
398
|
+
end
|
399
|
+
|
400
|
+
# return the current ranking of yVal
|
401
|
+
# iter%0n,expImprovement,objective,x1,x2,x3,rank
|
402
|
+
# 0,,2.497238452,-1.617803189503011,1.7000148047278243,-0.6257063036187969,5
|
403
|
+
# 1,,2.001004884,-0.9279654404927888,-1.0276931078703342,1.1572219738148268,4
|
404
|
+
def getInfo(iPath)
|
405
|
+
# history.csv
|
406
|
+
topSize =`mselstr f=rank v=1 i=#{iPath}/history.csv | mcount a=freq | mcut f=freq -nfno`
|
407
|
+
thisRank =`mbest s=iter%nr i=#{iPath}/history.csv | mcut f=rank -nfno`
|
408
|
+
thisY=`mbest s=iter%nr i=#{iPath}/history.csv | mcut f=objValue -nfno`
|
409
|
+
optY =`mstats f=objValue c=min i=#{iPath}/history.csv | mcut f=objValue -nfno`
|
410
|
+
upd=nil
|
411
|
+
upd="UPDATED!!" if topSize.to_i==1 and thisRank.to_i==1
|
412
|
+
return upd,thisY.to_f,optY.to_f
|
413
|
+
end
|
414
|
+
|
415
|
+
def writeHistory(yVarHis,xVarHis,improvHis,pars,path)
|
416
|
+
temp=MCMD::Mtemp.new
|
417
|
+
xxtemp=temp.file
|
418
|
+
xxscp=temp.file
|
419
|
+
|
420
|
+
# output xVarHis and yVarHis
|
421
|
+
MCMD::Mcsvout.new("f=iter,expImprovement,objValue,#{pars['name'].join(',')} o=#{xxtemp}"){|oCSV|
|
422
|
+
(0...yVarHis.size).each{|i|
|
423
|
+
line=[i,improvHis[i],yVarHis[i]]
|
424
|
+
line.concat(xVarHis[i])
|
425
|
+
oCSV.write(line)
|
426
|
+
}
|
427
|
+
}
|
428
|
+
system "mnumber s=objValue%n S=1 e=skip a=rank i=#{xxtemp} | msortf f=iter%n o=#{path}/history.csv"
|
429
|
+
|
430
|
+
# history.csv
|
431
|
+
# iter%0n,expImprovement,objValue,x1,x2,x3,rank
|
432
|
+
# 0,,2.497238452,-1.617803189503011,1.7000148047278243,-0.6257063036187969,4
|
433
|
+
# 1,,2.001004884,-0.9279654404927888,-1.0276931078703342,1.1572219738148268,3
|
434
|
+
r_scp = <<EOF
|
435
|
+
d=read.csv("#{path}/history.csv",header=T)
|
436
|
+
png("#{path}/history.png")
|
437
|
+
default.par <- par()
|
438
|
+
mai <- par()$mai
|
439
|
+
mai[4] <- mai[1]
|
440
|
+
par(mai = mai)
|
441
|
+
options(warn=-1)
|
442
|
+
matplot(d$iter,d$objValue,col="royalblue3",pch=c(15,0),cex=1,type="b",lwd=2,lty=1,ylab="objective value",xlab="iteration")
|
443
|
+
par(new=T)
|
444
|
+
ret=try(matplot(d$iter,d$expImprovement,col="brown3",pch=c(15,0),cex=1,type="b",lwd=2,lty=1,axes=F,ylab="",xlab=""),silent=TRUE)
|
445
|
+
axis(4)
|
446
|
+
mtext("expected improvement", side = 4, line = 3)
|
447
|
+
par(default.par)
|
448
|
+
legend("top", legend=c("OF", "EI"), col=c("royalblue3","brown3"),pch=c(15,0), lwd=2, lty=1)
|
449
|
+
title("development of EI and OF")
|
450
|
+
options(warn=0)
|
451
|
+
dev.off()
|
452
|
+
EOF
|
453
|
+
File.open(xxscp,"w"){|fpw| fpw.write r_scp}
|
454
|
+
if $debug
|
455
|
+
system "R --vanilla -q < #{xxscp}"
|
456
|
+
else
|
457
|
+
system "R --vanilla -q < #{xxscp} &>/dev/null"
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
############################## main
|
462
|
+
MCMD::mkDir(oPath)
|
463
|
+
|
464
|
+
# set a starting iteration number
|
465
|
+
startIter=0
|
466
|
+
xVarHis=[]
|
467
|
+
yVarHis=[]
|
468
|
+
improvHis=[]
|
469
|
+
|
470
|
+
# in continue mode
|
471
|
+
startIter=getLastIterNo(oPath)+1 if cont
|
472
|
+
|
473
|
+
# 1. adaptive sampling => xVarCands
|
474
|
+
# 2. execute an objective function => yVar,xVar => new data
|
475
|
+
# 3. build a GP regression model
|
476
|
+
# 4. update the optimum(minimum) yVal for sampling point xVar and estimated surface
|
477
|
+
(startIter...maxIter).each{|iter|
|
478
|
+
MCMD.msgLog("##### iteration ##{iter} starts.")
|
479
|
+
|
480
|
+
prevIterPath="#{oPath}/iter_#{sprintf('%04d',iter-1)}"
|
481
|
+
thisIterPath="#{oPath}/iter_#{sprintf('%04d',iter)}"
|
482
|
+
MCMD::mkDir(thisIterPath)
|
483
|
+
|
484
|
+
# sampling candiate points of X variables and their EI
|
485
|
+
xVarCands=sampling(pars,prevIterPath)
|
486
|
+
|
487
|
+
# execute objective function using X variables on xVarCands one by one
|
488
|
+
# and get yVar and xVar.
|
489
|
+
yVar,xVar,improv=execObjectiveFunction(xVarCands,scp,pars,arg,objVal,thisIterPath)
|
490
|
+
|
491
|
+
unless yVar
|
492
|
+
MCMD::warningLog(" finally give up to get a value")
|
493
|
+
break
|
494
|
+
end
|
495
|
+
|
496
|
+
# add xVar and yVar to
|
497
|
+
xVarHis << xVar
|
498
|
+
yVarHis << yVar
|
499
|
+
improvHis << improv
|
500
|
+
|
501
|
+
# update GP regression model using xVar and yVar as a training data,
|
502
|
+
# and copy all necessary files to thisIterPath.
|
503
|
+
# no model is built if iter<randomTrial, meaning to use random sampling point.
|
504
|
+
if iter>=randomTrial-1
|
505
|
+
buildGPmodel(mtype,yVarHis,xVarHis,pars,seed,prevIterPath,thisIterPath)
|
506
|
+
MCMD::warningLog(" GP model was not built") unless File.exist?("#{thisIterPath}/model.robj")
|
507
|
+
else
|
508
|
+
MCMD::msgLog(" skip modeling in random trial")
|
509
|
+
end
|
510
|
+
|
511
|
+
# write all values of yVar, xVar and EI, which are previously examined.
|
512
|
+
writeHistory(yVarHis,xVarHis,improvHis,pars,thisIterPath)
|
513
|
+
|
514
|
+
# ranking of yVar for this iteration
|
515
|
+
upd,thisY,optY=getInfo(thisIterPath)
|
516
|
+
|
517
|
+
MCMD::msgLog(" BEST OBJ VALUE: #{optY} (this trial:#{thisY}) #{upd}")
|
518
|
+
}
|
519
|
+
|
520
|
+
# end message
|
521
|
+
MCMD::endLog(args.cmdline)
|
522
|
+
|