首页 > 其他分享 >【NLP】最大概率法(负对数相加)

【NLP】最大概率法(负对数相加)

时间:2023-02-27 17:33:32浏览次数:49  
标签:NLP word 合成 结合 dict 概率法 words 对数 left


自然语言处理中最大概率法教材算法实现

 

​​把概率的相乘转为负对数的相加。​​

词典的txt:https://pan.baidu.com/s/1ARx3-fetzOmrw2c8mVAK8w

提取码:hts4

import math

def load_dict():
"""
加载字典
:return:返回字典==>"词:频率"
"""
dic_file = open("WordFrequency.txt", 'r', encoding='utf-8')
freq_dict = {}
for l in dic_file:
freq_dict[l.split(',')[0]] = l.split(',')[2].strip()
#以逗号为分割的字符串的第一部分词的概率,strip()方法移除字符串头尾指定的字符(默认为空格或换行符)
dic_file.close()
#print("freq_dict:",freq_dict)
return freq_dict


def find_word_in_dict(s):
"""
在字典中查找候选词
:param s: 输入句子
:return: 返回字典==>"词:词频|候选左邻词1/候选左邻词2"
"""
print("========================在字典中查找候选词===================================")
freq_dict = load_dict()
result = {}
for index in range(0, len(s)): # 遍历所有字
for wordLen in range(0, len(s) - index): # 遍历该字的所有可能词
seg_word = s[index:index + wordLen + 1]
if seg_word in freq_dict.keys():
# 找到候选词,找其左邻词
left_words = ''
for word_len in range(index, 0, -1): # 在之前的候选词列表里找左邻词(最大词长开始)
for k in result.keys():
if s[index - word_len:index] == k.split('-')[1]:
left_words += str(index - word_len) + '-' + s[index - word_len:index] + '/'
# 返回候选词及其语料库词频和候选左邻词
result[str(index) + '-' + seg_word] = freq_dict[seg_word] + '|' + left_words
print("result:",result)
return result


def cl_probability(words_dict):
"""
计算累加花费并选择最佳左邻词
:param words_dict: "词:词花费|候选左邻词1/候选左邻词2"
:return:返回新字典==>"词:累计花费|最佳左邻词"
"""
print("===================计算累加花费并选择最佳左邻词==============================")

for k, v in words_dict.items():#items() 方法把字典中每对 key 和 value 组成一个元组
t1= v.split('|')[0][:-1]
cost=-math.log(float(t1)*0.01) #取负对数
left_words = v.split('|')[1]
words_dict[k] = v.replace(t1, str(cost)).replace('%','')#用负对数替换概率,并且把百分号去掉
if left_words == '':#无左邻词
continue
else:
left_word = left_words.split("/")
min_left_c = 10000#每个词的最小左邻词花费初始为10000
which_word = ''#选择的词
for num in range(0, len(left_word) - 1):#在每个词的左邻词中寻找最佳左邻词
t=words_dict[left_word[num]].split('|')[0][:-1]
curr_left_word_c = float(t)
if curr_left_word_c < min_left_c: # 比较当前左邻词的累计花费
min_left_c = curr_left_word_c
which_word = left_word[num]
curr_min_c = min_left_c + cost
#多字符替换:用最小累计花费替换原来的词频,用最佳左邻词替换候选左邻词,去掉%
words_dict[k] = v.replace(left_words, which_word).replace( str(t1), str(curr_min_c)).replace('%','')
print("words_dict:",words_dict,"\n")
return words_dict


def seg(sentence):
"""
接收输入,调用函数并输出
:param sentence:
:return: 分词后的句子
"""
words_dict = find_word_in_dict(sentence)
best_words_dict = cl_probability(words_dict)
seg_line = ''
keys = list(best_words_dict.keys())
key = keys[-1]
print("========================分词后的句子===================================")
while key != '':
seg_line = key.split('-')[1] + '/ ' + seg_line
key = best_words_dict[key].split('|')[1]
print("seg_line:",seg_line)
return seg_line


if __name__ == '__main__':
#print("概率最大化分词:")
#input_str = input()结合成分子时
input_str = "结合成分子时"
print(seg(input_str))

