Skip to content

Commit

Permalink
[AdPredictor] Code reduction in AdPredictor inference routines
Browse files Browse the repository at this point in the history
Summary:
Reducing amount of code.

Test Plan:
```
make test
make demo
```

Reviewers:

CC:
  • Loading branch information
ajtulloch committed Dec 1, 2013
1 parent 4c57926 commit 639d20b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 54 deletions.
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ ANIMATE = convert \
-unsharp 0x1 \
-loop 0 /tmp/adpredictor/*.png

all:
test
all: | test

proto:
mkdir -p protobufs
Expand Down
13 changes: 1 addition & 12 deletions adpredictor.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,7 @@ message Feature {
optional int64 value = 2;
}

message TrainingRequest {
optional bool label = 1;
repeated Feature features = 2;
}

message Gaussian {
optional double mean = 1;
optional double variance = 2;
}

message PredictionRequest {
repeated Feature features = 1;
}


}
63 changes: 23 additions & 40 deletions adpredictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,59 +16,44 @@ class AdPredictor(object):
def __init__(self, config):
self._config = config
self._weights = {}

# Initial bias weight
self._set_weight(
util.bias_feature(),
util.prior_bias_weight(
config.prior_probability, config.beta, config.num_features))
bias_weight = util.prior_bias_weight(
config.prior_probability,
config.beta,
config.num_features)

@property
def weights(self):
return [(util.deserialize_feature(f), w)
for (f, w) in self._weights.iteritems()]
self._set_weight(util.bias_feature(), bias_weight)

def predict(self, features):
logger.info("Predicting: %s features", len(features))
logger.debug("Predicting: %s", map(util.pp, features))

assert len(features) == self._config.num_features
return norm.cdf(self._total_mean(features) /
self._total_variance(features))

total_mean, total_variance = self._active_mean_variance(features)
return norm.cdf(total_mean / total_variance)

def train(self, features, label):
logger.info("Training: %s, %s features", label, len(features))
logger.debug("Training: %s, %s", label, map(util.pp, features))
assert len(features) == self._config.num_features

y = util.label_to_float(label)
sigmaSquared = self._total_variance(features)
totalMean = self._total_mean(features)
surprise = y * totalMean / sigmaSquared

v, w = util.gaussian_corrections(y * totalMean / sigmaSquared)

assert 0.0 <= w < 1.0, \
"w should be bounded in [0, 1] - %s, %s, %s, %s, %s" % \
(totalMean, sigmaSquared, surprise, v, w)
total_mean, total_variance = self._active_mean_variance(features)
v, w = util.gaussian_corrections(y * total_mean / total_variance)

for feature in features:
weight = self._get_weight(feature)
assert 0.0 < weight.variance / sigmaSquared < 1.0

mean_delta = y * weight.variance / np.sqrt(sigmaSquared) * v
variance_multiplier = 1.0 - weight.variance / sigmaSquared * w
update = pb.Gaussian(
mean_delta = y * weight.variance / np.sqrt(total_variance) * v
variance_multiplier = 1.0 - weight.variance / total_variance * w
updated = pb.Gaussian(
mean=weight.mean + mean_delta,
variance=weight.variance * variance_multiplier)

self._set_weight(feature, self._apply_dynamics(update))
self._set_weight(feature, self._apply_dynamics(updated))

def _total_variance(self, features):
sigmaSquared = self._config.beta ** 2
for feature in features:
weight = self._get_weight(feature)
sigmaSquared += weight.variance
return sigmaSquared
def _active_mean_variance(self, features):
means = (self._get_weight(f).mean for f in features)
variances = (self._get_weight(f).variance for f in features)
return sum(means), sum(variances) + self._config.beta ** 2

def _get_weight(self, feature):
return self._weights.get(
Expand All @@ -84,12 +69,10 @@ def _set_weight(self, feature, weight):
assert weight.variance >= 0.0
self._weights[util.serialize_feature(feature)] = weight

def _total_mean(self, features):
meanSum = 0
for feature in features:
weight = self._get_weight(feature)
meanSum += weight.mean
return meanSum
@property
def weights(self):
return [(util.deserialize_feature(f), w)
for (f, w) in self._weights.iteritems()]

def _apply_dynamics(self, weight):
prior = util.prior_weight()
Expand Down

0 comments on commit 639d20b

Please sign in to comment.