当前位置:   article > 正文

用 Python 实现英文单词纠错功能

pycorrecter github

单词纠错

  在我们平时使用Word或者其他文字编辑软件的时候,常常会遇到单词纠错的功能。比如在Word中:

640?wx_fmt=png
单词拼写错误

单词纠错算法

  首先,我们需要一个语料库,基本上所有的NLP任务都会有语料库。单词纠错的语料库为bit.txt,里面包含的内容如下:

  • Gutenberg语料库数据;

  • 维基词典;

  • 英国国家语料库中的最常用单词列表。

下载的网址为:https://github.com/percent4/-word- 。

Python实现

  实现单词纠错的完整Python代码(spelling_correcter.py)如下:

  1. # -*- coding: utf-8 -*-
  2. import re, collections
  3. def tokens(text):
  4.     """
  5.     Get all words from the corpus
  6.     """
  7.     return re.findall('[a-z]+', text.lower())
  8. with open('E://big.txt''r'as f:
  9.     WORDS = tokens(f.read())
  10. WORD_COUNTS = collections.Counter(WORDS)
  11. def known(words):
  12.     """
  13.     Return the subset of words that are actually
  14.     in our WORD_COUNTS dictionary.
  15.     """
  16.     return {w for w in words if w in WORD_COUNTS}
  17. def edits0(word):
  18.     """
  19.     Return all strings that are zero edits away
  20.     from the input word (i.e., the word itself).
  21.     """
  22.     return {word}
  23. def edits1(word):
  24.     """
  25.     Return all strings that are one edit away
  26.     from the input word.
  27.     """
  28.     alphabet = 'abcdefghijklmnopqrstuvwxyz'
  29.     def splits(word):
  30.         """
  31.         Return a list of all possible (first, rest) pairs
  32.         that the input word is made of.
  33.         """
  34.         return [(word[:i], word[i:]) for i in range(len(word) + 1)]
  35.     pairs = splits(word)
  36.     deletes = [a + b[1:] for (a, b) in pairs if b]
  37.     transposes = [a + b[1] + b[0] + b[2:] for (a, b) in pairs if len(b) > 1]
  38.     replaces = [a + c + b[1:] for (a, b) in pairs for c in alphabet if b]
  39.     inserts = [a + c + b for (a, b) in pairs for c in alphabet]
  40.     return set(deletes + transposes + replaces + inserts)
  41. def edits2(word):
  42.     """
  43.     Return all strings that are two edits away
  44.     from the input word.
  45.     """
  46.     return {e2 for e1 in edits1(word) for e2 in edits1(e1)}
  47. def correct(word):
  48.     """
  49.     Get the best correct spelling for the input word
  50.     """
  51.     # Priority is for edit distance 0, then 1, then 2
  52.     # else defaults to the input word itself.
  53.     candidates = (known(edits0(word)) or
  54.                   known(edits1(word)) or
  55.                   known(edits2(word)) or
  56.                   [word])
  57.     return max(candidates, key=WORD_COUNTS.get)
  58. def correct_match(match):
  59.     """
  60.     Spell-correct word in match,
  61.     and preserve proper upper/lower/title case.
  62.     """
  63.     word = match.group()
  64.     def case_of(text):
  65.         """
  66.         Return the case-function appropriate
  67.         for text: upper, lower, title, or just str.:
  68.         """
  69.         return (str.upper if text.isupper() else
  70.                 str.lower if text.islower() else
  71.                 str.title if text.istitle() else
  72.                 str)
  73.     return case_of(word)(correct(word.lower()))
  74. def correct_text_generic(text):
  75.     """
  76.     Correct all the words within a text,
  77.     returning the corrected text.
  78.     """
  79.     return re.sub('[a-zA-Z]+', correct_match, text)

测试

  有了上述的单词纠错程序,接下来我们对一些单词或句子做测试。如下:

  1. original_word_list = ['fianlly''castel''case''monutaiyn''foresta', \
  2.                       'helloa''forteen''persreve''kisss''forteen helloa', \
  3.                       'phons forteen Doora. This is from Chinab.']
  4. for original_word in original_word_list:
  5.     correct_word = correct_text_generic(original_word)
  6.     print('Orginial word: %s\nCorrect word: %s'%(original_word, correct_word))

输出结果如下:

Orginial word: fianlly

  接着,我们对如下的Word文档(Spelling Error.docx)进行测试(下载地址为:https://github.com/percent4/-word-),

640?wx_fmt=png
有单词错误的Word文档

对该文档进行单词纠错的Python代码如下:

  1. from docx import Document
  2. from nltk import sent_tokenize, word_tokenize
  3. from spelling_correcter import correct_text_generic
  4. from docx.shared import RGBColor
  5. # 文档中修改的单词个数
  6. COUNT_CORRECT = 0
  7. #获取文档对象
  8. file = Document("E://Spelling Error.docx")
  9. #print("段落数:"+str(len(file.paragraphs)))
  10. punkt_list = r",.?\"'!()/\\-<>:@#$%^&*~"
  11. document = Document()   # word文档句柄
  12. def write_correct_paragraph(i):
  13.     global COUNT_CORRECT
  14.     # 每一段的内容
  15.     paragraph = file.paragraphs[i].text.strip()
  16.     # 进行句子划分
  17.     sentences = sent_tokenize(text=paragraph)
  18.     # 词语划分
  19.     words_list = [word_tokenize(sentence) for sentence in sentences]
  20.     p = document.add_paragraph(' '*7)  # 段落句柄
  21.     for word_list in words_list:
  22.         for word in word_list:
  23.             # 每一句话第一个单词的第一个字母大写,并空两格
  24.             if word_list.index(word) == 0 and words_list.index(word_list) == 0:
  25.                 if word not in punkt_list:
  26.                     p.add_run(' ')
  27.                     # 修改单词,如果单词正确,则返回原单词
  28.                     correct_word = correct_text_generic(word)
  29.                     # 如果该单词有修改,则颜色为红色
  30.                     if correct_word != word:
  31.                         colored_word = p.add_run(correct_word[0].upper()+correct_word[1:])
  32.                         font = colored_word.font
  33.                         font.color.rgb = RGBColor(0x000x000xFF)
  34.                         COUNT_CORRECT += 1
  35.                     else:
  36.                         p.add_run(correct_word[0].upper() + correct_word[1:])
  37.                 else:
  38.                     p.add_run(word)
  39.             else:
  40.                 p.add_run(' ')
  41.                 # 修改单词,如果单词正确,则返回原单词
  42.                 correct_word = correct_text_generic(word)
  43.                 if word not in punkt_list:
  44.                     # 如果该单词有修改,则颜色为红色
  45.                     if correct_word != word:
  46.                         colored_word = p.add_run(correct_word)
  47.                         font = colored_word.font
  48.                         font.color.rgb = RGBColor(0xFF0x000x00)
  49.                         COUNT_CORRECT += 1
  50.                     else:
  51.                         p.add_run(correct_word)
  52.                 else:
  53.                     p.add_run(word)
  54. for i in range(len(file.paragraphs)):
  55.     write_correct_paragraph(i)
  56. document.save('E://correct_document.docx')
  57. print('修改并保存文件完毕!')
  58. print('一共修改了%d处。'%COUNT_CORRECT)

输出的结果如下:

修改并保存文件完毕!

修改后的Word文档如下:

640?wx_fmt=png
单词纠错后的Word文档

其中的红色字体部分为原先的单词有拼写错误,进行拼写纠错后的单词,一共修改了19处。

总结

  单词纠错实现起来并没有想象中的那么难,但也不是那么容易~https://github.com/percent4/-word- 。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/371005
推荐阅读
相关标签
  

闽ICP备14008679号