class EWACalibratedForecaster(Forecaster):
  """Produces calibrated estimates by minimizng internal regret"""
  def __init__(self, N, eta=None):
    super(EWACalibratedForecaster, self).__init__(N+1)
    self.F_int = EWAInternalForecaster(N+1, eta)
    self.e = np.array([float(i)/N for i in range(N+1)])
    self.examples_seen = 0

  def predict(self):
    w = self.F_int.weights.reshape(self.N,)
    ind = np.random.multinomial(1, w)
    return ind.dot(self.e)

  def expected_prediction(self):
    w = self.F_int.weights.reshape(self.N,)
    return w.T.dot(self.e)

  def observe(self, y_t):
    l = np.array([(y_t - e)**2 for e in self.e])
    self.F_int.observe(l)
    self.examples_seen += 1

  @property
  def weights(self):
    return self.F_int.weights
class EWACalibratedForecaster(Forecaster):
  """Produces calibrated estimates by minimizng internal regret"""
  def __init__(self, N, eta=None):
    super(EWACalibratedForecaster, self).__init__(N+1)
    self.F_int = EWAInternalForecaster(N+1, eta)
    self.e = np.array([float(i)/N for i in xrange(N+1)])
    self.examples_seen = 0

  def predict(self):
    w = self.F_int.weights.reshape(self.N,)
    ind = np.random.multinomial(1, w)
    return ind.dot(self.e)

  def expected_prediction(self):
    w = self.F_int.weights.reshape(self.N,)
    return w.T.dot(self.e)

  def observe(self, y_t):
    l = np.array([(y_t - e)**2 for e in self.e])
    self.F_int.observe(l)
    self.examples_seen += 1

  @property
  def weights(self):
    return self.F_int.weights
 def __init__(self, N, eta=None):
   super(EWACalibratedForecaster, self).__init__(N+1)
   self.F_int = EWAInternalForecaster(N+1, eta)
   self.e = np.array([float(i)/N for i in range(N+1)])
   self.examples_seen = 0
 def __init__(self, N, eta=None):
   super(EWACalibratedForecaster, self).__init__(N+1)
   self.F_int = EWAInternalForecaster(N+1, eta)
   self.e = np.array([float(i)/N for i in xrange(N+1)])
   self.examples_seen = 0