From 1cc6329b18937716fc972ae9613a7cca2861400e Mon Sep 17 00:00:00 2001 From: Matthew Honnibal Date: Wed, 18 Feb 2015 04:43:21 -0500 Subject: [PATCH] * Add base class to do transitions --- spacy/_transitions.pxd | 25 ++++++++++++++++++++++++ spacy/_transitions.pyx | 44 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 spacy/_transitions.pxd create mode 100644 spacy/_transitions.pyx diff --git a/spacy/_transitions.pxd b/spacy/_transitions.pxd new file mode 100644 index 000000000..84422a532 --- /dev/null +++ b/spacy/_transitions.pxd @@ -0,0 +1,25 @@ +cdef struct Transition: + int clas + int move + int label + + weight_t score + int cost + + int (*get_cost)(const Transition* self, const State* state, const TokenC* gold) except -1 + + int (*is_valid)(const Transition* self, const State* state) except -1 + + int (*do)(const Transition* self, State* state) except -1 + + +cdef class TransitionSystem: + cdef readonly dict label_ids + cdef Pool mem + cdef const Transition* c + + cdef const Transition best_valid(self, const weight_t*, const State*) except * + + cdef const Transition best_gold(self, const weight_t*, const State*, + const TokenC*) except * + diff --git a/spacy/_transitions.pyx b/spacy/_transitions.pyx new file mode 100644 index 000000000..4bcb177ee --- /dev/null +++ b/spacy/_transitions.pyx @@ -0,0 +1,44 @@ +from cymem.cymem cimport Pool +from ._state cimport State +from ..structs cimport TokenC +from thinc.typedefs cimport weight_t + + +cdef weight_t MIN_SCORE = -90000 + +cdef class TransitionSystem: + cdef Pool mem + cdef const Transition* c + + def __init__(self, dict move_types): + entries = [] + for move, labels in move_types.items(): + entries.extend((move, label) for label in labels) + entries.sort() + moves = self.mem.alloc(len(entries), sizeof(Transition)) + for i, (move, label_str) in enumerate(entries): + moves[i].move = move + moves[i].label = self.label_ids.setdefault(label_str, len(self.label_ids)) + moves[i].clas + + cdef const Transition best_valid(self, const weight_t* scores, + const State* s) except *: + cdef int best = -1 + cdef weight_t score = MIN_SCORE + cdef int i + for i in range(self.n_moves): + if scores[i] > score and self.c[i].is_valid(&self.c[i], s): + best = i + score = scores[i] + return self.c[best] + + cdef const Transition best_gold(self, const weight_t* scores, const State* s, + const TokenC* gold) except *: + cdef int best = -1 + cdef weight_t score = MIN_SCORE + cdef int i + for i in range(self.n_moves): + if scores[i] > score and self.c[i].get_cost(&self.c[i], s, gold) == 0: + best = i + score = scores[i] + return self.c[best]