一种快速分词系统的设计与实现

(***计算机学院)

摘  要: 通过对已有分词算法的分析,一方面用hash加tire树的结构来改进词典,从而提高了分词速度,另一方面,在已有模型的基础上,通过增加规则来保证分词准确率。实验表明整个系统的分词速度和准确率都得到了一定程度的提高。

关键词:分词;hash;Trie树;规则

1 概述

分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。在英文的行文中,单词之间是以空格作为自然分界符的,而中文只有在句与句之间才通过标点或段落来简单划界,词与词之间则没有这样的分界符,因此,计算机上对于中文的处理就要比英文复杂得多。

词是最小的、能独立活动的、有意义的语言成分。计算机的所有语言知识都来自机器词典(给出词的各项信息)、句法规则(以词类的各种组合方式来描述词的聚合现象)以及有关词和句子的语义、语境、语用知识库。汉语信息处理系统只要涉及句法、语义(如检索、翻译、文摘、校对等应用),就需要以词为基本单位。当汉字由句转化为词之后,才能使得句法分析、语句理解、自动文摘、自动分类和机器翻译等文本处理具有可行性。可以说,分词是机器语言学的基础。

在实现分词算法的过程中,有两方面必须考虑:分词的正确率和分词的速度。由于无论哪种分词方法都需要将大量的时间用于计算出待切分语句的可能词,然后通过对切分出的这些词依据统计或语法方面的规则,得到一种最有可能的正确切分结果,来提高分词的正确率。如果能加快初始切分的速度,对于提高整个分词算法的速度也会有很大帮助。

本文在前人基础上设计了一种高效的字典组织结构来提高查找而提高分词速度,又加上二条规则的分词方法来保证分词的正确率。从而从整体上保证了分词的速度和正确率。

2 字典结构介绍

为了解决速度的问题,先介绍两个数据结构:

1.Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

那么在查找汉字的时候,那怎么用hash确定一个汉字位置呢?这就和每种编码的排列有关了,这里主要给出一种hash函数的策略。

对于GB2312编码,设输入的汉字为GBword,我们可以采用公式(C1-176)*94 + (C2-161)确定GBindex。其中,C1表示第一字节,C2表示第二字节。具体如下:

GBindex =((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) - 161;

2.Trie树

Trie,又称字典树、单词查找树,是一种树形结构,用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。

其基本性质可以归纳为:

1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。

2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

3. 每个节点的所有子节点包含的字符都不相同。

其基本操作有:查找 插入和删除,当然删除操作比较少见.我在这里只是实现了对整个树的删除操作,至于单个word的删除操作也很简单.

搜索字典项目的方法为:

(1) 从根结点开始一次搜索;

(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;

(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。

(4) 迭代过程……

(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。

其他操作类似处理.

假设有b,abc,abd,bcd,abcd,efg,hii这6个单词,我们构建的树就是这样的。

图1 Trie树结构图

3.将hash和trie树结合起来则会得到我们所要的字典结构:

图2 hash_Trie树字典结构图

经分析hash的查找时间复杂度为O(1),同理:Trie在查找的时间复杂度也为O(1).那么查询整个词的查找时间复杂度也为O(1)。

3 基于规则的分词算法:

本分词系统也是基于字典的改进型最大匹配算法。

分词算法,目前有很多。比较常用的是正向最大匹配和反向最大匹配算法。但这两种算法对于一些存在多元歧异的句子缺乏较好的支持。以“长春市长春节致词”和“长春市长春药店”这个两个句子为例:

“长春市长春节致词”可以依次拆分为 长春、长春市、市长、长春、春节、致词 这几个词,按照正向最大匹配算法,分词结果是长春市/长/春节/致词,按照反向最大匹配算法,分词结果是长春/市长/春节/致词。

“长春市长春药店”可以依次拆分为长春、长春市、市长、长春、春药、春药店、药店 这几个词,按照正向最大匹配算法,分词结果是 长春市/长春/药店,按照反向最大匹配算法,分词结果是“长春/市长/春药店”。

可见无论是正向还是反向最大匹配,都存在产生歧异的情况。

本系统的算法在正向匹配算法的基础上做了一些改进,用一句话描述就是找到句子中第一个未被匹配的字数最少的单词组合,如果多个组合未被匹配的字数都是最少则找到其中匹配的单词个数最少的组合。匹配顺序是从左至右。还是以上面两个句子为例:

“长春市长春节致词” 按正向最大匹配扫描顺序可以出现如下匹配的单词组合:

1) 长春/市长/春节/致词 匹配单词数4,未匹配字数0

2) 长春市/长春/致词 匹配单词数3,未匹配字数0

不难看出,第一中组合未匹配的字数最少,所以取组合1。

“长春市长春药店”按正向最大匹配扫描顺序可以出现如下匹配的单词组合

1)     长春市/长春/药店 匹配单词数3,未匹配字数0

2)     长春市/春药店 匹配单词数2,未匹配字数1

3)     长春市/春药 匹配单词数2,未匹配字数2

4)     长春市/药店 匹配单词数2,未匹配字数2

5)     长春/市长/春药店 匹配单词数3,未匹配字数0

6)     长春/市长/春药 匹配单词数3,未匹配字数1

7)     长春/市长/药店 匹配单词数3,未匹配字数1

8)     长春/市长/药店 匹配单词数3,未匹配字数1

9)     长春/长春/药店 匹配单词数3,未匹配字数1

可见组合1和组合5 未匹配数最小,匹配单词数相等,但组合1匹配顺序靠前,所以取组合1。

4 实现

以下是其分词的整个流程图:

图3 系统流程图

图中可以看出整个算法的核心由两个一个是它将字典组织成入口为hash结构而存储用trie树的结构,有了这个结构就可以快速的找到处理的句子中可能含有的所有词。这个结构就保证了此算法的快速。

另一个则是用博弈树来找到最佳匹配,而找的核心则是这个系统自定义的规则来找:一个句子中词数最少且未匹配字数最少的为最佳匹配。

下面是是博弈树来找到最佳匹配的流程图:

图4 寻找最佳匹配流程图

参考文献

[1] 张小欢.中文分词系统的设计和实现[D].电子科技大学学位论文 .2010-05-01.

[2] 吴晶晶,荆继武,聂晓峰,王平建.一种快速中文分词词典机制[J].中国科学院研究生完学报.2008-10-16

[3] 阵桂林,王永成,韩客松,王 刚.一种改进的快速分词算法.计算机研究与发展[J].1999-08-20.

[4] 陈小荷.现代汉语自动分析----Visual c++实现[M].北京语言文化大学出版社.1999.

[5] 王骐.博弈树搜索算法的研究及改进[D].浙江大学硕士论文 20060201

[6] 黄昌宁,赵海. 中文分词十年回顾[J] 中文信息学报 2007-03-22

[7] 翟伟斌,周振柳,蒋卓明,许榕生. 汉语分词词典设计[J] 计算机工程与应用2007

最后附上寻找最优匹配的代码:

//得到最优组合

//sentword表示全切分的词,pbegin表示当前
unsigned int getbestcomb(unsigned char first,sentwords* preinfo,strword*pbegin)
{
sentwords *pcurs;
strword *pcurw;
strword *prew;
strword *ptmp;
unsigned int i;

//如果是第一次,则进行下列初始化
if (first==1||pbegin==NULL)
{
pbegin=g_words.head;
first=0;
}

//其它情况时需进行下面的初始化
pcurs=(sentwords*)malloc(sizeof(sentwords));
if (pcurs==NULL)
{
return NULL;
}
initcomsent(pcurs);
if (preinfo!=NULL)
{
for (i=0;i<preinfo->wordcnt-1;i++)
{
pcurs->words[i]=preinfo->words[i];
}
pcurs->wordcnt=preinfo->wordcnt;
pcurs->blanks=preinfo->blanks+(pbegin->pos-preinfo->words[preinfo->wordcnt-1]->pos);
pcurs->words[pcurs->wordcnt-1]=pbegin;
}
else if (preinfo==NULL)
{
pcurs->blanks+=pbegin->pos;
pcurs->words[pcurs->wordcnt]=pbegin;
pcurs->wordcnt++;
}

prew=pbegin;
pcurw=prew->next;
//进入循环
while (pcurw!=NULL)
{
ptmp=prew;
if ((prew->pos+strlen(prew->word))<=pcurw->pos)
{
pcurs->blanks=pcurs->blanks+(pcurw->pos-(prew->pos+strlen(prew->word)));
pcurs->words[pcurs->wordcnt]=pcurw;
pcurs->wordcnt++;
prew=pcurw;
pcurw=pcurw->next;
}
else
{
//当有分支,则进行递归调用
getbestcomb(first,pcurs,pcurw);
//prew=pcurw;因为此行代码调了2个小时,
//而这个得到最优组合的函数共写了3个小时。
pcurw=pcurw->next;
}
// prew=pcurw;
// pcurw=pcurw->next;
}

if (minblank>pcurs->blanks||
minblank==pcurs->blanks&&mincnt>pcurs->wordcnt)
{
if (g_segresult!=NULL)
{
free((void *)g_segresult);
}
mincnt=pcurs->wordcnt;
minblank=pcurs->blanks;
g_segresult=pcurs;
}
else
{
free((void *)pcurs);
}
return SYS_OK;
}

一种快速分词系统的设计与实现相关推荐

  1. 匹配系统Java开发,基于RFID的机场行李快速匹配系统的设计(Java,MySQL)

    基于RFID的机场行李快速匹配系统的设计(JAVA,MySQL)(论文11400字,程序代码,MySQL数据库) 摘要:机场设备的智能化体现了我国在航空领域的水平.现代技术的快速发展也为机场行李匹配的 ...

  2. 基于树莓派实现平菇栽培种 自动种植系统的设计和实现

     基于树莓派实现平菇栽培种 自动种植系统的设计和实现 徐征宇 韩佳辰 摘 要:本文从树莓派实现温湿度和二氧化碳浓度远程监测控制系统的搭建.平菇种植的特点.远程控制支持三个层次介绍了基于树莓派实现平菇栽 ...

  3. 混合网络:为自动驾驶设计的一种快速车辆检测系统

    题目:HybridNet A fast vehicle detection system for autonomous driving 摘要:对于自动驾驶系统来说,车辆检测是非常重要的也是最具挑战性的 ...

  4. 基于matlab语音增强,基于MATLAB的语音增强系统的设计

    187 2010 年第 05 期,第 43 卷 通 信 技 术 Vol.43,No.05,2010 总第 221 期 Communications Technology No.221,Totally ...

  5. 利用现有资源快速实现汉语专用分词系统

    利用现有资源快速实现汉语专用分词系统<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office&q ...

  6. 在linux下进行嵌入式系统设计,一种应用于测控系统的基于Linux的嵌入式系统的设计...

    描述 1.前言 随着网络控制技术的快速发展,工业以太网得到逐步完善,在工业控制领域获得越来越广泛的应用.工业以太网使用了TCP/IP协议,便于联网,并具有高速控制网络的优点.随着32位嵌入式CPU价格 ...

  7. c语言快餐店计费系统,一种快餐快速计费系统的制作方法

    本实用新型涉及一种快餐快速计费系统,尤其是通过图像对餐具进行识别的计费系统. 背景技术: 快餐快速计费系统通常适用于自选模式的餐厅,应用场所主要包括学校(高校)食堂.企事业单位食堂.园区食堂.快餐连锁 ...

  8. 初学入门 | 一种快速准确的人脸检测、识别和验证系统

    即将迎来了2019世界人工智能大会,相信这个会议又一次推动人工智能的发展,有兴趣的同学可以去参加感受一下人工智能的热度,绝不会低于这个夏天的高温. 今天"计算机视觉战队"为大家分析 ...

  9. 一种快速准确的人脸检测、识别和验证系统(入门)

    即将迎来了2019世界人工智能大会,相信这个会议又一次推动人工智能的发展,有兴趣的同学可以去参加感受一下人工智能的热度,绝不会低于这个夏天的高温. 今天"计算机视觉战队"为大家分析 ...

最新文章

  1. SpringBoot (七) :SpringBoot 整合dubbo
  2. 视频中的目标检测与跟踪综述
  3. 最常见的HTTP错误
  4. liferay spring mvc的实现
  5. select,poll,epoll区别
  6. 阿里“AI搭配师”一秒给你100种穿搭建议,程序员进军女性时尚靠什么?
  7. python fpga chips_FPGA实现USB2.0同步读数据传输且用chipscop抓取波形(3)
  8. Harmony OS — TimePicker时间选择器
  9. 数据挖掘实战—餐饮行业的数据挖掘之数据预处理
  10. Yu-Chee Tseng
  11. SnakeYaml快速入门
  12. 零信任架构的3大核心技术
  13. DM368开发 -- 再论 UBL
  14. BIOS知识枝桠——UEFI Driver
  15. iOS 单元测试和UI测试教程
  16. H264解码器源码(vc6版)H264Decoder_vc6.rar
  17. Android开发之实时更新系统时间
  18. arduino学习:本人编写的单个传感器控制电机运转的代码
  19. 《Linux命令行与shell脚本编程大全》第十三章 学习笔记
  20. Opencv 分水岭算法 watershed的图像分割

热门文章

  1. [模拟训练]海星突击队
  2. Maven可选依赖与排除依赖
  3. 数学公式编辑器有哪些?方法要选对
  4. 原来这些热门游戏都基于Unity开发,为何Unity集训营越来越受欢迎?
  5. php+mysql网站开发全程实例 于荷云 pdf_《PHP 7 0+MySQL网站开发全程实例》于荷云著【摘要 书评 在线阅读】-苏宁易购图书...
  6. 店铺一定要注意店铺质量|百择电商
  7. MySQL查询字段详细信息
  8. 考研线性代数知识导图
  9. 畅游青岛旅游系统的设计与实现
  10. UBUNTU之安装软件