结果:

========================在字典中查找候选词===================================
result: {'0-结': '0.0037%|'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/', '1-合成': '0.0006%|0-结/'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/', '1-合成': '0.0006%|0-结/', '2-成': '0.0423%|0-结合/1-合/'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/', '1-合成': '0.0006%|0-结/', '2-成': '0.0423%|0-结合/1-合/', '2-成分': '0.0023%|0-结合/1-合/'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/', '1-合成': '0.0006%|0-结/', '2-成': '0.0423%|0-结合/1-合/', '2-成分': '0.0023%|0-结合/1-合/', '3-分': '0.0312%|1-合成/2-成/'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/', '1-合成': '0.0006%|0-结/', '2-成': '0.0423%|0-结合/1-合/', '2-成分': '0.0023%|0-结合/1-合/', '3-分': '0.0312%|1-合成/2-成/', '3-分子': '0.0038%|1-合成/2-成/'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/', '1-合成': '0.0006%|0-结/', '2-成': '0.0423%|0-结合/1-合/', '2-成分': '0.0023%|0-结合/1-合/', '3-分': '0.0312%|1-合成/2-成/', '3-分子': '0.0038%|1-合成/2-成/', '4-子': '0.0010%|2-成分/3-分/'}
result: {'0-结': '0.0037%|', '0-结合': '0.0353%|', '1-合': '0.0049%|0-结/', '1-合成': '0.0006%|0-结/', '2-成': '0.0423%|0-结合/1-合/', '2-成分': '0.0023%|0-结合/1-合/', '3-分': '0.0312%|1-合成/2-成/', '3-分子': '0.0038%|1-合成/2-成/', '4-子': '0.0010%|2-成分/3-分/', '5-时': '0.1043%|3-分子/4-子/'}
===================计算累加花费并选择最佳左邻词==============================
words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '0.0006%|0-结/', '2-成': '0.0423%|0-结合/1-合/', '2-成分': '0.0023%|0-结合/1-合/', '3-分': '0.0312%|1-合成/2-成/', '3-分子': '0.0038%|1-合成/2-成/', '4-子': '0.0010%|2-成分/3-分/', '5-时': '0.1043%|3-分子/4-子/'}

words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '22.228343734056217|0-结', '2-成': '0.0423%|0-结合/1-合/', '2-成分': '0.0023%|0-结合/1-合/', '3-分': '0.0312%|1-合成/2-成/', '3-分子': '0.0038%|1-合成/2-成/', '4-子': '0.0010%|2-成分/3-分/', '5-时': '0.1043%|3-分子/4-子/'}

words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '22.228343734056217|0-结', '2-成': '15.717180879948966|0-结合', '2-成分': '0.0023%|0-结合/1-合/', '3-分': '0.0312%|1-合成/2-成/', '3-分子': '0.0038%|1-合成/2-成/', '4-子': '0.0010%|2-成分/3-分/', '5-时': '0.1043%|3-分子/4-子/'}

words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '22.228343734056217|0-结', '2-成': '15.717180879948966|0-结合', '2-成分': '18.629058843066094|0-结合', '3-分': '0.0312%|1-合成/2-成/', '3-分子': '0.0038%|1-合成/2-成/', '4-子': '0.0010%|2-成分/3-分/', '5-时': '0.1043%|3-分子/4-子/'}

words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '22.228343734056217|0-结', '2-成': '15.717180879948966|0-结合', '2-成分': '18.629058843066094|0-结合', '3-分': '23.78968825010375|2-成', '3-分子': '0.0038%|1-合成/2-成/', '4-子': '0.0010%|2-成分/3-分/', '5-时': '0.1043%|3-分子/4-子/'}

words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '22.228343734056217|0-结', '2-成': '15.717180879948966|0-结合', '2-成分': '18.629058843066094|0-结合', '3-分': '23.78968825010375|2-成', '3-分子': '25.895105278186847|2-成', '4-子': '0.0010%|2-成分/3-分/', '5-时': '0.1043%|3-分子/4-子/'}

