1 //
2 //  CRF++ -- Yet Another CRF toolkit
3 //
4 //  $Id: tagger.h 1588 2007-02-12 09:03:39Z taku $;
5 //
6 //  Copyright(C) 2005-2007 Taku Kudo <taku@chasen.org>
7 //
8 #ifndef CRFPP_TAGGER_H_
9 #define CRFPP_TAGGER_H_
10 
11 #include <iostream>
12 #include <vector>
13 #include <queue>
14 #include "param.h"
15 #include "crfpp.h"
16 #include "scoped_ptr.h"
17 #include "feature_index.h"
18 
19 namespace CRFPP {
20 
toprob(Node * n,double Z)21 static inline double toprob(Node *n, double Z) {
22   return std::exp(n->alpha + n->beta - n->cost - Z);
23 }
24 
25 class Allocator;
26 
27 class ModelImpl : public Model {
28  public:
ModelImpl()29   ModelImpl() : nbest_(0), vlevel_(0) {}
~ModelImpl()30   virtual ~ModelImpl() {}
31   bool open(int argc,  char** argv);
32   bool open(const char* arg);
33   bool openFromArray(int argc,  char** argv,
34                      const char *buf, size_t size);
35   bool openFromArray(const char* arg,
36                      const char *buf, size_t size);
37   Tagger *createTagger() const;
what()38   const char* what() { return what_.str(); }
39 
nbest()40   unsigned int nbest() const { return nbest_; }
vlevel()41   unsigned int vlevel() const { return vlevel_; }
feature_index()42   FeatureIndex *feature_index() const { return feature_index_.get(); }
43   const char *getTemplate() const;
44 
45  private:
46   bool open(const Param &param);
47   bool openFromArray(const Param &param,
48                      const char *buf, size_t size);
49 
50   whatlog       what_;
51   unsigned int nbest_;
52   unsigned int vlevel_;
53   scoped_ptr<DecoderFeatureIndex> feature_index_;
54 };
55 
56 class TaggerImpl : public Tagger {
57  public:
TaggerImpl()58   explicit TaggerImpl() : mode_(TEST), vlevel_(0), nbest_(0),
59                           ysize_(0), Z_(0), feature_id_(0),
60                           thread_id_(0), feature_index_(0),
61                           allocator_(0) {}
~TaggerImpl()62   virtual ~TaggerImpl() { close(); }
63 
allocator()64   Allocator *allocator() const {
65     return allocator_;
66   }
67 
set_feature_id(size_t id)68   void   set_feature_id(size_t id) { feature_id_  = id; }
feature_id()69   size_t feature_id() const { return feature_id_; }
set_thread_id(unsigned short id)70   void   set_thread_id(unsigned short id) { thread_id_ = id; }
thread_id()71   unsigned short thread_id() const { return thread_id_; }
node(size_t i,size_t j)72   Node  *node(size_t i, size_t j) const { return node_[i][j]; }
set_node(Node * n,size_t i,size_t j)73   void   set_node(Node *n, size_t i, size_t j) { node_[i][j] = n; }
74 
75   // for LEARN mode
76   bool         open(FeatureIndex *feature_index, Allocator *allocator);
77 
78   // for TEST mode, but feature_index is shared.
79   bool         open(FeatureIndex *feature_index,
80                     unsigned int nvest, unsigned velvel);
81 
82   // for TEST mode
83   bool         open(const Param &param);
84   bool         open(const char *argv);
85   bool         open(int argc, char **argv);
86 
87   bool         set_model(const Model &model);
88 
89 
90   int          eval();
91   double       gradient(double *);
92   double       collins(double *);
93   bool         shrink();
94   bool         parse_stream(std::istream *is, std::ostream *os);
95   bool         read(std::istream *is);
96   void         close();
97   bool         add(size_t size, const char **line);
98   bool         add(const char*);
size()99   size_t       size() const { return x_.size(); }
xsize()100   size_t       xsize() const { return feature_index_->xsize(); }
dsize()101   size_t       dsize() const { return feature_index_->size(); }
weight_vector()102   const float *weight_vector() const { return feature_index_->alpha_float(); }
empty()103   bool         empty() const { return x_.empty(); }
ysize()104   size_t ysize() const { return ysize_; }
cost()105   double cost() const { return cost_; }
Z()106   double Z() const { return Z_; }
prob()107   double       prob() const { return std::exp(- cost_ - Z_); }
prob(size_t i,size_t j)108   double       prob(size_t i, size_t j) const {
109     return toprob(node_[i][j], Z_);
110   }
prob(size_t i)111   double       prob(size_t i) const {
112     return toprob(node_[i][result_[i]], Z_);
113   }
114   void set_penalty(size_t i, size_t j, double penalty);
115   double penalty(size_t i, size_t j) const;
alpha(size_t i,size_t j)116   double alpha(size_t i, size_t j) const { return node_[i][j]->alpha; }
beta(size_t i,size_t j)117   double beta(size_t i, size_t j) const { return node_[i][j]->beta; }
emission_cost(size_t i,size_t j)118   double emission_cost(size_t i, size_t j) const { return node_[i][j]->cost; }
next_transition_cost(size_t i,size_t j,size_t k)119   double next_transition_cost(size_t i, size_t j, size_t k) const {
120     return node_[i][j]->rpath[k]->cost;
121   }
prev_transition_cost(size_t i,size_t j,size_t k)122   double prev_transition_cost(size_t i, size_t j, size_t k) const {
123     return node_[i][j]->lpath[k]->cost;
124   }
best_cost(size_t i,size_t j)125   double best_cost(size_t i, size_t j) const {
126     return node_[i][j]->bestCost;
127   }
emission_vector(size_t i,size_t j)128   const int *emission_vector(size_t i, size_t j) const {
129     return const_cast<int *>(node_[i][j]->fvector);
130   }
next_transition_vector(size_t i,size_t j,size_t k)131   const int* next_transition_vector(size_t i, size_t j, size_t k) const {
132     return node_[i][j]->rpath[k]->fvector;
133   }
prev_transition_vector(size_t i,size_t j,size_t k)134   const int* prev_transition_vector(size_t i, size_t j, size_t k) const {
135     return node_[i][j]->lpath[k]->fvector;
136   }
answer(size_t i)137   size_t answer(size_t i) const { return answer_[i]; }
result(size_t i)138   size_t result(size_t i) const { return result_[i]; }
y(size_t i)139   size_t y(size_t i)  const    { return result_[i]; }
yname(size_t i)140   const char* yname(size_t i) const    { return feature_index_->y(i); }
y2(size_t i)141   const char* y2(size_t i) const      { return yname(result_[i]); }
x(size_t i,size_t j)142   const char*  x(size_t i, size_t j) const { return x_[i][j]; }
x(size_t i)143   const char** x(size_t i) const {
144     return const_cast<const char **>(&x_[i][0]);
145   }
146   const char* toString();
147   const char* toString(char *, size_t);
148   const char* parse(const char*);
149   const char* parse(const char*, size_t);
150   const char* parse(const char*, size_t, char*, size_t);
151   bool parse();
152   bool clear();
153   bool next();
154 
vlevel()155   unsigned int vlevel() const { return vlevel_; }
156 
cost_factor()157   float cost_factor() const {
158     return feature_index_ ? feature_index_->cost_factor() : 0.0;
159   }
160 
nbest()161   size_t nbest() const { return nbest_; }
162 
set_vlevel(unsigned int vlevel)163   void set_vlevel(unsigned int vlevel) {
164     vlevel_ = vlevel;
165   }
166 
set_cost_factor(float cost_factor)167   void set_cost_factor(float cost_factor) {
168     if (cost_factor > 0 && feature_index_) {
169       feature_index_->set_cost_factor(cost_factor);
170     }
171   }
172 
set_nbest(size_t nbest)173   void set_nbest(size_t nbest) {
174     nbest_ = nbest;
175   }
176 
what()177   const char* what() { return what_.str(); }
178 
179  private:
180   void forwardbackward();
181   void viterbi();
182   void buildLattice();
183   bool initNbest();
184   bool add2(size_t, const char **, bool);
185 
186   struct QueueElement {
187     Node *node;
188     QueueElement *next;
189     double fx;
190     double gx;
191   };
192 
193   class QueueElementComp {
194    public:
operator()195     const bool operator()(QueueElement *q1,
196                           QueueElement *q2)
197     { return(q1->fx > q2->fx); }
198   };
199 
200   enum { TEST, TEST_SHARED, LEARN };
201   unsigned int    mode_ ;
202   unsigned int    vlevel_;
203   unsigned int    nbest_;
204   size_t          ysize_;
205   double          cost_;
206   double          Z_;
207   size_t          feature_id_;
208   unsigned short  thread_id_;
209   FeatureIndex   *feature_index_;
210   Allocator      *allocator_;
211   std::vector<std::vector <const char *> > x_;
212   std::vector<std::vector <Node *> > node_;
213   std::vector<std::vector<double> > penalty_;
214   std::vector<unsigned short int>  answer_;
215   std::vector<unsigned short int>  result_;
216   whatlog       what_;
217   string_buffer os_;
218 
219   scoped_ptr<std::priority_queue <QueueElement*, std::vector <QueueElement *>,
220                                   QueueElementComp> > agenda_;
221   scoped_ptr<FreeList <QueueElement> > nbest_freelist_;
222 };
223 }
224 #endif
225