作业一:训练Bigram模型并预测句子概率|自然语言


1.实验内容

∙ \bullet 基于人民日报标注语料(见附件),训练一个Bigram语言模型,并预测任意给定语句语言概率。(中文分词可以采用Jieba, SnowNLP, PkuSeg, IK Analyzer, HanLP等)


2.思路

∙ \bullet 由于词已经分好,那么训练模型只需要计算每个词的概率以及两个词组的共同概率,这里我使用正则表达式来提取每个词,然后使用字典存储它们的频数。

∙ \bullet 训练好模型以后,需要对新输入的句子进行分词,这里我调用jieba进行分词。

∙ \bullet 计算句子概率是可能出现概率为0的情况,在这里我使用加1法来解决这种问题。


3.python代码

import jieba
import re


#Bigram模型
#计算分词概率函数
def cal_word_prob(file_path):
    '''
    input:
        param file_path(str):存放分词文件的地址
    output:
        return single_word_prob(dict):记录单个词语出现的频数
        return single_word_prob(dict):记录两个词语出现的频数
    '''
    #打开txt文件,按行读取全部内容
    f = open(file_path,"r", encoding='utf-8', errors='ignore')
    lines = f.readlines()
    
    single_word_prob = {}  #记录单词词语出现的频数
    double_word_prob = {}  #记录两个词语出现的频数
    
    #按行进行计算
    for line in lines:
        #使用正则表达式提取目标内容
        temp =re.findall('\d*[\u4e00-\u9fa5]+',line)
        #在句首和句尾添加特定标识符
        temp.insert(0,"<BOS>")
        temp.append('<EOS>')
        #计算两个词的概率并填入
        for i in range(1,len(temp)):
            #两个词的组合
            item = temp[i-1]+temp[i]
            if item in double_word_prob:
                double_word_prob[item]+=1
            else:
                double_word_prob[item]=1
        #计算单个词的概率并填入
        for s in temp:
            if s in single_word_prob:
                single_word_prob[s]+=1
            else:
                single_word_prob[s]=1
    return single_word_prob,double_word_prob


#将测试语句分词
def participle(single_word_prob,double_word_prob,sentence):
    '''
    input:
        param single_word_prob(dict):记录单个词的概率
        param double_word_prob(dict):记录两个连续词的概率
        param sentence(string):传入要测试的句子
    output:
        NULL   
    '''
    ans = jieba.lcut(sentence)
    ans.insert(0,'<BOS>')
    ans.append('<EOS>')
    cal_sen_prob(single_word_prob,double_word_prob,sentence,ans)

        
#计算语句的概率
def cal_sen_prob(single_word_prob,double_word_prob,sentence,ans):
    '''
    input:
        param single_word_prob(dict):记录单个词的概率
        param double_word_prob(dict):记录两个连续词的概率
        param sentence(list):原句
        param ans(list):分好词待测试的列表
    output:
        NULL
    '''
    #存放句子的概率
    res = 1
    for i in range(1,len(ans)):
        item = ans[i-1]+ans[i]
        if item in double_word_prob:
            temp=double_word_prob[item]/single_word_prob[ans[i]]
        elif ans[i] in single_word_prob:
            temp=1/single_word_prob[ans[i]]
        else:
            temp=1/len(single_word_prob)
        res*=temp
    print('(',sentence,')的句子概率为:',res)
    
    
#主函数
if __name__ == '__main__':
    #分好词的语料库文件路径以及训练语料函数
    file_path = "E://大三上//自然语言//训练语料//训练语料1.txt"
    single_word_prob,double_word_prob=cal_word_prob(file_path)
    #输入n条句子
    n = input('输入你想要测试的句子个数:')
    for i in range(int(n)):
        sentence = input("请输入句子:")
        participle(single_word_prob,double_word_prob,sentence)
    

4.结果

在这里插入图片描述

  • 7
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比奇堡咻飞兜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值