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 ¶m);
47 bool openFromArray(const Param ¶m,
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 ¶m);
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