关于拼写纠正的一点发现

发现

​ 在对着课件仔细更改一点小错误后,测试了几遍,效果不错。当我进行效果统计时,通过下面代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#! /usr/bin/env python  
#! -*- coding:utf-8 -*-  
#====#====#====#====  
#!@Author : px
#!@time : 2020/3/28 22:04
#!@File : test比较
#====#====#====#====  
import sys
import re
def read_file(filename):
try:
fp=open(filename)
text=fp.read()
except IOError:
print(filename,"文件打开失败")
sys.exit()
#print(text)
return text
A = re.findall(r'\w+', read_file('batch0.tab.txt').lower())
#print(A)
print(len(A))
print(len([1,2,3,4,5,6,7,8,9]))
print(4206*2)
j=1
for i in A:
print(i,j)
j+=1
print(len(A))

​ 我用的测试文件是两个竖排的单词组,理论上应该是偶数才对,而且通过在线字数统计得出结果也可推断出问题了。

情况1明偶却奇.PNG

​ 通过对相似单词检查奇偶性,发现情况1问题位置.PNG

​ 对比原文,发现情况1问题出处.PNG

这说明对于含有 的单词,代码并没有识别成一个。通过\w’\w语料库测试文件的查找,也发现文本里有许多这种单词。对A(代码里的A)使用\w'\w,也可说明代码没有把这种单词识别为一个单词。通过A = re.findall(r'\w+', read_file('batch0.tab.txt').lower())更说明没有把这种单词识别为一个单词。

修改

​ 方案一: 使用A = re.findall(r'\w+\'?\w+', read_file('batch0.tab.txt').lower())

情况1问题解决.PNG

新问题

​ 由于更改了规则,语言模型里有类似can't的单词,所以在字母替换时要注意',所以将alphabeta='qwertyuiopasdfghjklzxcvbnm'更改为alphabeta='qwertyuiopasdfghjklzxcvbnm\'

统计方式

  1. 文本里有两列,一列错误,一列期望结果。 (我觉得慢)
  2. 文本好几行,一行第一个错误,其余期望结果。(我还可以接受)
  3. 使用原作者的方式,把原作者的的部分代码放入我的代码里修修补补。 (我还可以接受)

又发现新问题

有的单词通过-连接成一个单词,可以通过A = re.findall(r'\w+-?\w+', read_file('batch0.tab.txt').lower())

其实对于-'应可以不考虑,因为这样的单词比较少。当然也可以改进,用A = re.findall(r'\w+\'?-?\w+', read_file('batch0.tab.txt').lower()).

或许还有其他类型的单词,但道理差不多。

新知识

  1. python lambda:
  2. python from import
  3. python if for
  4. python set

一些感悟

  1. python 突然感觉挺有趣,挺好玩的。
  2. 这一次知识点感觉好多,好累啊。
  3. 如果以后做报表这类的或许会打算用python自动化。

代码

虽然我的博客没人看,但后期大概率会通过一些手段(由于是静态页面,所以这个手段拦不住一些有心人,当然我也愿意给他看)把一些地方(比如代码)隐藏掉,时间过了再显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#! /usr/bin/env python  
#! -*- coding:utf-8 -*-  
#====#====#====#====  
#!@Author : px
#!@time : 2020/3/26 16:08
#!@File : 3-26-1
#====#====#====#===
#拼写纠正
import sys
import math
#
def read_file(filename):
try:
fp=open(filename)
text=fp.read()
except IOError:
print(filename,"文件打开失败")
sys.exit()
#print(text)
return text
#分词
import re
def words(text):
#1
#A=re.findall('[a-z]+',text.lower())
#2
A = re.findall(r'\w+\'?\w+', text.lower())
#print(A)
return A
#统计词频 语言模型训练
import collections
def train(features):
#初始化模型 得到默认字典 value=1
model=collections.defaultdict(lambda :1)
for f in features:
model[f]= model[f]+1
#print("model: ",model)
return model
A=words(read_file("big.txt"))
###############################
#添加的
from collections import Counter
WORDS=Counter(A)
#############################
NWORDS=train(A)
#print(len(A))
P=sum(NWORDS.values())
#print(NWORDS["the"],NWORDS["they"],NWORDS["that"])

