huapei1989的个人博客分享 http://blog.sciencenet.cn/u/huapei1989

博文

分词技术之全切分词图

已有 4178 次阅读 2015-5-10 23:31 |个人分类:nlp|系统分类:科研笔记| 分词, 切分词图

  今晚在家有点闲,便想点是来做。想来想去,决定写一下最近研究的中文分词技术。

  中文分词方法发展至今,具体来说,方法已经有多种,什么正向最大匹配、逆向最大匹配、双向最大匹配这些纯机械切词,也有基于统计模型的n元分词、HMM分词等等。

   目前个人研究到了n元分词,就来说说n元分词中的重要数据结构或者说基础,切分词图。当然,研究到这发现什么正向最大匹配或者逆向最大匹配等,完成可以看成是n元分词在某种条件限制下的特例,也是我想说说切分词图的原因。

   首先,上一张切分词图吧,该词图的句子是“有意见分歧”。

1.切分词图

    看到词图,大家或许会想,如何生成词图,词图的意义是什么呢,词图用什么样的数据结构存储和实现呢,下面将道来。

      1)生成词图:

对于一个长度为n的句子,可以有n+1个节点,将句子所有的单字分开。如果我们把其中两个节点连上,我们会神奇的发现,这条边可以代表一个词(当然,可能这条表实际上并不是词,不过这没关系)。如上图,将节点13连起来,记做1->3,则该边便可以代表词“意见”。

根据词典,将一个句子中的所有可能词识别出来。同时,对于未知的(词不在词典中时)我们认为一个单字代表一个词,这样,我们很容易生成切分词图了(如图1)。

2)词图的意义

词图的意义一句话概括即是包括所有可能的切分方案,后续可采用一些算法,求得最可能的切分方案。(注:当我们认为每条边的概率一样时,也就是边是词的概率一样时,切分词图求最可能切分方案则退化到最大匹配分词算法,也即是分出词最少的分词方案)。

1,我们有两条路径(对应着两种切分方案)如下:

路径1:0-1-3-5   对应切分方案S1:有/  意见/  分歧/

路径2:0-2-3-5   对应切分方案S2:有意/  见/  分歧/

至于如何确定这两个方案那个更佳呢,我们可以通过n元模型去求得(常用1元模型或者2元模型),这不再该篇的考虑范畴内,不再细述。

3)词图的实现

可以很容易想到,词图可以通过邻接表去实现。对,没错,邻接表可以实现词图。以下给出一些示例:

定义节点:

public class CnToken{

   public String termText;//

   public int start;//词的开始位置

   public int end;//词的结束位置

   public int freq;//词在语料库中出现的频率

   public CnToken(int vertexFrom, intvertexTo, String word) {

       start = vertexFrom;

       end = vertexTo;

       termText = word;

   }

 

}

 

邻接表表示的切分词图由一个链表表示的数组组成,实现一个单向链表:

publicclass TokenLinkedList implements Iterable<TokenInf> {

  public static class Node {

       public TokenInf item;

       public Node next;

       Node(TokenInf item) {

            this.item = item;

            next = null;

       }

}

 

private Node head;

   public TokenLinkedList() {

       head = null;

   }

 

   public void put(TokenInf item) {

       Node n = new Node(item);

       n.next = head;

       head = n;

}

 

   public Node getHead() {

       return head;

}

 

   public Iterator<TokenInf> iterator(){//迭代器

       return new LinkIterator(head);

   }

 

   private class LinkIterator implementsIterator<TokenInf> {

       Node itr;

       public LinkIterator(Node begin) {

            itr = begin;

       }

       public boolean hasNext() {

           return itr != null;

       }

       public TokenInf next() {

            if (itr == null) {

                throw newNoSuchElementException();

            }

            Node cur = itr;

            itr = itr.next;

            return cur.item;

       }

       public void remove() {

            throw new UnsupportedOperationException();

       }

   }

 

   public String toString() {

       StringBuilder buf = newStringBuilder();

       Node cur = head;

       while (pCur != null) {

            buf.append(cur.item.toString());

            buf.append('t');

            cur = cur.next;

       }

       return buf.toString();

   }

}




https://blog.sciencenet.cn/blog-706395-889210.html

上一篇:Java编程线程状态解析
下一篇:知识产权出版社专利价值评估系统(P2I)有奖试用活动火热进行中
收藏 IP: 125.33.49.*| 热度|

1 icgwang

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-4-19 14:29

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部