一文包揽文本分割(话题分割)的6种评估性能的方法,理论+样例+代码,看完还不会的来找我!

在本文中,我们将会简要介绍文本分割任务,并介绍6种常用的性能评估指标,使用通俗易懂的例子进行一个直观的感受,并最后使用代码实现评估过程,让你看完本文,就可以进行文本分割任务的评估了。如果看完理论+样例+代码还是不会的话,直接私聊我!

任务定义

本文讨论的文本分割/话题分割是比较大的颗粒度的,一般是基于句子或者段落的。一般的,连续的段落会有一个子话题,我们就是在一篇文章中进行子话题的划分,例如下面这样一个诗歌:

  1. In Xanadu did Kubla Khan
  2. A stately pleasure-dome decree:
  3. Where Alph, the sacred river, ran
  4. Through caverns measureless to man
  5. Down to a sunless sea.
  6. So twice five miles of fertile ground
  7. With walls and towers were girdled round:
  8. And here were gardens bright with sinuous rills,
  9. Where blossomed many an incense-bearing tree;
  10. And here were forests ancient as the hills,
  11. Enfolding sunny spots of greenery.

它共包含11个句子,可以被划分为下面3个部分:
1–2 Kubla Khan and his decree
3–5 Waterways
6–11 Fertile ground and greenery

这样的拆分就是文本分割任务。我们这里先不讲如何通过模型进行判断,当然可以使用无监督、分类、序列标注等模型进行实验,我们会在下一篇文章中介绍。

下面将会介绍在文本分割中常用的6类评估指标,使用实例告诉具体的计算方法,并在最后给出其代码实现。

评估指标

判断一个模型进行文本分割任务的性能的高低,方法主要有以下6种:

  1. PRF值
    这个评判标准在信息抽取(IR)中非常广泛的使用。在之前的文章中,我们就已经介绍过,这里不再赘述。

  2. 基于分词的方法
    基于这个方法有两种,一种是比较宽容的,以BMEO四个标签的正确与否来进行判别,另一类则是比较严格的,必须预测正确每一个span的首位置和尾位置才算正确,例如正确的span划分为(1,3),(4,4),(5,7),那么你要是划分为(1,2),(3,4),(5,7),则只算对1个。

  3. P k P_k
    P k P_k 值最早在1997年TextTiling: Segmenting Text into Multi-paragraph Subtopic Passages 的论文中出现,后来在1999年Statistical Models for Text Segmentation中有了明确的定义,下面是它最原始的定义。
    P μ ( r e f , h y p ) = 1 i j n D μ ( i , j ) δ r e f ( i , j ) X N O R δ h p y ( i , j ) P_μ(ref,hyp)=\sum_{1 \le i \le j \le n}D_μ(i,j)\delta_{ref}(i,j) XNOR \delta_{hpy}(i,j)
    我们不解释其公式的具体含义,我们解释一下它的目的,它就是使用一个窗口大小为K的滑动窗口(其中K如果不指定,K为标准分割的每个块的大小的平均值的一半),判断窗口的2个边缘的节点是否属于同一个主题,然后再看标准的判断和预测的判断是否一致即可,最后将一致的数量除以滑动次数就得出 P k P_k 值。下面我们会有真实的例子进行讲解。

  4. WindowDiff(WD)
    从刚才的描述来看, P k P_k 是一个相当麻烦的评估方法,而且并没有直接评估划分的是否正确,因此,到了2002年的论文(A Critique and Improvement of an Evaluation Metric for Text Segmentation),才有了Windowdiff(WD)。
    WD指出Pk拥有5个问题:

    1. False negatives penalized more than false positives(假负例比假正例更容易受到惩罚)
    2. Number of boundaries ignored(忽略边界数量)
    3. Sensitivity to variations in segment size (对文本块大小敏感)
    4. Near-miss error penalized too much(对于小错误处罚太多)
    5. What do the numbers mean? (指标意图不明显)

    Windowdiff是替代Pk的评价指标,更加客观,其评估的公式为:
    W i n d o w D i f f ( r e f , h y p ) = 1 N k i = 1 N k ( b ( r e f i , r e f i + k ) b ( h y p i , h y p i + k ) > 0 ) WindowDiff (ref , hyp) = \frac{1}{N-k}\sum_{i=1}^{N-k}(|b(ref_i, ref_{i+k} ) − b(hyp_i, hyp_{i+k} )| > 0 )
    这个就比较直观,就是直接判别两个区域内的分割线数量的异同即可,其中K的定义与之前 P k P_k 的一样。

  5. Segmentation Similarity(S)
    到了10年后,2012年Segmentation Similarity and Agreement使用编辑距离来更好的获取一些那种微小的错误(near misses)所带来的性能偏差。
    S ( s a , s b , n t ) = 1 e d i t s ( s a , s b , n t ) p b ( D ) S(s_a,s_b,n_t)=1- \frac{|edits(s_a,s_b,n_t)|}{|pb(D)|}
    学过编辑距离的,就知道如何计算 s a s_a s b s_b 序列的编辑距离,pb(D)是潜在的边界数量,不知道的话,这里有传送门

  6. Boundary Similarity (B)
    然而就在1年以后,更先进的计算方法又出现了。在2013年的论文Evaluating Text Segmentation using Boundary Edit Distance中说,之前的3种方法都是具有偏见性的,并列举了4个例子(我们将会在下一部分见到)来说明新的评估方法的优势,下面是它的计算公式。
    B ( s 1 , s 2 , n t ) = 1 A e + w t _ s p a n ( T e , n t ) + w s _ o r d ( S e , T b ) A e + T e + S e + B m B(s_1,s_2,n_t)=1-\frac{|A_e|+w_t\_span(T_e,n_t)+w_s\_ord(S_e,T_b)}{|A_e|+|T_e|+|S_e|+|B_m|}
    公式的具体细节可以看一下论文,论文里将的比较细,因为这不是重点,我们不再这重复讲解了。当然,我们也会在下面的示例中展示。从公式中,我们可以看到很多来源于S的想法,没错,其实这篇文章与2012的文章是同一个作者所写,他在之前的工作中进一步的进行了研究,并提出了一个更好的办法,但这并不能说明之前的工作没有意义。

尽管有6个评估方法,而且越来越客观了,最新的研究仍然使用 P k P_k W D WD 两个经典的计算方法进行评估其文本分割的性能。例如IJCAI18的SEGBOT: A Generic Neural Text Segmentation Model with Pointer Network等。

实例说明

我们这里以2013年的论文里的例子,来讲解一下刚才的后4种专门用在文本分割的指标的性能之间的差异。其中,m为标准分割,a为预测分割,每个灰色方块表示一个篇章单元,单元间黑线为划分位置。那么此时有11个篇章单元,2个划分位置。
在这里插入图片描述
第一种情况:Pk=0.778, WD=0.778, B=0.500, S=0.900
在这里插入图片描述
第二种情况:Pk=0.778, WD=0.778, B=0.750, S=0.950
在这里插入图片描述
第三种情况:Pk=0.778, WD=0.778, B=0.667, S=0.900
在这里插入图片描述
第四种情况:Pk=0.889, WD=0.667, B=0.500, S=0.800

从这里可以看出,Pk和WD的指标对于是完全错误还是少许错误等同看待了,当有小片段错误时,PK和WD以及S都不敏感,而B是其中最严格的,也是能够衡量出时错一点还是完全错误。(这是作者的分析思路,看看你是否和他分析的大致相同,还是有更好的见解?)

你会问,这些指标具体怎么计算?上面的公式太复杂,没关系,下面将介绍已经完成的库,直接就可以开箱即用!

代码实现

正所谓别人的成果,必然有人实现过这些了。有轮子一定要用轮子,这样才能够站在巨人的肩膀上,而且通过对于源码的解读,你会对很多细节有更加深入的了解。正如《看论文看不懂时该怎么办》中讲的那样,看代码也是除了论文、PPT、视频、博文、课程之外很好的一个途径,而且是非常重要的途径,但其实也是最难的一种。2013年的论文有着相应的代码,而这个代码也是偶然通过另一个论文代码中发现的,它是一个已经封装好的python库,只需要执行pip install segeval就可以安装完成,如果你想研读其源码,传送门在此,如果你想看其文档,这里也提供。

在开始我们的实验前,我们先介绍一下对于文本分割的结果的表示形式有哪几种。就像我们刚开始讲述的任务一样,当我们对一个包含有若干个段落的文章进行一个潜在划分时,主要有以下3种形式:

  • mass
    聚类的形式,一个列表包含每个部分的篇章单元的数目。
  • postion
    这就是一个连续的序列,并将每一个主题都进行了标号划分。
  • boundary_string
    这是一个连续篇章单元的二值化的结果,值得注意的是,这个结果虽然使用1表示该篇章单元为分割边界,但是并不在最后一个篇章单元上标志为1。
	# mass format [2, 3, 6]
    masses = [2, 3, 6]
    # position format (1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3)
    positions = convert_masses_to_positions(masses)
    # boundary_string ({0},{1},{0},{0},{1},{0},{0},{0},{0},{0})
    boundary_string = boundary_string_from_masses(masses)

还有一种兼容NLTK形式的,如果我们要使用这种的话,可以根据传送门查看详情。

我们下面贴出代码,这个实验样例是2013年论文中的,除了一个0.95与论文中汇报不同以外(可能是论文笔误),其他全部对的上:

from segeval.window.pk import pk
from segeval.window.windowdiff import window_diff as WD
from segeval.similarity.boundary import boundary_similarity as B
from segeval.similarity.segmentation import segmentation_similarity as S

if __name__ == '__main__':
    gold = [2, 3, 6]
    h_list = [[5, 6], [2, 2, 7], [2, 3, 3, 3], [1, 1, 3, 1, 5]]
    for n, h in enumerate(h_list):
        print("第%d次实验" % int(n + 1))
        print("Pk=%.3f, WD=%.3f, B=%.3f, S=%.3f" % (pk(h, gold, one_minus=True),
              WD(h, gold, one_minus=True, window_size=2), B(h, gold), S(h, gold)))

可以得出下面的结果:

第1次实验
Pk=0.778, WD=0.778, B=0.500, S=0.900
第2次实验
Pk=0.778, WD=0.778, B=0.750, S=0.950
第3次实验
Pk=0.778, WD=0.778, B=0.667, S=0.900
第4次实验
Pk=0.889, WD=0.667, B=0.500, S=0.800

就是这么简单,我们以后的文本分割的任务都可以使用这些指标进行评判了。

PS: 对于完整的评估代码,我已经开源至Github中,代码链接

小结

通过上面的理论+样例+代码的形式,我们较为系统的理解、知道并且能够实现关于文本分割的评估过程了,在接下来,我们将会介绍几种常见的文本分割的模型以及其性能表现情况。

发布了232 篇原创文章 · 获赞 547 · 访问量 51万+

猜你喜欢

转载自blog.csdn.net/qq_35082030/article/details/105410478