words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '22.228343734056217|0-结', '2-成': '15.717180879948966|0-结合', '2-成分': '18.629058843066094|0-结合', '3-分': '23.78968825010375|2-成', '3-分子': '25.895105278186847|2-成', '4-子': '30.14198430803632|2-成分', '5-时': '0.1043%|3-分子/4-子/'}

words_dict: {'0-结': '10.20459264532005|', '0-结合': '7.949042501030977|', '1-合': '20.12828290517365|0-结', '1-合成': '22.228343734056217|0-结', '2-成': '15.717180879948966|0-结合', '2-成分': '18.629058843066094|0-结合', '3-分': '23.78968825010375|2-成', '3-分子': '25.895105278186847|2-成', '4-子': '30.14198430803632|2-成分', '5-时': '32.76075938115034|3-分子'}

========================分词后的句子===================================
seg_line: 时/
seg_line: 分子/ 时/
seg_line: 成/ 分子/ 时/
seg_line: 结合/ 成/ 分子/ 时/
结合/ 成/ 分子/ 时/

 

标签:NLP,word,合成,结合,dict,概率法,words,对数,left
From: https://blog.51cto.com/u_15983387/6088756

相关文章

  • 我是怎么丧失对数学的兴趣的
    和很多人一样,自从大一结束高数课,我的数学水平就停滞了,直到写下此文的此刻,我对数学的认知仍然没有走出微积分的范畴。究其原因,我的数学学习一直没有走出功利的范畴,那就是:一些......
  • NLP预训练模型 | 按时间线整理10种常见的预训练模型
    https://zhuanlan.zhihu.com/p/210077100 最近在学习NLP常见的预训练模型,做一下整理和对比,按照时间线主要有:ELMO2018.3华盛顿大学 论文 / 代码GPT2018.06Open......
  • 使用Python对数据备份文件进行整理
    最近公司上了一个转储服务器,用于存储所有应用系统的数据文件备份,由于每天的备份文件都放在一个固定的文件夹,不需要的文件也会传过来,日后不方便整理,于是便使用Python脚本,将......
  • 为什么要对数值类型特征做归一化?
    给出一个场景通过住户的居住面积和楼层来分析他们的居住舒适度,楼层的特征会在1-20(层)数值范围内,居住面积的特征会在30-200(平方米)数值范围内,那么根据这两种特征分析出来的数据......
  • 在对数据进行预处理时,怎样处理类别型特征?
    什么样的特征是类别型特征?类别型特征主要是指性别(男/女),体型(胖/瘦/适中)等只有在选项内取值的特征,类别型特征的原始输入通常是字符串形式,除了决策树等少数模型能够直接处理字......
  • ArcGIS Pro SDK 002 对数据文件的读取和操作
    做系统开发或者数据处理的时候,我一般还是喜欢使用文件数据源,例如矢量用.shp文件存储,栅格数据用.tif或者.img文件存储。ArcGISProSDK中对数据源操作的API和ArcObjectsSDK......
  • 多项式的各类计算(多项式的逆/开根/对数/exp/带余除法/多点求值)
    预备知识:FFT/NTT多项式的逆给定一个多项式,请求出一个多项式,满足。系数对取模,首先将多项式的长度拓展至的次幂,然后我们要求的是假设已经求出了又因为有两式相减有因为......
  • NLP自然语言处理—主题模型LDA案例:挖掘人民网留言板文本数据|附代码数据
    全文链接:tecdat.cn/?p=2155最近我们被客户要求撰写关于NLP自然语言处理的研究报告,包括一些图形和统计输出。随着网民规模的不断扩大,互联网不仅是传统媒体和生活方式的补......
  • 使用stream流对数据进行处理
    1.使用场景本次使用是通过条件查询出所需要的多个字段后,对其进行处理(一个条件查询多个下拉框内容,并对每个下拉框内容封装对象,进行返回)2.代码点击查看代码//获取......
  • 区间插入,维护本质相同集合对数 (离线)
    有\(n\)个集合,\(m\)次操作,第\(i\)次操作选择一个区间\([l_i,r_i]\),在这些集合里插入\(i\),每次操作后查询本质相同集合对数。先用可持久化线段树来存每个集合。......