smoothnlp / SmoothNLP

专注于可解释的NLP技术 An NLP Toolset With A Focus on Explainable Inference

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

左右熵的问题

niutyut opened this issue · comments

这个包处理的左右熵不是在实际语境中候选词的左右熵,是用ngram组合后的词的左右熵。例如选择一个ngram的范围为2-4.如果一个句子是abcd,那么组合出来的词汇是ab,bc,cd,abc,bcd,abcd。假设要考虑bc是不是一个独立词汇,它的左熵变成了ab,右熵变成了cd。我觉得这是不合理的。因为这不是一个具体的文字的语境。所以导致算出来的结果不正确。因为到了abcd这个词的时候没有了右熵,而且abcd到底是不是一个正确的词也不清楚。因此希望技术人员能够从算法原理上给予一点解释。

如果选择ngram的范围为2-4,计算过程中会生成1-5的ngram。假设要考虑bc是不是一个独立词汇,将会统计bc在所有文本中的前后字符。如果bc是一个独立词汇,bc在所有文本中可能以{bcd,bcf,bca...}等多种形式出现,基于这些全局的统计结果计算右熵,在文本量足够大的情况下,我们可以认为统计结果已经接近具体的文字的语境,同理可以基于bc左边字符的出现情况{abc,xbc,lbc,hbc...}计算左熵。假设要考虑abcd是不是一个独立词汇,由于计算过程生成了5gram,所以可得到包含abcd的所有长度为5的字符串,如{abcde,abcdf,abcdk...},由此可计算右熵。

我举一个实际的例子,看能否解决您的疑问。
通过大量财经新闻文本的统计结果,算得“二维码”一词的左熵和右熵分别为 6.457、6.913。“二维”是“二维码”的一个子串,它的左熵和右熵分别为 6.453 、 0.015。可以看出,虽然“二维”也是一个合法的中文词汇,但是由于在财经领域的文本中,这个词通常是以“二维码”的子串的形式出现在文本中,也就是说,在大量财经领域文本中“二维”一词右边的字符较为单一,经常是“码”这个字,所以它的右熵很小。同理,“维码”这一子串也会有很小的左熵。生成所有候选词后,计算候选词得分并比较,保留得分最高的top K。所以最终抽取的新词,会是合法的中文词汇,并且具有领域的特点(同样合法的词语“二维码”和“二维”,“二维码“这一形式在财经领域更常见,最终得分更高)。

用于计算3gram左右熵的是所有的4gram。“二维码”的左熵,是通过 { “ 是二维码 ”,“ 算二维码 ”,“ 的二维码 ”,...} 这样的4gram计算。这也是ngram的范围为2-4,计算过程却需要生成1-5的ngram的原因。

1.这个代码中target_ngrams 是所有3gram,parent_candidates是所有4gram。
2.ngram_freq[parent_candidate]是parent_candidate这个词在所有文本中出现的频数,for parent_candidate in parent_candidates以及下面两行是建Trie的过程。
3.left_neighbors一行中的“parent_candidate[1:]+parent_candidate[0]]”,是因为使用pygtrie建Trie要求left/right neighbor位于尾部。
4.代码中140-141行,145-146行,在所有4gram中找到”二维码“的左/右相邻字符 {是二维码,说二维码,算二维码,二维码好,二维码差,二维码不}的词频,并计算二维码的左右熵.