LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
feat_extractors.h
Go to the documentation of this file.
1
// Copyright 2021 CEA LIST
2
// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3
//
4
// SPDX-License-Identifier: MIT
5
6
#ifndef DEEPLIMA_FEAT_EXTRACTORS_H
7
#define DEEPLIMA_FEAT_EXTRACTORS_H
8
9
#include <vector>
10
#include <string>
11
#include <unordered_map>
12
#include <unordered_set>
13
#include <limits>
14
15
#include "
deeplima/utils/split_string.h
"
16
17
namespace
deeplima
18
{
19
20
template
<
typename
Token>
21
class
TokenStrFeatExtractor
22
{
23
protected
:
24
inline
static
std::string
to_lower
(
const
std::string& src)
25
{
26
std::string copy = src;
27
std::transform(copy.begin(), copy.end(), copy.begin(),
28
[](
unsigned
char
c){ return std::tolower(c); });
29
return
copy;
30
}
31
32
public
:
33
TokenStrFeatExtractor
()
34
{
35
}
36
37
inline
static
bool
needs_preprocessing
()
38
{
39
return
false
;
40
}
41
42
inline
void
preprocess
(
const
Token& token)
43
{
44
}
45
46
inline
static
size_t
get_feat_id
(
const
std::string& name)
47
{
48
if
(name ==
"form"
)
return
0;
49
if
(name ==
"lc(form)"
)
return
1;
50
throw
std::runtime_error(
"Unknown feature name."
);
51
}
52
53
inline
static
std::string
feat_value
(
const
Token& token,
size_t
feat_no)
54
{
55
switch
(feat_no)
56
{
57
case
0:
// form as is
58
return
token.form();
59
case
1:
// form in lower case
60
return
to_lower
(token.form());
61
default
:
62
throw
std::runtime_error(
"Unknown feature id."
);
63
}
64
}
65
66
inline
bool
should_preprocess_feature
(
int
/*feat_no*/
)
const
67
{
68
return
true
;
69
}
70
71
inline
static
size_t
size
()
72
{
73
return
2;
74
}
75
};
76
77
template
<
typename
Token>
78
class
TokenUIntFeatExtractor
79
{
80
public
:
81
inline
static
size_t
get_feat_id
(
const
std::string& name)
82
{
83
if
(name ==
"eos"
)
return
0;
84
throw
std::runtime_error(
"Unknown feature name."
);
85
}
86
87
inline
static
uint64_t
feat_value
(
const
Token& token,
size_t
feat_no)
88
{
89
switch
(feat_no)
90
{
91
case
0:
// form as is
92
return
token.eos();
93
default
:
94
throw
std::runtime_error(
"Unknown feature id."
);
95
}
96
}
97
98
inline
static
size_t
size
()
99
{
100
return
1;
101
}
102
};
103
104
template
<
typename
Token>
105
class
TokenUIntClsFeatExtractor
106
{
107
std::vector<std::string> m_idx2feat;
108
std::unordered_map<std::string, int> m_feat2idx;
109
std::vector<uint32_t> m_idx2cls;
110
111
public
:
112
// Sentinel class id meaning "the source provides no column for this feature";
113
// feat_value() then returns 0 (the UNK / unknown-value index).
114
static
constexpr
uint32_t
NO_COLUMN
= std::numeric_limits<uint32_t>::max();
115
116
TokenUIntClsFeatExtractor
()
117
{
118
}
119
120
void
add_feature
(
const
std::string& name,
size_t
cls_id)
121
{
122
m_feat2idx[name] = m_idx2feat.size();
123
m_idx2feat.push_back(name);
124
m_idx2cls.push_back(cls_id);
125
}
126
127
inline
size_t
get_feat_id
(
const
std::string& name)
const
128
{
129
const
auto
it = m_feat2idx.find(name);
130
if
(m_feat2idx.cend() == it)
131
{
132
throw
std::runtime_error(
"Unknown feature name."
);
133
}
134
return
it->second;
135
}
136
137
inline
uint64_t
feat_value
(
const
Token& token,
size_t
feat_no)
const
138
{
139
if
(feat_no < m_idx2cls.size())
140
{
141
// Feature absent from the source (e.g. a morph class the tagger does not
142
// produce but the parser was trained with): fall back to UNK (id 0).
143
if
(
NO_COLUMN
== m_idx2cls[feat_no])
144
{
145
return
0;
146
}
147
return
token.cls(m_idx2cls[feat_no]);
148
}
149
150
throw
std::runtime_error(
"Unknown feature id."
);
151
}
152
153
inline
size_t
size
()
const
154
{
155
return
m_idx2feat.size();
156
}
157
};
158
159
template
<
typename
Token>
160
class
ConlluFeatExtractor
161
{
162
protected
:
163
std::vector<std::string>
m_idx2feat
;
164
std::unordered_map<std::string, size_t>
m_feat2idx
;
165
std::unordered_set<std::string>
m_prohibited_feats
;
166
std::unordered_set<int>
m_dont_preprocess
;
167
int
m_form
= -1;
168
int
m_form_lc
= -1;
169
int
m_upos
= -1;
170
int
m_xpos
= -1;
171
int
m_eos
= -1;
172
int
m_rel
= -1;
173
bool
m_feats
=
false
;
174
175
void
add_feature
(
const
std::string& name)
176
{
177
m_feat2idx
[name] =
m_idx2feat
.size();
178
m_idx2feat
.push_back(name);
179
}
180
181
public
:
182
183
ConlluFeatExtractor
() =
default
;
184
185
ConlluFeatExtractor
(
const
ConlluFeatExtractor
& other) =
default
;
186
187
ConlluFeatExtractor
(
const
std::string& feats_to_train)
188
{
189
for
(
const
std::string& s :
utils::split
(feats_to_train,
','
))
190
{
191
assert(s.size() > 0);
192
193
bool
dont_preprocess =
false
;
194
std::string feat_name = s;
195
if
(s[0] ==
'*'
)
196
{
197
dont_preprocess =
true
;
198
feat_name = s.substr(1);
199
}
200
201
if
(feat_name ==
"form"
)
202
{
203
add_feature
(feat_name);
204
m_form
=
m_feat2idx
[feat_name];
205
}
206
else
if
(feat_name ==
"lc(form)"
)
207
{
208
add_feature
(feat_name);
209
m_form_lc
=
m_feat2idx
[feat_name];
210
}
211
else
if
(feat_name ==
"upos"
)
212
{
213
add_feature
(
"upos"
);
214
m_upos
=
m_feat2idx
[
"upos"
];
215
}
216
else
if
(feat_name ==
"xpos"
)
217
{
218
add_feature
(
"xpos"
);
219
m_xpos
=
m_feat2idx
[
"xpos"
];
220
}
221
else
if
(feat_name ==
"feats"
)
222
{
223
m_feats
=
true
;
224
}
225
else
if
(feat_name ==
"eos"
)
226
{
227
add_feature
(
"eos"
);
228
m_eos
=
m_feat2idx
[
"eos"
];
229
}
230
else
if
(feat_name ==
"rel"
)
231
{
232
add_feature
(
"rel"
);
233
m_rel
=
m_feat2idx
[
"rel"
];
234
}
235
else
if
(s[0] ==
'-'
)
236
{
237
std::string feat_name = s.substr(1);
238
assert(feat_name.size() > 0);
239
m_prohibited_feats
.insert(feat_name);
240
}
241
else
242
{
243
throw
std::invalid_argument(
"Can't parse list of features: \""
+ feats_to_train +
"\""
);
244
}
245
246
if
(dont_preprocess)
247
{
248
m_dont_preprocess
.insert(
m_feat2idx
[s.substr(1)]);
249
}
250
}
251
}
252
253
inline
static
bool
needs_preprocessing
()
254
{
255
return
true
;
256
}
257
258
inline
void
preprocess
(
const
Token& token)
259
{
260
if
(
m_feats
)
261
{
262
for
(
const
auto
& fv : token.feats())
263
{
264
if
(
m_prohibited_feats
.end() !=
m_prohibited_feats
.find(fv.first))
265
{
266
continue
;
267
}
268
if
(
m_feat2idx
.end() ==
m_feat2idx
.find(fv.first))
269
{
270
m_feat2idx
[fv.first] =
m_idx2feat
.size();
271
m_idx2feat
.push_back(fv.first);
272
}
273
}
274
}
275
}
276
277
inline
size_t
get_feat_id
(
const
std::string& name)
const
278
{
279
const
auto
it =
m_feat2idx
.find(name);
280
if
(
m_feat2idx
.cend() == it)
281
{
282
throw
std::runtime_error(
"Unknown feature name."
);
283
}
284
return
it->second;
285
}
286
287
inline
std::string
feat_value
(
const
Token& token,
int
feat_no)
const
288
{
289
assert(feat_no >= 0);
290
291
if
(-1 !=
m_form
&&
m_form
== feat_no)
292
{
293
return
TokenStrFeatExtractor<Token>::feat_value
(token, 0);
294
}
295
else
if
(-1 !=
m_form
&&
m_form
== feat_no)
296
{
297
return
TokenStrFeatExtractor<Token>::feat_value
(token, 1);
298
}
299
else
if
(-1 !=
m_upos
&&
m_upos
== feat_no)
300
{
301
return
token.upos();
302
}
303
else
if
(-1 !=
m_xpos
&&
m_xpos
== feat_no)
304
{
305
return
token.xpos();
306
}
307
else
if
(-1 !=
m_rel
&&
m_rel
== feat_no)
308
{
309
return
token.deprel();
310
}
311
else
if
(-1 !=
m_eos
&&
m_eos
== feat_no)
312
{
313
return
token.eos() ?
"Yes"
:
"No"
;
314
}
315
else
if
(
m_feats
)
316
{
317
assert(
size_t
(feat_no) <
m_idx2feat
.size());
318
const
std::string feat_name =
m_idx2feat
[feat_no];
319
const
auto
& fv = token.feats();
320
auto
it = fv.find(feat_name);
321
if
(fv.end() == it)
322
{
323
return
"-"
;
324
}
325
assert(!it->second.empty());
326
assert(it->second.size() == 1);
327
return
*(it->second.begin());
328
}
329
330
throw
std::invalid_argument(
"Unknown feature identifier"
);
331
}
332
333
inline
bool
should_preprocess_feature
(
int
feat_no)
const
334
{
335
return
m_dont_preprocess
.cend() ==
m_dont_preprocess
.find(feat_no);
336
}
337
338
inline
size_t
size
()
const
339
{
340
return
m_idx2feat
.size();
341
}
342
343
std::vector<std::string>
feats
()
const
344
{
345
return
m_idx2feat
;
346
}
347
};
348
349
}
// namespace deeplima
350
351
#endif
deeplima::ConlluFeatExtractor
Definition
feat_extractors.h:161
deeplima::ConlluFeatExtractor::m_dont_preprocess
std::unordered_set< int > m_dont_preprocess
Definition
feat_extractors.h:166
deeplima::ConlluFeatExtractor::needs_preprocessing
static bool needs_preprocessing()
Definition
feat_extractors.h:253
deeplima::ConlluFeatExtractor::m_eos
int m_eos
Definition
feat_extractors.h:171
deeplima::ConlluFeatExtractor::m_idx2feat
std::vector< std::string > m_idx2feat
Definition
feat_extractors.h:163
deeplima::ConlluFeatExtractor::m_xpos
int m_xpos
Definition
feat_extractors.h:170
deeplima::ConlluFeatExtractor::ConlluFeatExtractor
ConlluFeatExtractor()=default
deeplima::ConlluFeatExtractor::m_form
int m_form
Definition
feat_extractors.h:167
deeplima::ConlluFeatExtractor::m_form_lc
int m_form_lc
Definition
feat_extractors.h:168
deeplima::ConlluFeatExtractor::should_preprocess_feature
bool should_preprocess_feature(int feat_no) const
Definition
feat_extractors.h:333
deeplima::ConlluFeatExtractor::ConlluFeatExtractor
ConlluFeatExtractor(const std::string &feats_to_train)
Definition
feat_extractors.h:187
deeplima::ConlluFeatExtractor::preprocess
void preprocess(const Token &token)
Definition
feat_extractors.h:258
deeplima::ConlluFeatExtractor::m_feat2idx
std::unordered_map< std::string, size_t > m_feat2idx
Definition
feat_extractors.h:164
deeplima::ConlluFeatExtractor::m_feats
bool m_feats
Definition
feat_extractors.h:173
deeplima::ConlluFeatExtractor::m_prohibited_feats
std::unordered_set< std::string > m_prohibited_feats
Definition
feat_extractors.h:165
deeplima::ConlluFeatExtractor::feats
std::vector< std::string > feats() const
Definition
feat_extractors.h:343
deeplima::ConlluFeatExtractor::m_rel
int m_rel
Definition
feat_extractors.h:172
deeplima::ConlluFeatExtractor::feat_value
std::string feat_value(const Token &token, int feat_no) const
Definition
feat_extractors.h:287
deeplima::ConlluFeatExtractor::ConlluFeatExtractor
ConlluFeatExtractor(const ConlluFeatExtractor &other)=default
deeplima::ConlluFeatExtractor::m_upos
int m_upos
Definition
feat_extractors.h:169
deeplima::ConlluFeatExtractor::size
size_t size() const
Definition
feat_extractors.h:338
deeplima::ConlluFeatExtractor::get_feat_id
size_t get_feat_id(const std::string &name) const
Definition
feat_extractors.h:277
deeplima::ConlluFeatExtractor::add_feature
void add_feature(const std::string &name)
Definition
feat_extractors.h:175
deeplima::TokenStrFeatExtractor
Definition
feat_extractors.h:22
deeplima::TokenStrFeatExtractor::TokenStrFeatExtractor
TokenStrFeatExtractor()
Definition
feat_extractors.h:33
deeplima::TokenStrFeatExtractor::needs_preprocessing
static bool needs_preprocessing()
Definition
feat_extractors.h:37
deeplima::TokenStrFeatExtractor::size
static size_t size()
Definition
feat_extractors.h:71
deeplima::TokenStrFeatExtractor::should_preprocess_feature
bool should_preprocess_feature(int) const
Definition
feat_extractors.h:66
deeplima::TokenStrFeatExtractor::get_feat_id
static size_t get_feat_id(const std::string &name)
Definition
feat_extractors.h:46
deeplima::TokenStrFeatExtractor::preprocess
void preprocess(const Token &token)
Definition
feat_extractors.h:42
deeplima::TokenStrFeatExtractor::to_lower
static std::string to_lower(const std::string &src)
Definition
feat_extractors.h:24
deeplima::TokenStrFeatExtractor::feat_value
static std::string feat_value(const Token &token, size_t feat_no)
Definition
feat_extractors.h:53
deeplima::TokenUIntClsFeatExtractor
Definition
feat_extractors.h:106
deeplima::TokenUIntClsFeatExtractor::size
size_t size() const
Definition
feat_extractors.h:153
deeplima::TokenUIntClsFeatExtractor::add_feature
void add_feature(const std::string &name, size_t cls_id)
Definition
feat_extractors.h:120
deeplima::TokenUIntClsFeatExtractor::NO_COLUMN
static constexpr uint32_t NO_COLUMN
Definition
feat_extractors.h:114
deeplima::TokenUIntClsFeatExtractor::TokenUIntClsFeatExtractor
TokenUIntClsFeatExtractor()
Definition
feat_extractors.h:116
deeplima::TokenUIntClsFeatExtractor::get_feat_id
size_t get_feat_id(const std::string &name) const
Definition
feat_extractors.h:127
deeplima::TokenUIntClsFeatExtractor::feat_value
uint64_t feat_value(const Token &token, size_t feat_no) const
Definition
feat_extractors.h:137
deeplima::TokenUIntFeatExtractor
Definition
feat_extractors.h:79
deeplima::TokenUIntFeatExtractor::size
static size_t size()
Definition
feat_extractors.h:98
deeplima::TokenUIntFeatExtractor::feat_value
static uint64_t feat_value(const Token &token, size_t feat_no)
Definition
feat_extractors.h:87
deeplima::TokenUIntFeatExtractor::get_feat_id
static size_t get_feat_id(const std::string &name)
Definition
feat_extractors.h:81
deeplima::utils::split
std::vector< std::string > split(const std::string &str, char delim)
Definition
split_string.h:20
deeplima
Definition
dependency_parser.h:28
split_string.h
deeplima
include
deeplima
feat_extractors.h
Generated by
1.9.8