基于条件随机场模型的中文分词改进(Python中文分词)

目录

改进分词速度

一、更改存储特征值的数据结构

二、缩短对语料库的遍历时间(对语料库的预处理)

三、先将所有的特征值保存到数据库中

改进分词的准确度

实验项目和结果截图

实验项目

保存特征值时采用多层嵌套(多特征多嵌套-34.9秒)

保存特征值时不采用多层嵌套(仅特征四少嵌套-32.73秒)

缩短对语料库的遍历时间(语料库预处理-4.24秒)

将所有的特征值保存到数据库后(最快-0.04秒)

“人机耦合”提高分词准确度(0.04秒)


基于条件随机场模型的中文分词实现:基于条件随机场模型的中文分词实现(Python中文分词)_条件随机场实现中文分词_admiz的博客-CSDN博客

改进分词速度

一、更改存储特征值的数据结构

在保存征值时,我们可以用字典、列表等数据结构来对结果保存。经过多次对不同数据结构的测试,发现在字典内嵌套的层数越多,遍历的速度越慢。针对特征四的所有结果中……

最慢的是形如: {'希': {'B': {'前': {' '长':0 }, '后': {'望': 0}}, 'M': {'前': {'阎': 0 }, '后': {'军': 0}}, 'E': {'前': {'里': 0}, '后': {'在': 0}}, 'S': {'前': {'几': 0}, '后': {'一': 0}}}的三四层嵌套字典。(该字典dict的用法:寻找“希”字在“B” 状态时前面为“长”的概率是多少时输入dict[‘希’][‘B’][‘前’][‘长’]即可找到相应的数据。)

最快的是形如: {'希': {'腊': [1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], '希': [0.3, 0.6, 0.6, 0.3, 0.0, 0.0, 0.0, 0.0]}, '腊': {'希': [0.0, 0.0, 0.034, 0.034, 0.965, 0.965, 0.0, 0.0]}} 该字典dict的用法:寻找“希”字在“B”状态时前面为“腊”的概率是多少时输入dict[‘希’][‘腊’][0],寻找“希”字在“B”状态时后面为“腊”的概率是多少时输入dict[‘希’] [‘腊’] [1],寻找“希”字在“M”状态时前面为“腊”的概率是多少时输入dict[‘希’] [‘腊’] [2],以此类推……)

同时我们也发现字典内的字越少,遍历越快,所以在遍历时可以加个判断来筛选出有用的数据,不添加没用的数据到列表中。

综上所述,当采用嵌套层数越少的数据结构,并只把有用的数据保存到数据结构中,分词速度能有一定的提升。

二、缩短对语料库的遍历时间(对语料库的预处理)

在针对某字寻找特征二时,需要遍历一遍语料库来寻找该字的所有状态来求得需要的概率,特征三、特征四同理。而语料库有四百多万个字,当要寻找多个字的所有特征值时,约等于需要遍历三遍[(分词列表的长度数)x(四百多万)]个字,若分词列表内有十个字则需要遍历三次四千万多字。

为缩短对语料库的遍历时间,可以对语料库进行精准的删减。通过对特征二、特征三、特征四的理解,我们得知特征二只针对分词列表内的字,特征三针对分词列表内的字以及其下一个字,特征四针对分词列表内的字以及它的上一个字和下一个字。

至此我们可以知道,如果一个语料库能解决计算特征四的问题,那么这个语料库也能解决计算出特征二、特征三的问题。

生成所需语料库的步骤:

(1)打开并读取语料库

wordFile=open("msr_training.utf8.ic",'r',encoding='utf-8')
wordFeedInit=wordFile.readlines() #[0]=字 [2]=标注
wordFile.close
wordFeedLen=len(wordFeedInit)

(2)获取分词内容(列表)

str1=input("请输入要分词的字符串:")

(3)保存分词列表内每个字及它的上下字的数据

wordFeed = [ ]  #用来储存所需语料库
for i in range(1,wordFeedLen-1):
    if wordFeedInit[i][0] in str1:
        key1=[wordFeedInit[i-1],wordFeedInit[i],wordFeedInit[i+1]]
        wordFeed.extend(key1)
wordFeedLen=len(wordFeed)

三、先将所有的特征值保存到数据库中

即使是精准地缩短了语料库的长度,但在整个程序的运行时间里,大部分时间基本

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是基于条件随机场模型中文分词代码,使用CRF++工具包: 1. 数据准备 首先将训练数据和测试数据转换成CRF++的格式,格式为每个词和标注用空格隔开,句子之间用空行隔开,例如: 中 B 国 E 是 S 一个 S 伟 B 大 E 的 S 国 S 2. 模型训练 使用CRF++工具包进行模型训练,需要准备好训练数据和模板文件。模板文件指定了特征模板,例如: U00:%x[-2,0] U01:%x[-1,0] U02:%x[0,0] U03:%x[1,0] U04:%x[2,0] U05:%x[-2,0]/%x[-1,0]/%x[0,0] U06:%x[-1,0]/%x[0,0]/%x[1,0] U07:%x[0,0]/%x[1,0]/%x[2,0] 其中,%x[i,j]表示当前位置加上偏移量(i,j)的词和标注,U00-U07则是特征函数的名称。训练命令如下: crf_learn -f 3 -c 4.0 template train.data model 其中,-f指定特征函数的截断阈值,-c指定正则化参数。训练完成后会生成一个模型文件model。 3. 模型测试 使用CRF++工具包进行模型测试,需要准备好测试数据和模型文件。测试命令如下: crf_test -m model test.data > result 其中,-m指定模型文件,test.data是测试数据文件,> result表示将结果输出到result文件中。测试结果为每个词和标注用空格隔开,例如: 中 B 国 E 是 S 一个 S 伟 B 大 E 的 S 国 S 4. 结果评估 使用Python脚本进行结果评估,代码如下: ```python import sys def evaluate(gold_file, pred_file): gold = [] with open(gold_file, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if line: word, label = line.split() gold.append(label) pred = [] with open(pred_file, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if line: word, label = line.split() pred.append(label) assert len(gold) == len(pred) correct = 0 for i in range(len(gold)): if gold[i] == pred[i]: correct += 1 accuracy = correct / len(gold) return accuracy if __name__ == '__main__': gold_file = sys.argv[1] pred_file = sys.argv[2] accuracy = evaluate(gold_file, pred_file) print('Accuracy: {:.2%}'.format(accuracy)) ``` 将正确的标注文件和预测的标注文件作为参数传入,即可计算准确率。例如: python evaluate.py test.gold result 输出结果为准确率的百分比。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值