diff options
| -rw-r--r-- | gi/pf/align-lexonly-pyp.cc | 2 | ||||
| -rw-r--r-- | gi/pf/align-lexonly.cc | 2 | ||||
| -rw-r--r-- | gi/pf/brat.cc | 2 | ||||
| -rw-r--r-- | gi/pf/conditional_pseg.h | 4 | ||||
| -rw-r--r-- | gi/pf/learn_cfg.cc | 4 | ||||
| -rw-r--r-- | gi/pf/pfbrat.cc | 2 | ||||
| -rw-r--r-- | gi/pf/pyp_lm.cc | 70 | ||||
| -rw-r--r-- | phrasinator/gibbs_train_plm.cc | 2 | ||||
| -rw-r--r-- | utils/ccrp.h | 95 | ||||
| -rw-r--r-- | utils/ccrp_nt.h | 52 | ||||
| -rw-r--r-- | utils/ccrp_onetable.h | 70 | ||||
| -rw-r--r-- | utils/mfcr.h | 58 | 
12 files changed, 203 insertions, 160 deletions
diff --git a/gi/pf/align-lexonly-pyp.cc b/gi/pf/align-lexonly-pyp.cc index e24cb457..4ce7cf62 100644 --- a/gi/pf/align-lexonly-pyp.cc +++ b/gi/pf/align-lexonly-pyp.cc @@ -104,7 +104,7 @@ struct HierarchicalWordBase {    }    void Summary() const { -    cerr << "NUMBER OF CUSTOMERS: " << r.num_customers() << "  (d=" << r.d() << ",\\alpha=" << r.alpha() << ')' << endl; +    cerr << "NUMBER OF CUSTOMERS: " << r.num_customers() << "  (d=" << r.discount() << ",\\alpha=" << r.alpha() << ')' << endl;      for (MFCR<vector<WordID> >::const_iterator it = r.begin(); it != r.end(); ++it)        cerr << "   " << it->second.total_dish_count_ << " (on " << it->second.table_counts_.size() << " tables)" << TD::GetString(it->first) << endl;    } diff --git a/gi/pf/align-lexonly.cc b/gi/pf/align-lexonly.cc index 8c1d689f..dbc9dc07 100644 --- a/gi/pf/align-lexonly.cc +++ b/gi/pf/align-lexonly.cc @@ -105,7 +105,7 @@ struct HierarchicalWordBase {    }    void Summary() const { -    cerr << "NUMBER OF CUSTOMERS: " << r.num_customers() << "  (\\alpha=" << r.concentration() << ')' << endl; +    cerr << "NUMBER OF CUSTOMERS: " << r.num_customers() << "  (\\alpha=" << r.alpha() << ')' << endl;      for (CCRP_NoTable<vector<WordID> >::const_iterator it = r.begin(); it != r.end(); ++it)        cerr << "   " << it->second << '\t' << TD::GetString(it->first) << endl;    } diff --git a/gi/pf/brat.cc b/gi/pf/brat.cc index 7b60ef23..c2c52760 100644 --- a/gi/pf/brat.cc +++ b/gi/pf/brat.cc @@ -191,7 +191,7 @@ struct UniphraseLM {    void ResampleHyperparameters(MT19937* rng) {      phrases_.resample_hyperparameters(rng);      gen_.resample_hyperparameters(rng); -    cerr << " " << phrases_.concentration(); +    cerr << " " << phrases_.alpha();    }    CCRP_NoTable<vector<int> > phrases_; diff --git a/gi/pf/conditional_pseg.h b/gi/pf/conditional_pseg.h index 2e9e38fc..f9841cbf 100644 --- a/gi/pf/conditional_pseg.h +++ b/gi/pf/conditional_pseg.h @@ -22,7 +22,7 @@ struct MConditionalTranslationModel {    void Summary() const {      std::cerr << "Number of conditioning contexts: " << r.size() << std::endl;      for (RuleModelHash::const_iterator it = r.begin(); it != r.end(); ++it) { -      std::cerr << TD::GetString(it->first) << "   \t(d=" << it->second.d() << ",\\alpha = " << it->second.alpha() << ") --------------------------" << std::endl; +      std::cerr << TD::GetString(it->first) << "   \t(d=" << it->second.discount() << ",\\alpha = " << it->second.alpha() << ") --------------------------" << std::endl;        for (MFCR<TRule>::const_iterator i2 = it->second.begin(); i2 != it->second.end(); ++i2)          std::cerr << "   " << -1 << '\t' << i2->first << std::endl;      } @@ -95,7 +95,7 @@ struct ConditionalTranslationModel {    void Summary() const {      std::cerr << "Number of conditioning contexts: " << r.size() << std::endl;      for (RuleModelHash::const_iterator it = r.begin(); it != r.end(); ++it) { -      std::cerr << TD::GetString(it->first) << "   \t(\\alpha = " << it->second.concentration() << ") --------------------------" << std::endl; +      std::cerr << TD::GetString(it->first) << "   \t(\\alpha = " << it->second.alpha() << ") --------------------------" << std::endl;        for (CCRP_NoTable<TRule>::const_iterator i2 = it->second.begin(); i2 != it->second.end(); ++i2)          std::cerr << "   " << i2->second << '\t' << i2->first << std::endl;      } diff --git a/gi/pf/learn_cfg.cc b/gi/pf/learn_cfg.cc index b2ca029a..5b748311 100644 --- a/gi/pf/learn_cfg.cc +++ b/gi/pf/learn_cfg.cc @@ -183,9 +183,9 @@ struct HieroLMModel {        nts[i].resample_hyperparameters(rng);      if (kHIERARCHICAL_PRIOR) {        q0.resample_hyperparameters(rng); -      cerr << "[base d=" << q0.discount() << ", alpha=" << q0.discount() << "]"; +      cerr << "[base d=" << q0.discount() << ", alpha=" << q0.alpha() << "]";      } -    cerr << " d=" << nts[0].discount() << ", alpha=" << nts[0].concentration() << endl; +    cerr << " d=" << nts[0].discount() << ", alpha=" << nts[0].alpha() << endl;    }    const BaseRuleModel base; diff --git a/gi/pf/pfbrat.cc b/gi/pf/pfbrat.cc index 7b60ef23..c2c52760 100644 --- a/gi/pf/pfbrat.cc +++ b/gi/pf/pfbrat.cc @@ -191,7 +191,7 @@ struct UniphraseLM {    void ResampleHyperparameters(MT19937* rng) {      phrases_.resample_hyperparameters(rng);      gen_.resample_hyperparameters(rng); -    cerr << " " << phrases_.concentration(); +    cerr << " " << phrases_.alpha();    }    CCRP_NoTable<vector<int> > phrases_; diff --git a/gi/pf/pyp_lm.cc b/gi/pf/pyp_lm.cc index 2837e33c..0d85536c 100644 --- a/gi/pf/pyp_lm.cc +++ b/gi/pf/pyp_lm.cc @@ -50,16 +50,19 @@ template <unsigned N> struct PYPLM;  // uniform base distribution  template<> struct PYPLM<0> { -  PYPLM(unsigned vs) : p0(1.0 / vs) {} -  void increment(WordID w, const vector<WordID>& context, MT19937* rng) const {} -  void decrement(WordID w, const vector<WordID>& context, MT19937* rng) const {} +  PYPLM(unsigned vs) : p0(1.0 / vs), draws() {} +  void increment(WordID w, const vector<WordID>& context, MT19937* rng) { ++draws; } +  void decrement(WordID w, const vector<WordID>& context, MT19937* rng) { --draws; assert(draws >= 0); }    double prob(WordID w, const vector<WordID>& context) const { return p0; } +  void resample_hyperparameters(MT19937* rng, const unsigned nloop, const unsigned niterations) {} +  double log_likelihood() const { return draws * log(p0); }    const double p0; +  int draws;  };  // represents an N-gram LM  template <unsigned N> struct PYPLM { -  PYPLM(unsigned vs) : backoff(vs) {} +  PYPLM(unsigned vs) : backoff(vs), d(0.8), alpha(1.0) {}    void increment(WordID w, const vector<WordID>& context, MT19937* rng) {      const double bo = backoff.prob(w, context);      static vector<WordID> lookup(N-1); @@ -67,7 +70,7 @@ template <unsigned N> struct PYPLM {        lookup[i] = context[context.size() - 1 - i];      typename unordered_map<vector<WordID>, CCRP<WordID>, boost::hash<vector<WordID> > >::iterator it = p.find(lookup);      if (it == p.end()) -      it = p.insert(make_pair(lookup, CCRP<WordID>(1,1,1,1))).first; +      it = p.insert(make_pair(lookup, CCRP<WordID>(d,alpha))).first;      if (it->second.increment(w, bo, rng))        backoff.increment(w, context, rng);    } @@ -89,7 +92,58 @@ template <unsigned N> struct PYPLM {      if (it == p.end()) return bo;      return it->second.prob(w, bo);    } + +  double log_likelihood() const { +    return log_likelihood(d, alpha) + backoff.log_likelihood(); +  } + +  double log_likelihood(const double& dd, const double& aa) const { +    if (aa <= -dd) return -std::numeric_limits<double>::infinity(); +    double llh = Md::log_beta_density(dd, 1, 1) + Md::log_gamma_density(aa, 1, 1); +    typename unordered_map<vector<WordID>, CCRP<WordID>, boost::hash<vector<WordID> > >::const_iterator it; +    for (it = p.begin(); it != p.end(); ++it) +      llh += it->second.log_crp_prob(dd, aa); +    return llh; +  } + +  struct DiscountResampler { +    DiscountResampler(const PYPLM& m) : m_(m) {} +    const PYPLM& m_; +    double operator()(const double& proposed_discount) const { +      return m_.log_likelihood(proposed_discount, m_.alpha); +    } +  }; + +  struct AlphaResampler { +    AlphaResampler(const PYPLM& m) : m_(m) {} +    const PYPLM& m_; +    double operator()(const double& proposed_alpha) const { +      return m_.log_likelihood(m_.d, proposed_alpha); +    } +  }; + +  void resample_hyperparameters(MT19937* rng, const unsigned nloop = 5, const unsigned niterations = 10) { +    DiscountResampler dr(*this); +    AlphaResampler ar(*this); +    for (int iter = 0; iter < nloop; ++iter) { +      alpha = slice_sampler1d(ar, alpha, *rng, 0.0, +                              std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations); +      d = slice_sampler1d(dr, d, *rng, std::numeric_limits<double>::min(), +                          1.0, 0.0, niterations, 100*niterations); +    } +    alpha = slice_sampler1d(ar, alpha, *rng, 0.0, +                            std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations); +    typename unordered_map<vector<WordID>, CCRP<WordID>, boost::hash<vector<WordID> > >::iterator it; +    cerr << "PYPLM<" << N << ">(d=" << d << ",a=" << alpha << ") = " << log_likelihood(d, alpha) << endl; +    for (it = p.begin(); it != p.end(); ++it) { +      it->second.set_discount(d); +      it->second.set_alpha(alpha); +    } +    backoff.resample_hyperparameters(rng, nloop, niterations); +  } +    PYPLM<N-1> backoff; +  double d, alpha;    unordered_map<vector<WordID>, CCRP<WordID>, boost::hash<vector<WordID> > > p;  }; @@ -109,7 +163,7 @@ int main(int argc, char** argv) {    cerr << "Reading corpus...\n";    CorpusTools::ReadFromFile(conf["input"].as<string>(), &corpuse, &vocabe);    cerr << "E-corpus size: " << corpuse.size() << " sentences\t (" << vocabe.size() << " word types)\n"; -#define kORDER 5 +#define kORDER 3    PYPLM<kORDER> lm(vocabe.size());    vector<WordID> ctx(kORDER - 1, TD::Convert("<s>"));    int mci = corpuse.size() * 99 / 100; @@ -126,6 +180,10 @@ int main(int argc, char** argv) {        if (SS > 0) lm.decrement(kEOS, ctx, &rng);        lm.increment(kEOS, ctx, &rng);      } +    if (SS % 10 == 9) { +      cerr << " [LLH=" << lm.log_likelihood() << "]" << endl; +      if (SS % 20 == 19) lm.resample_hyperparameters(&rng); +    } else { cerr << '.' << flush; }    }    double llh = 0;    unsigned cnt = 0; diff --git a/phrasinator/gibbs_train_plm.cc b/phrasinator/gibbs_train_plm.cc index 66b46011..54861dcb 100644 --- a/phrasinator/gibbs_train_plm.cc +++ b/phrasinator/gibbs_train_plm.cc @@ -252,7 +252,7 @@ struct UniphraseLM {    void ResampleHyperparameters(MT19937* rng) {      phrases_.resample_hyperparameters(rng);      gen_.resample_hyperparameters(rng); -    cerr << " d=" << phrases_.discount() << ",c=" << phrases_.concentration(); +    cerr << " d=" << phrases_.discount() << ",a=" << phrases_.alpha();    }    CCRP<vector<int> > phrases_; diff --git a/utils/ccrp.h b/utils/ccrp.h index 1a9e3ed5..d9a38089 100644 --- a/utils/ccrp.h +++ b/utils/ccrp.h @@ -17,35 +17,37 @@  template <typename Dish, typename DishHash = boost::hash<Dish> >  class CCRP {   public: -  CCRP(double disc, double conc) : +  CCRP(double disc, double alpha) :      num_tables_(),      num_customers_(),      discount_(disc), -    concentration_(conc), +    alpha_(alpha),      discount_prior_alpha_(std::numeric_limits<double>::quiet_NaN()),      discount_prior_beta_(std::numeric_limits<double>::quiet_NaN()), -    concentration_prior_shape_(std::numeric_limits<double>::quiet_NaN()), -    concentration_prior_rate_(std::numeric_limits<double>::quiet_NaN()) {} +    alpha_prior_shape_(std::numeric_limits<double>::quiet_NaN()), +    alpha_prior_rate_(std::numeric_limits<double>::quiet_NaN()) {}    CCRP(double d_alpha, double d_beta, double c_shape, double c_rate, double d = 0.9, double c = 1.0) :      num_tables_(),      num_customers_(),      discount_(d), -    concentration_(c), +    alpha_(c),      discount_prior_alpha_(d_alpha),      discount_prior_beta_(d_beta), -    concentration_prior_shape_(c_shape), -    concentration_prior_rate_(c_rate) {} +    alpha_prior_shape_(c_shape), +    alpha_prior_rate_(c_rate) {}    double discount() const { return discount_; } -  double concentration() const { return concentration_; } +  double alpha() const { return alpha_; } +  void set_discount(double d) { discount_ = d; } +  void set_alpha(double a) { alpha_ = a; }    bool has_discount_prior() const {      return !std::isnan(discount_prior_alpha_);    } -  bool has_concentration_prior() const { -    return !std::isnan(concentration_prior_shape_); +  bool has_alpha_prior() const { +    return !std::isnan(alpha_prior_shape_);    }    void clear() { @@ -79,7 +81,7 @@ class CCRP {      DishLocations& loc = dish_locs_[dish];      bool share_table = false;      if (loc.total_dish_count_) { -      const double p_empty = (concentration_ + num_tables_ * discount_) * p0; +      const double p_empty = (alpha_ + num_tables_ * discount_) * p0;        const double p_share = (loc.total_dish_count_ - loc.table_counts_.size() * discount_);        share_table = rng->SelectSample(p_empty, p_share);      } @@ -113,7 +115,7 @@ class CCRP {      DishLocations& loc = dish_locs_[dish];      bool share_table = false;      if (loc.total_dish_count_) { -      const T p_empty = T(concentration_ + num_tables_ * discount_) * p0; +      const T p_empty = T(alpha_ + num_tables_ * discount_) * p0;        const T p_share = T(loc.total_dish_count_ - loc.table_counts_.size() * discount_);        share_table = rng->SelectSample(p_empty, p_share);      } @@ -180,63 +182,46 @@ class CCRP {    double prob(const Dish& dish, const double& p0) const {      const typename std::tr1::unordered_map<Dish, DishLocations, DishHash>::const_iterator it = dish_locs_.find(dish); -    const double r = num_tables_ * discount_ + concentration_; +    const double r = num_tables_ * discount_ + alpha_;      if (it == dish_locs_.end()) { -      return r * p0 / (num_customers_ + concentration_); +      return r * p0 / (num_customers_ + alpha_);      } else {        return (it->second.total_dish_count_ - discount_ * it->second.table_counts_.size() + r * p0) / -               (num_customers_ + concentration_); +               (num_customers_ + alpha_);      }    }    template <typename T>    T probT(const Dish& dish, const T& p0) const {      const typename std::tr1::unordered_map<Dish, DishLocations, DishHash>::const_iterator it = dish_locs_.find(dish); -    const T r = T(num_tables_ * discount_ + concentration_); +    const T r = T(num_tables_ * discount_ + alpha_);      if (it == dish_locs_.end()) { -      return r * p0 / T(num_customers_ + concentration_); +      return r * p0 / T(num_customers_ + alpha_);      } else {        return (T(it->second.total_dish_count_ - discount_ * it->second.table_counts_.size()) + r * p0) / -               T(num_customers_ + concentration_); +               T(num_customers_ + alpha_);      }    }    double log_crp_prob() const { -    return log_crp_prob(discount_, concentration_); -  } - -  static double log_beta_density(const double& x, const double& alpha, const double& beta) { -    assert(x > 0.0); -    assert(x < 1.0); -    assert(alpha > 0.0); -    assert(beta > 0.0); -    const double lp = (alpha-1)*log(x)+(beta-1)*log(1-x)+lgamma(alpha+beta)-lgamma(alpha)-lgamma(beta); -    return lp; -  } - -  static double log_gamma_density(const double& x, const double& shape, const double& rate) { -    assert(x >= 0.0); -    assert(shape > 0.0); -    assert(rate > 0.0); -    const double lp = (shape-1)*log(x) - shape*log(rate) - x/rate - lgamma(shape); -    return lp; +    return log_crp_prob(discount_, alpha_);    }    // taken from http://en.wikipedia.org/wiki/Chinese_restaurant_process    // does not include P_0's -  double log_crp_prob(const double& discount, const double& concentration) const { +  double log_crp_prob(const double& discount, const double& alpha) const {      double lp = 0.0;      if (has_discount_prior()) -      lp = log_beta_density(discount, discount_prior_alpha_, discount_prior_beta_); -    if (has_concentration_prior()) -      lp += log_gamma_density(concentration, concentration_prior_shape_, concentration_prior_rate_); +      lp = Md::log_beta_density(discount, discount_prior_alpha_, discount_prior_beta_); +    if (has_alpha_prior()) +      lp += Md::log_gamma_density(alpha, alpha_prior_shape_, alpha_prior_rate_);      assert(lp <= 0.0);      if (num_customers_) {        if (discount > 0.0) {          const double r = lgamma(1.0 - discount); -        lp += lgamma(concentration) - lgamma(concentration + num_customers_) -             + num_tables_ * log(discount) + lgamma(concentration / discount + num_tables_) -             - lgamma(concentration / discount); +        lp += lgamma(alpha) - lgamma(alpha + num_customers_) +             + num_tables_ * log(discount) + lgamma(alpha / discount + num_tables_) +             - lgamma(alpha / discount);          assert(std::isfinite(lp));          for (typename std::tr1::unordered_map<Dish, DishLocations, DishHash>::const_iterator it = dish_locs_.begin();               it != dish_locs_.end(); ++it) { @@ -254,12 +239,12 @@ class CCRP {    }    void resample_hyperparameters(MT19937* rng, const unsigned nloop = 5, const unsigned niterations = 10) { -    assert(has_discount_prior() || has_concentration_prior()); +    assert(has_discount_prior() || has_alpha_prior());      DiscountResampler dr(*this);      ConcentrationResampler cr(*this);      for (int iter = 0; iter < nloop; ++iter) { -      if (has_concentration_prior()) { -        concentration_ = slice_sampler1d(cr, concentration_, *rng, 0.0, +      if (has_alpha_prior()) { +        alpha_ = slice_sampler1d(cr, alpha_, *rng, 0.0,                                 std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations);        }        if (has_discount_prior()) { @@ -267,7 +252,7 @@ class CCRP {                                 1.0, 0.0, niterations, 100*niterations);        }      } -    concentration_ = slice_sampler1d(cr, concentration_, *rng, 0.0, +    alpha_ = slice_sampler1d(cr, alpha_, *rng, 0.0,                               std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations);    } @@ -275,15 +260,15 @@ class CCRP {      DiscountResampler(const CCRP& crp) : crp_(crp) {}      const CCRP& crp_;      double operator()(const double& proposed_discount) const { -      return crp_.log_crp_prob(proposed_discount, crp_.concentration_); +      return crp_.log_crp_prob(proposed_discount, crp_.alpha_);      }    };    struct ConcentrationResampler {      ConcentrationResampler(const CCRP& crp) : crp_(crp) {}      const CCRP& crp_; -    double operator()(const double& proposed_concentration) const { -      return crp_.log_crp_prob(crp_.discount_, proposed_concentration); +    double operator()(const double& proposed_alpha) const { +      return crp_.log_crp_prob(crp_.discount_, proposed_alpha);      }    }; @@ -295,7 +280,7 @@ class CCRP {    };    void Print(std::ostream* out) const { -    std::cerr << "PYP(d=" << discount_ << ",c=" << concentration_ << ") customers=" << num_customers_ << std::endl; +    std::cerr << "PYP(d=" << discount_ << ",c=" << alpha_ << ") customers=" << num_customers_ << std::endl;      for (typename std::tr1::unordered_map<Dish, DishLocations, DishHash>::const_iterator it = dish_locs_.begin();           it != dish_locs_.end(); ++it) {        (*out) << it->first << " (" << it->second.total_dish_count_ << " on " << it->second.table_counts_.size() << " tables): "; @@ -320,15 +305,15 @@ class CCRP {    std::tr1::unordered_map<Dish, DishLocations, DishHash> dish_locs_;    double discount_; -  double concentration_; +  double alpha_;    // optional beta prior on discount_ (NaN if no prior)    double discount_prior_alpha_;    double discount_prior_beta_; -  // optional gamma prior on concentration_ (NaN if no prior) -  double concentration_prior_shape_; -  double concentration_prior_rate_; +  // optional gamma prior on alpha_ (NaN if no prior) +  double alpha_prior_shape_; +  double alpha_prior_rate_;  };  template <typename T,typename H> diff --git a/utils/ccrp_nt.h b/utils/ccrp_nt.h index 63b6f4c2..79321493 100644 --- a/utils/ccrp_nt.h +++ b/utils/ccrp_nt.h @@ -18,20 +18,20 @@ class CCRP_NoTable {   public:    explicit CCRP_NoTable(double conc) :      num_customers_(), -    concentration_(conc), -    concentration_prior_shape_(std::numeric_limits<double>::quiet_NaN()), -    concentration_prior_rate_(std::numeric_limits<double>::quiet_NaN()) {} +    alpha_(conc), +    alpha_prior_shape_(std::numeric_limits<double>::quiet_NaN()), +    alpha_prior_rate_(std::numeric_limits<double>::quiet_NaN()) {}    CCRP_NoTable(double c_shape, double c_rate, double c = 10.0) :      num_customers_(), -    concentration_(c), -    concentration_prior_shape_(c_shape), -    concentration_prior_rate_(c_rate) {} +    alpha_(c), +    alpha_prior_shape_(c_shape), +    alpha_prior_rate_(c_rate) {} -  double concentration() const { return concentration_; } +  double alpha() const { return alpha_; } -  bool has_concentration_prior() const { -    return !std::isnan(concentration_prior_shape_); +  bool has_alpha_prior() const { +    return !std::isnan(alpha_prior_shape_);    }    void clear() { @@ -73,16 +73,16 @@ class CCRP_NoTable {    double prob(const Dish& dish, const double& p0) const {      const unsigned at_table = num_customers(dish); -    return (at_table + p0 * concentration_) / (num_customers_ + concentration_); +    return (at_table + p0 * alpha_) / (num_customers_ + alpha_);    }    double logprob(const Dish& dish, const double& logp0) const {      const unsigned at_table = num_customers(dish); -    return log(at_table + exp(logp0 + log(concentration_))) - log(num_customers_ + concentration_); +    return log(at_table + exp(logp0 + log(alpha_))) - log(num_customers_ + alpha_);    }    double log_crp_prob() const { -    return log_crp_prob(concentration_); +    return log_crp_prob(alpha_);    }    static double log_gamma_density(const double& x, const double& shape, const double& rate) { @@ -95,14 +95,14 @@ class CCRP_NoTable {    // taken from http://en.wikipedia.org/wiki/Chinese_restaurant_process    // does not include P_0's -  double log_crp_prob(const double& concentration) const { +  double log_crp_prob(const double& alpha) const {      double lp = 0.0; -    if (has_concentration_prior()) -      lp += log_gamma_density(concentration, concentration_prior_shape_, concentration_prior_rate_); +    if (has_alpha_prior()) +      lp += log_gamma_density(alpha, alpha_prior_shape_, alpha_prior_rate_);      assert(lp <= 0.0);      if (num_customers_) { -      lp += lgamma(concentration) - lgamma(concentration + num_customers_) + -        custs_.size() * log(concentration); +      lp += lgamma(alpha) - lgamma(alpha + num_customers_) + +        custs_.size() * log(alpha);        assert(std::isfinite(lp));        for (typename std::tr1::unordered_map<Dish, unsigned, DishHash>::const_iterator it = custs_.begin();               it != custs_.end(); ++it) { @@ -114,10 +114,10 @@ class CCRP_NoTable {    }    void resample_hyperparameters(MT19937* rng, const unsigned nloop = 5, const unsigned niterations = 10) { -    assert(has_concentration_prior()); +    assert(has_alpha_prior());      ConcentrationResampler cr(*this);      for (int iter = 0; iter < nloop; ++iter) { -        concentration_ = slice_sampler1d(cr, concentration_, *rng, 0.0, +        alpha_ = slice_sampler1d(cr, alpha_, *rng, 0.0,                                 std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations);      }    } @@ -125,13 +125,13 @@ class CCRP_NoTable {    struct ConcentrationResampler {      ConcentrationResampler(const CCRP_NoTable& crp) : crp_(crp) {}      const CCRP_NoTable& crp_; -    double operator()(const double& proposed_concentration) const { -      return crp_.log_crp_prob(proposed_concentration); +    double operator()(const double& proposed_alpha) const { +      return crp_.log_crp_prob(proposed_alpha);      }    };    void Print(std::ostream* out) const { -    (*out) << "DP(alpha=" << concentration_ << ") customers=" << num_customers_ << std::endl; +    (*out) << "DP(alpha=" << alpha_ << ") customers=" << num_customers_ << std::endl;      int cc = 0;      for (typename std::tr1::unordered_map<Dish, unsigned, DishHash>::const_iterator it = custs_.begin();           it != custs_.end(); ++it) { @@ -153,11 +153,11 @@ class CCRP_NoTable {      return custs_.end();    } -  double concentration_; +  double alpha_; -  // optional gamma prior on concentration_ (NaN if no prior) -  double concentration_prior_shape_; -  double concentration_prior_rate_; +  // optional gamma prior on alpha_ (NaN if no prior) +  double alpha_prior_shape_; +  double alpha_prior_rate_;  };  template <typename T,typename H> diff --git a/utils/ccrp_onetable.h b/utils/ccrp_onetable.h index b63737d1..1fe01b0e 100644 --- a/utils/ccrp_onetable.h +++ b/utils/ccrp_onetable.h @@ -21,33 +21,33 @@ class CCRP_OneTable {      num_tables_(),      num_customers_(),      discount_(disc), -    concentration_(conc), +    alpha_(conc),      discount_prior_alpha_(std::numeric_limits<double>::quiet_NaN()),      discount_prior_beta_(std::numeric_limits<double>::quiet_NaN()), -    concentration_prior_shape_(std::numeric_limits<double>::quiet_NaN()), -    concentration_prior_rate_(std::numeric_limits<double>::quiet_NaN()) {} +    alpha_prior_shape_(std::numeric_limits<double>::quiet_NaN()), +    alpha_prior_rate_(std::numeric_limits<double>::quiet_NaN()) {}    CCRP_OneTable(double d_alpha, double d_beta, double c_shape, double c_rate, double d = 0.9, double c = 1.0) :      num_tables_(),      num_customers_(),      discount_(d), -    concentration_(c), +    alpha_(c),      discount_prior_alpha_(d_alpha),      discount_prior_beta_(d_beta), -    concentration_prior_shape_(c_shape), -    concentration_prior_rate_(c_rate) {} +    alpha_prior_shape_(c_shape), +    alpha_prior_rate_(c_rate) {}    double discount() const { return discount_; } -  double concentration() const { return concentration_; } -  void set_concentration(double c) { concentration_ = c; } +  double alpha() const { return alpha_; } +  void set_alpha(double c) { alpha_ = c; }    void set_discount(double d) { discount_ = d; }    bool has_discount_prior() const {      return !std::isnan(discount_prior_alpha_);    } -  bool has_concentration_prior() const { -    return !std::isnan(concentration_prior_shape_); +  bool has_alpha_prior() const { +    return !std::isnan(alpha_prior_shape_);    }    void clear() { @@ -108,29 +108,29 @@ class CCRP_OneTable {    double prob(const Dish& dish, const double& p0) const {      const typename DishMapType::const_iterator it = dish_counts_.find(dish); -    const double r = num_tables_ * discount_ + concentration_; +    const double r = num_tables_ * discount_ + alpha_;      if (it == dish_counts_.end()) { -      return r * p0 / (num_customers_ + concentration_); +      return r * p0 / (num_customers_ + alpha_);      } else {        return (it->second - discount_ + r * p0) / -               (num_customers_ + concentration_); +               (num_customers_ + alpha_);      }    }    template <typename T>    T probT(const Dish& dish, const T& p0) const {      const typename DishMapType::const_iterator it = dish_counts_.find(dish); -    const T r(num_tables_ * discount_ + concentration_); +    const T r(num_tables_ * discount_ + alpha_);      if (it == dish_counts_.end()) { -      return r * p0 / T(num_customers_ + concentration_); +      return r * p0 / T(num_customers_ + alpha_);      } else {        return (T(it->second - discount_) + r * p0) / -               T(num_customers_ + concentration_); +               T(num_customers_ + alpha_);      }    }    double log_crp_prob() const { -    return log_crp_prob(discount_, concentration_); +    return log_crp_prob(discount_, alpha_);    }    static double log_beta_density(const double& x, const double& alpha, const double& beta) { @@ -152,19 +152,19 @@ class CCRP_OneTable {    // taken from http://en.wikipedia.org/wiki/Chinese_restaurant_process    // does not include P_0's -  double log_crp_prob(const double& discount, const double& concentration) const { +  double log_crp_prob(const double& discount, const double& alpha) const {      double lp = 0.0;      if (has_discount_prior())        lp = log_beta_density(discount, discount_prior_alpha_, discount_prior_beta_); -    if (has_concentration_prior()) -      lp += log_gamma_density(concentration, concentration_prior_shape_, concentration_prior_rate_); +    if (has_alpha_prior()) +      lp += log_gamma_density(alpha, alpha_prior_shape_, alpha_prior_rate_);      assert(lp <= 0.0);      if (num_customers_) {        if (discount > 0.0) {          const double r = lgamma(1.0 - discount); -        lp += lgamma(concentration) - lgamma(concentration + num_customers_) -             + num_tables_ * log(discount) + lgamma(concentration / discount + num_tables_) -             - lgamma(concentration / discount); +        lp += lgamma(alpha) - lgamma(alpha + num_customers_) +             + num_tables_ * log(discount) + lgamma(alpha / discount + num_tables_) +             - lgamma(alpha / discount);          assert(std::isfinite(lp));          for (typename DishMapType::const_iterator it = dish_counts_.begin();               it != dish_counts_.end(); ++it) { @@ -180,12 +180,12 @@ class CCRP_OneTable {    }    void resample_hyperparameters(MT19937* rng, const unsigned nloop = 5, const unsigned niterations = 10) { -    assert(has_discount_prior() || has_concentration_prior()); +    assert(has_discount_prior() || has_alpha_prior());      DiscountResampler dr(*this);      ConcentrationResampler cr(*this);      for (int iter = 0; iter < nloop; ++iter) { -      if (has_concentration_prior()) { -        concentration_ = slice_sampler1d(cr, concentration_, *rng, 0.0, +      if (has_alpha_prior()) { +        alpha_ = slice_sampler1d(cr, alpha_, *rng, 0.0,                                 std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations);        }        if (has_discount_prior()) { @@ -193,7 +193,7 @@ class CCRP_OneTable {                                 1.0, 0.0, niterations, 100*niterations);        }      } -    concentration_ = slice_sampler1d(cr, concentration_, *rng, 0.0, +    alpha_ = slice_sampler1d(cr, alpha_, *rng, 0.0,                               std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations);    } @@ -201,20 +201,20 @@ class CCRP_OneTable {      DiscountResampler(const CCRP_OneTable& crp) : crp_(crp) {}      const CCRP_OneTable& crp_;      double operator()(const double& proposed_discount) const { -      return crp_.log_crp_prob(proposed_discount, crp_.concentration_); +      return crp_.log_crp_prob(proposed_discount, crp_.alpha_);      }    };    struct ConcentrationResampler {      ConcentrationResampler(const CCRP_OneTable& crp) : crp_(crp) {}      const CCRP_OneTable& crp_; -    double operator()(const double& proposed_concentration) const { -      return crp_.log_crp_prob(crp_.discount_, proposed_concentration); +    double operator()(const double& proposed_alpha) const { +      return crp_.log_crp_prob(crp_.discount_, proposed_alpha);      }    };    void Print(std::ostream* out) const { -    (*out) << "PYP(d=" << discount_ << ",c=" << concentration_ << ") customers=" << num_customers_ << std::endl; +    (*out) << "PYP(d=" << discount_ << ",c=" << alpha_ << ") customers=" << num_customers_ << std::endl;      for (typename DishMapType::const_iterator it = dish_counts_.begin(); it != dish_counts_.end(); ++it) {        (*out) << "  " << it->first << " = " << it->second << std::endl;      } @@ -233,15 +233,15 @@ class CCRP_OneTable {    DishMapType dish_counts_;    double discount_; -  double concentration_; +  double alpha_;    // optional beta prior on discount_ (NaN if no prior)    double discount_prior_alpha_;    double discount_prior_beta_; -  // optional gamma prior on concentration_ (NaN if no prior) -  double concentration_prior_shape_; -  double concentration_prior_rate_; +  // optional gamma prior on alpha_ (NaN if no prior) +  double alpha_prior_shape_; +  double alpha_prior_rate_;  };  template <typename T,typename H> diff --git a/utils/mfcr.h b/utils/mfcr.h index 396d0205..df988f51 100644 --- a/utils/mfcr.h +++ b/utils/mfcr.h @@ -43,29 +43,29 @@ class MFCR {      num_floors_(num_floors),      num_tables_(),      num_customers_(), -    d_(d), +    discount_(d),      alpha_(alpha), -    d_prior_alpha_(std::numeric_limits<double>::quiet_NaN()), -    d_prior_beta_(std::numeric_limits<double>::quiet_NaN()), +    discount_prior_alpha_(std::numeric_limits<double>::quiet_NaN()), +    discount_prior_beta_(std::numeric_limits<double>::quiet_NaN()),      alpha_prior_shape_(std::numeric_limits<double>::quiet_NaN()),      alpha_prior_rate_(std::numeric_limits<double>::quiet_NaN()) {} -  MFCR(unsigned num_floors, double d_alpha, double d_beta, double alpha_shape, double alpha_rate, double d = 0.9, double alpha = 10.0) : +  MFCR(unsigned num_floors, double discount_alpha, double discount_beta, double alpha_shape, double alpha_rate, double d = 0.9, double alpha = 10.0) :      num_floors_(num_floors),      num_tables_(),      num_customers_(), -    d_(d), +    discount_(d),      alpha_(alpha), -    d_prior_alpha_(d_alpha), -    d_prior_beta_(d_beta), +    discount_prior_alpha_(discount_alpha), +    discount_prior_beta_(discount_beta),      alpha_prior_shape_(alpha_shape),      alpha_prior_rate_(alpha_rate) {} -  double d() const { return d_; } +  double discount() const { return discount_; }    double alpha() const { return alpha_; } -  bool has_d_prior() const { -    return !std::isnan(d_prior_alpha_); +  bool has_discount_prior() const { +    return !std::isnan(discount_prior_alpha_);    }    bool has_alpha_prior() const { @@ -122,15 +122,15 @@ class MFCR {      int floor = -1;      bool share_table = false;      if (loc.total_dish_count_) { -      const double p_empty = (alpha_ + num_tables_ * d_) * marg_p0; -      const double p_share = (loc.total_dish_count_ - loc.table_counts_.size() * d_); +      const double p_empty = (alpha_ + num_tables_ * discount_) * marg_p0; +      const double p_share = (loc.total_dish_count_ - loc.table_counts_.size() * discount_);        share_table = rng->SelectSample(p_empty, p_share);      }      if (share_table) { -      double r = rng->next() * (loc.total_dish_count_ - loc.table_counts_.size() * d_); +      double r = rng->next() * (loc.total_dish_count_ - loc.table_counts_.size() * discount_);        for (typename std::list<TableCount>::iterator ti = loc.table_counts_.begin();             ti != loc.table_counts_.end(); ++ti) { -        r -= ti->count - d_; +        r -= ti->count - discount_;          if (r <= 0.0) {            ++ti->count;            floor = ti->floor; @@ -206,25 +206,25 @@ class MFCR {      const double marg_p0 = std::inner_product(p0s.begin(), p0s.end(), lambdas.begin(), 0.0);      assert(marg_p0 <= 1.0);      const typename std::tr1::unordered_map<Dish, DishLocations, DishHash>::const_iterator it = dish_locs_.find(dish); -    const double r = num_tables_ * d_ + alpha_; +    const double r = num_tables_ * discount_ + alpha_;      if (it == dish_locs_.end()) {        return r * marg_p0 / (num_customers_ + alpha_);      } else { -      return (it->second.total_dish_count_ - d_ * it->second.table_counts_.size() + r * marg_p0) / +      return (it->second.total_dish_count_ - discount_ * it->second.table_counts_.size() + r * marg_p0) /                 (num_customers_ + alpha_);      }    }    double log_crp_prob() const { -    return log_crp_prob(d_, alpha_); +    return log_crp_prob(discount_, alpha_);    }    // taken from http://en.wikipedia.org/wiki/Chinese_restaurant_process    // does not include draws from G_w's    double log_crp_prob(const double& d, const double& alpha) const {      double lp = 0.0; -    if (has_d_prior()) -      lp = Md::log_beta_density(d, d_prior_alpha_, d_prior_beta_); +    if (has_discount_prior()) +      lp = Md::log_beta_density(d, discount_prior_alpha_, discount_prior_beta_);      if (has_alpha_prior())        lp += Md::log_gamma_density(alpha, alpha_prior_shape_, alpha_prior_rate_);      assert(lp <= 0.0); @@ -251,7 +251,7 @@ class MFCR {    }    void resample_hyperparameters(MT19937* rng, const unsigned nloop = 5, const unsigned niterations = 10) { -    assert(has_d_prior() || has_alpha_prior()); +    assert(has_discount_prior() || has_alpha_prior());      DiscountResampler dr(*this);      ConcentrationResampler cr(*this);      for (int iter = 0; iter < nloop; ++iter) { @@ -259,8 +259,8 @@ class MFCR {          alpha_ = slice_sampler1d(cr, alpha_, *rng, 0.0,                                 std::numeric_limits<double>::infinity(), 0.0, niterations, 100*niterations);        } -      if (has_d_prior()) { -        d_ = slice_sampler1d(dr, d_, *rng, std::numeric_limits<double>::min(), +      if (has_discount_prior()) { +        discount_ = slice_sampler1d(dr, discount_, *rng, std::numeric_limits<double>::min(),                                 1.0, 0.0, niterations, 100*niterations);        }      } @@ -279,8 +279,8 @@ class MFCR {    struct ConcentrationResampler {      ConcentrationResampler(const MFCR& crp) : crp_(crp) {}      const MFCR& crp_; -    double operator()(const double& proposed_alpha) const { -      return crp_.log_crp_prob(crp_.d_, proposed_alpha); +    double operator()(const double& proposediscount_alpha) const { +      return crp_.log_crp_prob(crp_.discount_, proposediscount_alpha);      }    }; @@ -292,7 +292,7 @@ class MFCR {    };    void Print(std::ostream* out) const { -    (*out) << "MFCR(d=" << d_ << ",alpha=" << alpha_ << ") customers=" << num_customers_ << std::endl; +    (*out) << "MFCR(d=" << discount_ << ",alpha=" << alpha_ << ") customers=" << num_customers_ << std::endl;      for (typename std::tr1::unordered_map<Dish, DishLocations, DishHash>::const_iterator it = dish_locs_.begin();           it != dish_locs_.end(); ++it) {        (*out) << it->first << " (" << it->second.total_dish_count_ << " on " << it->second.table_counts_.size() << " tables): "; @@ -317,12 +317,12 @@ class MFCR {    unsigned num_customers_;    std::tr1::unordered_map<Dish, DishLocations, DishHash> dish_locs_; -  double d_; +  double discount_;    double alpha_; -  // optional beta prior on d_ (NaN if no prior) -  double d_prior_alpha_; -  double d_prior_beta_; +  // optional beta prior on discount_ (NaN if no prior) +  double discount_prior_alpha_; +  double discount_prior_beta_;    // optional gamma prior on alpha_ (NaN if no prior)    double alpha_prior_shape_;  | 
