-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMwKwavg.lua
143 lines (115 loc) · 4.32 KB
/
MwKwavg.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
-- MwKwavg.lua
-- kernel weighted average using the Epanechnikov Quadratic Kernel
-- ref: Hastie-01 p.166 and following
-- example
if false then
local kwavg = MwKwavg(xs, ys, 'epanechnikov quadratic')
local ok, estimate = kwavg:estimate(query, lambda)
if not ok then
-- estimate is a string explaining why no estimate was provided
end
-- smooth is DEPRECATED
local useQueryPoint = false
local smoothedEstimate = MwKwavg:smooth(queryIndex, lambda,
useQueryPoint)
end
require 'affirm'
require 'KernelSmoother'
require 'makeVerbose'
require 'verify'
--------------------------------------------------------------------------------
-- CONSTRUCTION
--------------------------------------------------------------------------------
-- create class object
torch.class('MwKwavg')
function MwKwavg:__init(xs, ys, kernelName)
-- ARGS:
-- xs : 2D Tensor
-- the i-th input sample is xs[i]
-- ys : 1D Tensor or array of numbers
-- y[i] is the known value (target) of input sample xs[i]
-- number of ys must equal number of rows in xs
-- kernelName : string
local v, verbose = makeVerbose(false, 'MwKwavg:__init')
verify(v,
verbose,
{{xs, 'xs', 'isTensor2D'},
{ys, 'ys', 'isTensor1D'},
{kernelName, 'kernelName', 'isString'}
})
assert(kernelName == 'epanechnikov quadratic',
'for now, only kernel supported is epanechnikov quadratic')
self._xs = xs
self._ys = ys
self._kernelName = kernelName
self._kernelSmoother = KernelSmoother()
end
--------------------------------------------------------------------------------
-- PUBLIC METHODS
--------------------------------------------------------------------------------
function MwKwavg:estimate(query, lambda)
-- estimate y for a new query point using the specified kernel
-- ARGS:
-- lambda : number > 0, xs outside of this radius are given 0 weights
-- RESULTS:
-- true, estimate : estimate is the estimate for the query
-- estimate is a number
-- false, reason : no estimate was produced
-- reason is a string
local v, verbose = makeVerbose(false, 'MwKwavg:estimate')
verify(v,
verbose,
{{query, 'query', 'isTensor1D'},
{lambda, 'lambda', 'isNumberPositive'}
})
local weights = self._kernelSmoother:weights(self._xs,
query,
lambda)
local ok, estimate = self._kernelSmoother:weightedAverage(self._ys,
weights)
v('weights', weights)
v('ok', ok)
v('estimate', estimate)
return ok, estimate
end -- estimate
-- DEPRECATE smooth method
--[[
function Kwavg:smooth(queryIndex, lambda, useQueryPoint)
-- re-estimate y for an existing xs[queryIndex]
-- ARGS:
-- queryIndex : number >= 1
-- xs[math.floor(queryIndex)] is re-estimated
-- lambda : number > 0
-- useQueryPoint : boolean
-- if true, use the point at queryIndex as a neighbor
-- if false, don't
-- RESULTS:
-- true, estimate : estimate is the estimate at the query index
-- estimate is a number
-- false, reason : no estimate was produced
-- reason is a string
local v = makeVerbose(false, 'Kwavg:smooth')
v('queryIndex', queryIndex)
v('lambda', lambda)
v('useQueryPoint', useQueryPoint)
affirm.isIntegerPositive(queryIndex, 'queryIndex')
affirm.isNumberPositive(lambda, 'lambda')
affirm.isBoolean(useQueryPoint, 'useQueryPoint')
assert(queryIndex <= self._xs:size(1),
'queryIndex cannot exceed number of samples = ' ..
tostring(self._xs:size(1)))
local weights =
self:_determineWeights(self._xs[queryIndex], lambda)
if not useQueryPoint then
weights[queryIndex] = 0
end
local ok, value = self:_weightedAverage(weights)
v('ok', ok)
v('value', value)
return ok, value
end -- smooth
--]]
--------------------------------------------------------------------------------
-- PRIVATE METHODS
--------------------------------------------------------------------------------
-- NONE