Skip to content

Instantly share code, notes, and snippets.

@vznvzn
Created February 24, 2017 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vznvzn/a5b1b5bfbdc995c0756bc143acb5867d to your computer and use it in GitHub Desktop.
Save vznvzn/a5b1b5bfbdc995c0756bc143acb5867d to your computer and use it in GitHub Desktop.
require 'statsample'
def sum(l)
t = 0
l.each { |x| t += x }
return t
end
def av(l)
return nil if (l.empty?)
return sum(l) / l.size
end
def coef(x, y)
x1 = x2 = y1 = y2 = xy = 0.0
n = x.size
n.times \
{
|i|
x1 += x[i]
y1 += y[i]
xy += x[i] * y[i]
x2 += x[i] ** 2
y2 += y[i] ** 2
}
d = n * x2 - x1 ** 2
b = (y1 * x2 - x1 * xy) / d
m = (n * xy - x1 * y1) / d
b = 1 if (b.nan?)
m = 1 if (m.nan?)
return b, m
end
def d1(p, d, j)
r = (0...p.size)
r0 = r.select { |x| d[x].finite? }
raise if (r0.empty?)
t = sum(d.values_at(*r0))
w = []
r0.each { |x| w[x] = d[x] / t }
z = 0
r0.each { |x| z += (w[x] * p[x]) }
return z
end
def d2(p, d, j)
b, m = coef(d, p)
return b
end
def maxd(l)
m = l.max
return l.map { |x| m - x }
end
def near2(l, j, a, w)
l3 = a['l']
l2 = []
l1 = {'a' => ['a'], 'b' => ['a'], 'c' => ['a', 'b']}[$b[j]]
l.size.times \
{
|i|
next if (i == j)
next if (!l1.member?($b[i]))
d = 0
l3.each { |x| d += (l[i][x] - l[j][x]) ** 2 }
l2 << {'i' => i, 'd' => d}
}
l2 = l2.sort_by { |x| x['d'] }
r = (0..a['r'])
l4 = r.map { |x| l2[x]['i'] }
p = l4.map { |x| l[x][a['c']] }
d = r.map { |x| l2[x]['d'] }
return d1(p, d.map { |x| 1.0 / x }, j) if (w == 0)
return d1(p, maxd(d), j) if (w == 1)
return d2(p, d, j) if (w == 2)
end
def inc(e, b, x)
e[b] = {'t' => 0.0, 'c' => 0} if (!e.member?(b))
e[b]['t'] += x
e[b]['c'] += 1
end
def total(e)
return Hash[e.sort.map { |k, x| [k, x['t'] / x['c']] }]
end
def reshuffle()
l = $b.select { |x| x != 'c' }.shuffle
$b[0...l.size] = l
end
def stats(l)
e = {}
[l.map { |x| (x[0] - x[1]).abs }, $b].transpose.each \
{
|x, b|
inc(e, b, x)
}
return total(e)
end
def near(l, a, w)
l2 = (0...l.size).map { |i| near2(l, i, a, w) }
l1 = l.map { |x| x[a['c']] }
return stats([l1, l2].transpose).merge({'l2' => l2})
end
def out(fn, l)
f = File.open("#{fn}.txt", 'w')
l.each { |x| f.puts(x.join("\t")) }
f.close
end
def rbf(l, l1, y, w)
x = near(l, {'l' => l1, 'r' => 10, 'c' => y}, w)
return x['b']
end
def outby(fn, l)
out(fn, l.sort_by { |x| x[0] })
end
def rbf3(l)
return((0..2).map { |w| rbf(l, ['d', 'dh', 'dl', 'a', 'sd', 'mx', 'mn'], 'h2', w) })
end
def read(fn)
l = File.open('data.txt').readlines
l1 = l.shift.split
return l.map \
{
|x|
Hash[[l1, x.split.map { |y| y.to_f }].transpose]
}
end
def linear(l, y, lx)
l = l.values_at(*(0...l.size).select { |x| $b[x] == 'a' })
l1 = l.map { |x| x.values }.transpose
n = {}
l[0].keys.each_with_index { |x, i| n[x] = i }
a = {}
a['y'] = l1[n[y]].to_vector()
lx.each { |x| a[x] = l1[n[x]].to_vector() }
ds = a.to_dataset()
r = Statsample::Regression.multiple(ds, 'y')
# $stderr.puts(r.summary)
return r.coeffs.merge({'c' => r.constant})
end
def predict(l)
z = linear(l, 'h2', l[0].keys - ['nl', 'ls', 'h2'])
l = l.map { |x| x.dup }
l.each \
{
|x|
t = z['c']
(z.keys - ['c']).each { |k| t += z[k] * x[k] }
x['h2_p'] = t
x['ls_p'] = t / 50 * x['nl']
}
a = stats(l.map { |x| [x['h2'], x['h2_p']] })
return a['b']
end
def abc(n)
$b = []
a = {'a' => 1, 'b' => 1}
t = sum(a.values)
a.each \
{
|k, v|
$b += [k] * (v.to_f / t * n).to_i
}
$b[$b.size...n] = [a.keys.last] * (n - $b.size)
end
srand(0)
l = read('data.txt')
l.shuffle!
ls = l.size
$stderr.puts("ls=#{ls}")
abc(ls)
f1 = File.open('out1.txt', 'w')
f2 = File.open('out2.txt', 'w')
a = {}
loop \
{
l1 = [rbf3(l), predict(l)].flatten
f1.puts(l1.join("\t"))
f1.flush
l1.each_with_index { |x, i| inc(a, i, x) }
f2.puts(total(a).values.join("\t"))
f2.flush
reshuffle()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment