• 大小: 2.83MB
    文件类型: .zip
    金币: 2
    下载: 0 次
    发布日期: 2024-01-27
  • 语言: Python
  • 标签: n-gram  python  

资源简介

基于已知的语料库,实现高效的n-gram算法,python实现

资源截图

代码片段和文件信息

import re
from collections import Counter
import sys

if len(sys.argv) < 3:
    sys.exit(‘ERROR 命令行参数依次为:训练语料文件、测试语料文件‘)

#打开文件
try:
    # 训练语料
    file_in = open(sys.argv[1] ‘r‘ encoding=‘UTF-8‘)
    # 测试数据集
    file_testdata = open(sys.argv[2] ‘r‘ encoding=‘GBK‘)
    # 输出结果
    file_out = open(‘./output.txt‘ ‘w‘ encoding=‘UTF-8‘)
except IOError as e:
    sys.exit(e)

# 词库,key-词  val-频次
wordList = Counter()  

# 写入词库
strlist = file_in.readlines()
for strLine in strlist:
    # 过滤空行
    strLine = strLine.strip()
    if not strLine:
        continue
    linelist = re.split(‘ +|\n‘ strLine)
    linelist = linelist[1:]  # 去掉行首标签
    linelist = list(map(lambda x: x[:x.find(‘/‘ 0)].strip() linelist))  # 去掉词尾的标记并且去除首尾的空格
    wordList.update(linelist)

#读取测试集
intputstrList = file_testdata.readlines();
#将初始的词库保留下来,防止之前的测试污染词库
ini_wordlist=wordList;

#以行为单位进行分词
for input_str in intputstrList:
#恢复初始词库
    wordList=ini_wordlist
    inputStrLen = len(input_str)

    i j = 0 0
    # 计算平滑值,实现策略是,对于在词库中的词直接加入待拆解pool除此之外之外只有单字可以入池
    # 即:对于OOV不进行处理,OOV中的词以单字的形式进行切分。因此预处理,直接考察所有的单字,加入词库中,有利于计算平滑值
    # 如果需要平滑,则将词库中所有的词的频次加1
    laplaceList = []
#找到不在词库里面的单字
    while i < inputStrLen:
        if not wordList.get(input_str[i]):
            laplaceList.append(input_str[i])
        i = i + 1

#存在需要修正的单字,将原来词库里面的所有的词词频加1,将修正单字的词频设置为1
#达到了归一化修正的目的
    if len(laplaceList):
        wordList.update(wordList.keys())
        wordList.update(laplaceList)

    N = sum(wordList.values())  # 词库中总的词数
    MaxLen = len(max(wordList.keys() key=len))  # 词的最大长度

    # 切分结果的数据结构[START END RATE RATE_CAL LAW ]
    # START END 分别指向的就是子串的起始和终止位置本身
# Rate词在词库中的概率,RATE_CAL词的累积概率
# LAW 最佳左邻词的起始位置
    START END RATE RATE_CAL LAW = 0 1 2 3 4

    word_pool = []  # 可能作为切分结果的字符串池
    word_cal = []  # 存放单个的切分数据

    i j = 0 0
    # 找到所有可能的划分,并且写入rate
    while i < inputStrLen:
        j = i
        while j < inputStrLen and j - i < MaxLen:
            times = wordList.get(input_str[i:j + 1])
            if times:
                rate = times / N  # 计算概率
                if i == 0:
                    # 句首词,累加的概率等于词在词库中的概率
                    word_cal = [i j rate rate -1]
                else:
                    word_cal = [i j rate -1 -1]
            word_pool.append(word_cal)
            j = j + 1
        i = i + 1

    # 求rate_cal
    for word in word_pool:
        if word[RATE_CAL] == -1:
#找到左邻词的集合
            candidate = list(filter(lambda x: x[END] == word[START] - 1 word_pool))
            #找到最大的左邻词
            rate_cal_max = max(candidate key=lambda x: x[RATE_CAL])
            #计算当前词的累积概率
            word[RATE_CAL] = rate_cal_max[RATE_CAL] * word[RATE]
            #最佳左邻词的起始位置
            word[LAW] = rate_cal_max[START]

    # 结果集合,保存的内容是字符串
    res_list = []

    # 查找最优的词尾
    bestEndCandadaite = list(filter(lambda x: x[END] == inputStrL

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----
     文件        4547  2017-12-07 13:48  n-gram - 副本\n-gram.py
     文件       21974  2017-11-29 00:40  n-gram - 副本\testset.txt
     文件    10670780  2017-10-22 23:04  n-gram - 副本\北大(人民日报)语料库199801.txt
     目录           0  2017-12-07 13:48  n-gram - 副本\

评论

共有 条评论