SpaCy如何在标记化过程中跟踪字符和标记的偏移量?
在SpaCy中,有一个Span对象,该对象保持令牌/跨度https://spacy.io/api/span#init
的开始和结束偏移似乎有一种_recalculate_indices
方法正在检索token_by_start
和token_by_end
,但是看起来所有重新计算都在做。
在查看外部空间时,它正在执行一些smart alignment of the spans。
是否在每次执行正则表达式后重新计算,是否跟踪角色的移动?它会执行正则表达式后执行跨度搜索吗?
答案 0 :(得分:4)
摘要:
在标记化期间,this是跟踪偏移量和字符的部分。
简单的答案:它在字符串中一个接一个地字符化。
TL; DR在底部。
逐块解释:
它接受要标记的字符串,并开始一次遍历一个字母/空格。
这是一个简单的for
循环,其中uc
是字符串中的当前字符。
for uc in string:
它首先检查当前字符是否为空格,并将其进行比较以查看最后的in_ws
设置是否与空格相反。如果它们相同,它将向下跳并增加i += 1
。
in_ws
用于了解是否应该处理。他们想在空格和字符上做事,因此他们不能仅仅跟踪isspace()
并仅对False
进行操作。相反,在第一次启动时,会将in_ws
设置为string[0].isspace()
的结果,然后将其与自身进行比较。如果string[0]
是空格,它将求值相同,因此跳过并增加i
(稍后讨论),然后转到下一个uc
,直到达到uc
与第一个不同。实际上,这使它在处理完第一个空格后可以在多个空格之间进行排序,或者在到达下一个空格边界之前可以使用多个字符。
if uc.isspace() != in_ws:
它将继续遍历字符,直到到达下一个边界,并将当前字符的索引保持为i
。
它跟踪两个索引值:start
和i
。 start
是它所在的潜在标记的开始,而i
是它正在查看的结束字符。脚本启动时,start
将是0
。经过这样的循环后,start
将是最后一个空格的索引加1,这将使其成为当前单词的第一个字母。
它首先检查start
是否小于i
,这用来知道是否应尝试检查缓存并标记当前字符序列。这将是更合理的。
if start < i:
span
是当前用于标记化的单词。它是由start
索引值到i
索引值切成的字符串。
span = string[start:i]
然后,它将单词的哈希值(从start
到i
)并检查高速缓存字典,以查看该单词是否已被处理。如果没有,它将在字符串的该部分上调用_tokenize
方法。
key = hash_string(span)
cache_hit = self._try_cache(key, doc)
if not cache_hit:
self._tokenize(doc, span, key)
接下来,它检查当前字符uc
是否是一个正确的空格。如果是,它将重置为i + 1
,其中i
是当前字符的索引。
if uc == ' ':
doc.c[doc.length - 1].spacy = True
start = i + 1
如果字符不是空格,则将start设置为当前字符的索引。然后,它反转in_ws
,表示它是一个字符。
else:
start = i
in_ws = not in_ws
然后它增加i += 1
并循环到下一个字符。
i += 1
TL; DR
综上所述,它使用i
跟踪字符串中的字符,并使用start
跟踪单词的开头。 start
在单词处理结束时重置为当前字符,然后在空格之后将其设置为最后一个空格加一个(下一个单词的开头)。