#判读单词是否在字典,错误则纠正
def known(words):#不在则返回空
return (set(w for w in words if w in NWORDS))

alphabeta='qwertyuiopasdfghjklzxcvbnm\''
#编辑距离为的可能单词
def edist1(word):
n=len(word)
s1=[word[0:i]+word[i+1:] for i in range(n)]
#print(s1)#删除单词中的字母
s2=[word[0:i]+word[i]+word[i+2:] for i in range(n-1)]
#print(s2)# 单词字母错位
s3=[word[0:i]+c+word[i+1:] for i in range(n) for c in alphabeta]
#print(s3,len(s3))#字母替换
s4=[word[0:i]+c+word[i:] for i in range(n) for c in alphabeta]
#print(s4,len(s4))#字母插入
return (set(s1+s2+s3+s4))
#编辑距离为2,递归
def edist2(word):
return (set(e2 for e1 in edist1(word) for e2 in edist1(e1)))
def known_edist2(word):
return (set(e2 for e1 in edist1(word) for e2 in edist1(e1) if e2 in NWORDS))
#选择最大可能的单词
def correct(word):
#短路运算 candidates 列表
candidates=known([word]) or known(edist1(word)) or known(edist2(word)) or [word]
return max(candidates,key=lambda w:NWORDS[w])
def count():
batch0=read_file('batch0.tab.txt')
batch0words=words(batch0)
print(len(batch0words),batch0words[0],batch0words[1])
con=0
for i in range(len(batch0words)//2):
if (correct(batch0words[2*i]) == batch0words[2*i+1]):
con+=1
#print("con",con)
#print("i",i)
print(con/(len(batch0words)*0.5))

def read_file_lines(filename):
try:
fp=open(filename)
text=fp.readlines()
except IOError:
print(filename,"文件打开失败")
sys.exit()
#print(text)
return text
def count2():
con=0
words_line=read_file_lines("3.txt")#一排一排的记录
#print(len(words_line),words_line[0],words_line[1])
for linewords in words_line:#取一排
B=words(linewords)#一排转换为单词列表
if correct(B[0]) in B:
con+=1
print(con/len(words_line))

#############################
#添加的
#将unit_test删除了
def spelltest(tests, verbose=False):
"Run correction(wrong) on all (right, wrong) pairs; report results."
import time
start = time.perf_counter()
good, unknown = 0, 0
n = len(tests)
for right, wrong in tests:
w = correct(wrong)
good += (w == right)
if w != right:
unknown += (right not in WORDS)
if verbose:
print('correction({}) => {} ({}); expected {} ({})'
.format(wrong, w, WORDS[w], right, WORDS[right]))
dt = time.perf_counter() - start
print('{:.0%} of {} correct ({:.0%} unknown) at {:.0f} words per second '
.format(good / n, n, unknown / n, n / dt))


def Testset(lines):
"Parse 'right: wrong1 wrong2' lines into [('right', 'wrong1'), ('right', 'wrong2')] pairs."
return [(right, wrong)
for (right, wrongs) in (line.split(':') for line in lines)
for wrong in wrongs.split()]


# print(unit_tests())
# spelltest(Testset(open('spell-testset1.txt'))) # Development set
# spelltest(Testset(open('spell-testset2.txt'))) # Final test set
############################

def main():
while(1):
wrd=input("输入单词")
print("edist1: ",known(edist1(wrd)))
print("known_edist2: ",known_edist2(wrd))
print(correct(wrd))
#print()
# print(unit_tests())#我删除了

# spelltest(Testset(open('spell-testset1.txt'))) # Development set
# spelltest(Testset(open('spell-testset2.txt')))
# wrd = input("输入单词")
# print("edist1: ",known(edist1(wrd)))
# print("known_edist2: ",known_edist2(wrd))
# print(correct(wrd))
# #count()
# count2()

if __name__ == '__main__':
main()