是否可以测试分词器是否可以仅从其词汇表中无损地分词和去分词?

问题描述

我正在尝试测试给定的词汇表是否包含无损重建文本语料库所需的标记。也就是说,如果在文本语料库上训练的分词器尝试根据其关联的词汇对训练语料库进行分词,它是否能够对整个训练语料库进行分词和去分词,而不会丢失任何文本到 [unk] 分词?有没有办法对此进行测试?


假设您有一个文本语料库 - 我将在此示例中使用一个小语料库

corpus = ‘the cat in the hat’

假设您有一个训练有素的分词器,它根据其词汇列表进行分词,其中每个标记 id 只是列表中标记的索引。

vocab = [‘t’,‘h’,‘e’,‘ ‘,‘c’,‘a’,‘i’,‘n’]
print(len(vocab))
8
tokens = tokenize(corpus,vocab))
print(tokens)
[0,1,2,3,4,5,6,7,0]
print(“Tokenized length: {}”.format(len(tokens)))
Tokenized length: 18

如果我从这里去分词,我显然可以像原来一样重建语料库。然而,这个过程是次优的,因为我们可以组合标记来减少标记化表示的长度。

vocab = [‘t’,‘n’,‘th’]
print(len(vocab))
9
tokens = tokenize(corpus,vocab))
print(tokens)
[8,8,0]
print(“Tokenized length: {}”.format(len(tokens)))
Tokenized length: 16

这显然仍然是无损的,尽管它在词汇表中添加一个额外的标记,这将增加模型尝试预测序列中下一个标记的可能性空间。但是如果我删除一个必要的令牌,它就会变得有损。假设我们的分词器为不在词汇表中的所有词符输出“[unk]”,并且无论词汇表的内容如何,​​“[unk]”词符始终是词汇表中的最后一个词。

vocab = [‘t’,‘th’]
print(len(vocab))
8
tokens = tokenize(corpus,vocab))
print(tokens)
[7,0]
print(“Tokenized length: {}”.format(len(tokens)))
Tokenized length: 16

表示的长度没有改变,但我们可以从词汇表看出它是有损的,因此它已经被有损压缩了。

print(detokenize(tokens,vocab))
[‘the cat i[unk] the hat’]

这个例子很容易判断压缩是有损的,因为我们的词汇量很小并且由次优组合的标记组成。我们可以进一步组合词汇,将‘t’、‘h’、‘e’和‘’组合成一个单一的标记,涵盖“the”的所有实例。由于“e”不会出现在“the”中的位置之外,我们可以将其从词汇表中删除,并且仍然保持相同的压缩损失水平,“i”和“n”也是如此。

vocab = [‘t’,‘the  ‘,‘in’]
print(len(vocab))
7
tokens = tokenize(corpus,vocab)
print(tokens)
[2,0]
print(len(tokens)
11

到目前为止,这是句子的最佳压缩形式(尽管我不认为它是最佳压缩形式)并且它的词汇量最小,使模型更容易猜测下一个标记.在所有这些例子中,我们已经能够通过观察来明确地判断压缩是否是无损的。

然而,标记一个句子的方法不止一种。如果我们的分词器在没有 'e' 上下文的情况下看到 't' 和 'h',就会遇到问题:我们的词汇表中没有 'e',如果不正确训练后,它将被迫用 '[unk]' 标记替换该 'e',使其有损,同时显着扩大其表示的长度。

因此,即使我们刚刚证明了在给定这个语料库和最后一个词汇表的情况下无损压缩是可能的,如果分词器对序列的识别很差,即使词汇表列表也无法无损分词很适合它。随着语料库规模的增加,仅通过查看词汇表可以无损地重建语料库来判断变得越来越困难。

使用像 SentencePiece 这样的东西,它认为数千个词汇量,试图重建数百万个句子的 Wiki 句子语料库,仔细研究每个输出词汇量并手动检查是否它可以重建语料库。

因此我的问题是:给定一个词汇表和一个语料库,是否有一种自动方法来告诉它可能使用给定的词汇表无损地重建给定的语料库,假设一个训练有素的分词器?换句话说,是否有一个函数可以确定是否可以进行无损标记化,该函数在给定输入语料库和词汇表的情况下返回 true 或 false?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)