中文文本纠错 算例实现(有算例完整代码) |
您所在的位置:网站首页 › 食不果腹的正确词语是 › 中文文本纠错 算例实现(有算例完整代码) |
概述
文本纠错又称为拼写错误或者拼写检查,由于纯文本往往来源于手打或者OCR识别,很可能存在一些错误,因此此技术也是一大关键的文本预处理过程,一般存在两大纠错类型。 1拼写错误 第一种是Non-word拼写错误,表示此词汇本身在字典中不存在,比如把“要求”误写为“药求”, 2.少字多字 中文文本纠错比较难,不多说。上思路 方法有很多,本文讲解基于拼音 语言:python3.7 思路: 首先:本地得有一个正确字词的数据库 。命名 数据库.txt 格式:第一列正确字词,第二列 词频 ,第三列 词性 本文只用词和词频。考虑词性太难啦对于特定行业的任务,可能需要在添加一些字词进数据库.txt。哪些字词需要添加呀,一般是语音转换容易错的词。 方法见链接:用100行python代码发现语音识别文本错误词,并将结果和正确词一一对应![]() ![]() 代码: 1导入包 和标点符号 #!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Author: yudengwu # @Date : 2020/6/22 import sys import pinyin import jieba import string import re #标点符号 PUNCTUATION_LIST = string.punctuation # 标点符号!"#$%&'()*+,-./:;?@[\]^_`{|}~ PUNCTUATION_LIST += "。,?:;{}[]‘“”《》/!%……()" # 添加额外标点符号2读取 数据库.txt 只读取第一列和第二列 ,最后生成字典。 #得到的是各单词词频,如:{‘老师上课’: ‘3’, ‘老师傅’: ‘62’, ‘老师宿儒’: ‘老师上课’: ‘3’, ‘老师傅’: ‘62’, } #统计个单词的词频 def construct_dict(file_path): word_freq = {} with open(file_path, "r",encoding='utf-8') as f: for line in f: info = line.split() word = info[0] frequency = info[1] word_freq[word] = frequency return word_freq FILE_PATH = "token_freq_pos%40350k_jieba.txt" phrase_freq = construct_dict( FILE_PATH ) #得到的是各单词词频,如:{'老师上课': '3', '老师傅': '62', '老师宿儒': '老师上课': '3', '老师傅': '62', }3.读取编辑距离.txt import pinyin #载入编辑距离的单词列表 #cn_words_dict 用于编辑距离的,从里面选择字来菜如或者替换目标词 def load_cn_words_dict( file_path ): cn_words_dict = "" with open(file_path, "r",encoding='utf-8') as f: for word in f: cn_words_dict += word.strip()#去除首尾空格 return cn_words_dict cn_words_dict = load_cn_words_dict("cn_dict.txt")#导入单字4. 计算错误单词与数据库.txt里的单词的编辑距离 #函数计算与中文短语的距离 #cn_words_dict 用于编辑距离的,从里面选择字来菜如或者替换目标词 def edits1(phrase, cn_words_dict): "`所有的编辑都是一个编辑远离'短语." #phrase = phrase.decode("utf-8") splits = [(phrase[:i], phrase[i:]) for i in range(len(phrase) + 1)]#将单词前后分开 deletes = [L + R[1:] for L, R in splits if R]#删除 transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R)>1]#转换 replaces = [L + c + R[1:] for L, R in splits if R for c in cn_words_dict]#替换 inserts = [L + c + R for L, R in splits for c in cn_words_dict]#插入 return set(deletes + transposes + replaces + inserts) #编辑距离生成的词是否在我们前面得到的{词:词频}列表里,是就返回5.找到候选正确词集 。即编辑距离生成的词同时又在数据库.txt里的词 #编辑距离生成的词是否在我们前面得到的{词:词频}列表里,是就返回 def known(phrases): return set(phrase for phrase in phrases if phrase in phrase_freq)6.计算拼音,得到一级数组,二级数组,三级数据。对候选正确词进行分级 #得到错误短语的候选短语 #我们根据候选词的拼音对其重要性进行排序 #如果候选词的拼音与错误词完全匹配,则将候选词进行一级数组 #如果候选词的第一个词的拼音与错误词的第一个词匹配,我们将其按二级数组 #否则我们把候选短语放入第三个数组 def get_candidates(error_phrase): candidates_1st_order = [] candidates_2nd_order = [] candidates_3nd_order = [] #pinyin.get,get使用一个简单的get()函数,则可以返回拼音的符号,format="strip"去掉音调, delimiter="/"拼音之间的分隔符 error_pinyin = pinyin.get(error_phrase, format="strip", delimiter="/")#错误拼音 error_pinyin=str(error_pinyin)#转换成字符串格式,为后面选择拼音打下基础 cn_words_dict = load_cn_words_dict("cn_dict.txt")#导入单字 candidate_phrases = list(edits1(error_phrase, cn_words_dict))#编辑距离生成的候选词组 for candidate_phrase in candidate_phrases:#遍历编辑距离生成的候选词组 candidate_pinyin = pinyin.get(candidate_phrase, format="strip", delimiter="/")#候选词拼音 candidate_pinyin=str(candidate_pinyin) if candidate_pinyin == error_pinyin: # 如果错误词拼音等于候选词拼音,则加入第一选择 candidates_1st_order.append(candidate_phrase) elif candidate_pinyin.split("/")[0] == error_pinyin.split("/")[0]: candidates_2nd_order.append(candidate_phrase) else: candidates_3nd_order.append(candidate_phrase)#否则加入第三个 return candidates_1st_order, candidates_2nd_order, candidates_3nd_order7.找到正确单词 #自动更正单词 def auto_correct(error_phrase): c1_order, c2_order, c3_order = get_candidates(error_phrase)#得到的候选正确词 # print c1_order, c2_order, c3_order value1,value2,value3 = [],[],[] if c1_order: for i1 in c1_order: if i1 in phrase_freq: value1.append(i1) return (max(value1, key=phrase_freq.get)) #一级候选存在,如果候选词拼音与错误单词完全正确,则返回候选词词频最大的单词 elif c2_order: for i2 in c2_order: if i2 in phrase_freq: value2.append(i2) return (max(value2, key=phrase_freq.get)) #一级候选不存在,二级候选存在,返回二级候选词频最大的词 else: for i3 in c3_order: if i3 in phrase_freq: value3.append(i3) return(max(value3, key=phrase_freq.get)) #否则,返回三级候选词频最大的8.测试 对一个句子进行分词 ,然后每个单词 拿去寻找正确单词 ,最后将这些词拼接为正确句子 #对于任何一个给定的句子,用结巴做分词, #割完成后,检查word_freq dict中是否存在剩余的短语,如果不存在,则它是拼写错误的短语 #使用auto_correct函数纠正拼写错误的短语 #输出正确的句子 def auto_correct_sentence(error_sentence, verbose=True): jieba_cut = jieba.cut(error_sentence, cut_all=False) seg_list = "\t".join(jieba_cut).split("\t") # 分词 correct_sentence = "" for phrase in seg_list: correct_phrase = phrase # 当前词语 if phrase not in PUNCTUATION_LIST: # 去除标点符号 if phrase not in phrase_freq.keys(): correct_phrase = auto_correct(phrase) # 对当前学习进行修正 if True: print(phrase, correct_phrase) correct_sentence += correct_phrase return correct_sentence9.主函数 def main(): errsent = '重庆是中国的四大火炉之一,因风景锈丽,是"人间天棠"!' print("测试 :") correct_sent = auto_correct_sentence(errsent) print("原始文本:" + errsent + "\n==>\n" + "修正后的文本:" + correct_sent) if __name__ == "__main__": main()结果: 来源# @Author: yudengwu 资源链接: 文中所用的停用词表:中文文本纠错数据集.zip
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |