orth、lemma、tag、pos分别是什么意思?
见https://spacy.io/docs/usage/pos-tagging#pos-schemes
print(word) 和 print(word.orth_) 有什么区别
简而言之:
word.orth_ 和 word.text 是一样的。事实上 cython 属性以下划线结尾,它通常是开发人员并不想向用户公开的变量。
简而言之:
当您在https://github.com/explosion/spaCy/blob/develop/spacy/tokens/token.pyx#L537 访问word.orth_ 属性时,它会尝试访问保存所有单词词汇表的位置的索引:
property orth_:
def __get__(self):
return self.vocab.strings[self.c.lex.orth]
(有关self.c.lex.orth的解释详见下文In long)
而word.text 返回单词的字符串表示形式,它仅环绕orth_ 属性,请参阅https://github.com/explosion/spaCy/blob/develop/spacy/tokens/token.pyx#L128
property text:
def __get__(self):
return self.orth_
当您打印print(word) 时,它会调用__repr__ dunder 函数,该函数返回指向word.text 变量的word.__unicode__ 或word.__byte__,请参阅https://github.com/explosion/spaCy/blob/develop/spacy/tokens/token.pyx#L55
cdef class Token:
"""
An individual token --- i.e. a word, punctuation symbol, whitespace, etc.
"""
def __cinit__(self, Vocab vocab, Doc doc, int offset):
self.vocab = vocab
self.doc = doc
self.c = &self.doc.c[offset]
self.i = offset
def __hash__(self):
return hash((self.doc, self.i))
def __len__(self):
"""
Number of unicode characters in token.text.
"""
return self.c.lex.length
def __unicode__(self):
return self.text
def __bytes__(self):
return self.text.encode('utf8')
def __str__(self):
if is_config(python3=True):
return self.__unicode__()
return self.__bytes__()
def __repr__(self):
return self.__str__()
长篇大论:
让我们试着一步一步来:
>>> import spacy
>>> nlp = spacy.load('en')
>>> doc = nlp(u'This is a foo bar sentence.')
>>> type(doc)
<type 'spacy.tokens.doc.Doc'>
将句子传递给nlp() 函数后,它会生成一个spacy.tokens.doc.Doc 对象,来自文档:
cdef class Doc:
"""
A sequence of `Token` objects. Access sentences and named entities,
export annotations to numpy arrays, losslessly serialize to compressed
binary strings.
Aside: Internals
The `Doc` object holds an array of `TokenC` structs.
The Python-level `Token` and `Span` objects are views of this
array, i.e. they don't own the data themselves.
Code: Construction 1
doc = nlp.tokenizer(u'Some text')
Code: Construction 2
doc = Doc(nlp.vocab, orths_and_spaces=[(u'Some', True), (u'text', True)])
"""
所以spacy.tokens.doc.Doc 对象是spacy.tokens.token.Token 对象的序列。在 Token 对象中,我们看到一波 cython property 枚举,例如在https://github.com/explosion/spaCy/blob/develop/spacy/tokens/token.pyx#L162
property orth:
def __get__(self):
return self.c.lex.orth
回溯,我们看到self.c = &self.doc.c[offset]:
cdef class Token:
"""
An individual token --- i.e. a word, punctuation symbol, whitespace, etc.
"""
def __cinit__(self, Vocab vocab, Doc doc, int offset):
self.vocab = vocab
self.doc = doc
self.c = &self.doc.c[offset]
self.i = offset
没有完整的文档,我们真的不知道self.c 的含义,但从它的外观来看,它正在访问&self.doc 引用中的一个令牌,该引用指向传递给Doc doc 的Doc doc功能。所以很可能,这是访问令牌的捷径
看着Doc.c:
cdef class Doc:
def __init__(self, Vocab vocab, words=None, spaces=None, orths_and_spaces=None):
self.vocab = vocab
size = 20
self.mem = Pool()
# Guarantee self.lex[i-x], for any i >= 0 and x < padding is in bounds
# However, we need to remember the true starting places, so that we can
# realloc.
data_start = <TokenC*>self.mem.alloc(size + (PADDING*2), sizeof(TokenC))
cdef int i
for i in range(size + (PADDING*2)):
data_start[i].lex = &EMPTY_LEXEME
data_start[i].l_edge = i
data_start[i].r_edge = i
self.c = data_start + PADDING
现在我们看到Doc.c 指的是一个cython 指针数组data_start,它分配内存来存储spacy.tokens.doc.Doc 对象(如果我得到<TokenC*> 的解释错误,请纠正我)。
所以回到self.c = &self.doc.c[offset],它基本上是在尝试访问存储数组的内存点,更具体地说是访问数组中的“偏移量”项。
这就是spacy.tokens.token.Token。
回到property:
property orth:
def __get__(self):
return self.c.lex.orth
我们看到self.c.lex 正在访问data_start[i].lex from spacy.tokens.doc.Doc,而self.c.lex.orth 只是一个整数,表示保存在spacy.tokens.doc.Doc 内部词汇表中的单词出现的索引。
因此,我们看到property orth_ 尝试使用来自self.c.lex.orth https://github.com/explosion/spaCy/blob/develop/spacy/tokens/token.pyx#L162 的索引访问self.vocab.strings
property orth_:
def __get__(self):
return self.vocab.strings[self.c.lex.orth]