首先,谢谢你,你的问题让我感兴趣再加上我正在寻找一些有趣的训练。下面我已经在你的帖子的评论中提到了我的想法,以及@swbandit的想法。通过修改is_rnd
函数也可以在代码中添加任何其他策略。 我已经产生从这里(https://gist.github.com/jbergantine/2390284)发现短期字典意识字符串(当然这字典是小,可能不具有代表性,但是我用它用于测试目的)。这些字符串在代码中被认为是strok
。之后,生成相同长度的随机字符串(strrnd
)。我只使用小写字母,并假定字符串中没有空格。
函数is_rnd1
和is_rnd2
返回True
如果字符串是随机的。函数is_rnd1
检查最频繁的英文字符'e'(12.7%)和最罕见的'z'(0.074%)的频率。但是,在该功能中,频率的边界显着扩大。功能is_rnd2
只是检查@swbandit建议的连续四个辅音的外观。
在上面所描述的功能的代码的测试部分用于其在构成strok
字数来衡量串的不同长度进行测试。函数is_rnd
被调用两次。首先用strok
,然后用随机字符串。定义字符串随机与否的错误是相加的。
所以这是代码:
nouns = ['here is a list from gist.github.com/jbergantine/2390284']
allch = "abcdefghijklmnopqrstuvwxyz"
import numpy as np
import matplotlib.pyplot as plt
import random, string
import collections
import re
alb = 'etaoinshrdlcumwfgypbvkjxqz'
def frqlist(s):
dic = collections.Counter(s)
arr = np.zeros(len(alb))
for key in dic:
idx = alb.index(key)
arr[idx] = float(dic[key])/float(len(s))
return arr
def generate_strs(nw=1):
strok = ''.join([nouns[random.randrange(0, len(nouns))]
for i in range(nw)])
rand_str = lambda n: ''.join([random.choice(string.lowercase)
for i in xrange(n)])
strrnd = rand_str(len(strok))
return strok, strrnd
def is_rnd1(s):
fq = frqlist(s)
return not (fq[0] > 0.07 and fq[-1] < 0.01)
def is_rnd2(s):
return re.search(r'[^aeiou]{4}', s)
maxwords = 12
nprobe = 1000
is_rnd = is_rnd1
nwa = []
err = []
print "Words\t% of errors"
for nw in range(1, maxwords):
errok = 0
errrnd = 0
for i in range(0, nprobe):
strok, strrnd = generate_strs(nw)
if is_rnd(strok):
errok += 1./nprobe
if not is_rnd(strrnd):
errrnd += 1./nprobe
print nw, "\t", (errok*100. + errrnd*100.)/2.
nwa.append(nw)
err.append((errok*100. + errrnd*100.)/2.)
plt.plot(nwa, err)
plt.show()
下面是一些结果
For function is_rnd1
Words % of errors
1 28.2
2 20.45
3 17.15
4 13.15
5 13.7
6 10.65
7 9.25
8 7.35
9 6.5
For function is_rnd2 (4 consecutive consonants)
Words % of errors
1 23.15
2 13.0
3 13.55
4 17.75
5 22.2
6 24.35
7 27.7
8 30.6
9 33.25
For function is_rnd2 (6 consecutive consonants)
Words % of errors
1 39.45
2 20.8
3 11.9
4 6.5
5 4.05
6 3.05
7 2.5
8 1.6
9 2.0
对我来说结果很有趣。
UPDATE:
我已经试过机器学习。我用了一个有26个入口和一个出口的神经元。在入口处提供字符串中字符的频率。如果字符串是随机的,则输出为1,否则为0。神经元是由下面的类描述:
class Neuron(object):
def __init__(self, nin, wt=0.):
self.nin = nin
self.w = np.full(nin, wt, dtype=np.float32)
self.out = 0.
self.learnspd = 0.01
def result(self, ins):
self.out = np.sum(self.w * ins)
self.out = 1. if self.out > 0.1 else 0.
return self.out
def correctw(self, ins, err):
self.w = self.w + err*self.learnspd*ins
确定其学习的过程,实现了神经元neuron = Neuron(len(alb))
后:
def learning(neuron, nset, maxwords):
for i in xrange(nset):
nw = np.random.randint(1, maxwords+1)
strok, strrnd = generate_strs(nw)
fq = frqlist(strok)
neurres = neuron.result(fq)
errok = 0.0 - neurres
neuron.correctw(fq, errok)
fq = frqlist(strrnd)
neurres = neuron.result(fq)
errrnd = 1.0 - neurres
neuron.correctw(fq, errrnd)
让我们来学习learning(neuron, nset, maxwords)
。
Finaly,神经元可用于:
def is_rnd_neuron(s, neuron):
fq = frqlist(s)
return bool(neuron.result(fq))
使用相同的测试步骤描述上面我已经得到了以下结果:
nset = 100
Words % of errors
1 50.0
2 50.0
3 50.0
4 50.0
5 50.0
6 50.0
7 50.0
8 50.0
9 50.0
nset = 500
Words % of errors
1 20.4
2 13.25
3 9.5
4 5.55
5 5.95
6 3.9
7 3.35
8 2.55
9 2.4
nset = 1000
Words % of errors
1 16.95
2 9.35
3 4.55
4 2.4
5 1.7
6 0.65
7 0.4
8 0.15
9 0.1
nset = 5000
Words % of errors
1 16.6
2 7.25
3 3.8
4 1.8
5 1.1
6 0.5
7 0.1
8 0.1
9 0.05
我真的很感动有多么容易被意识到它会产生多好的结果。
NLTK可能证明对此有用。 – sytech
假设有效令牌包含英文,无效令牌将有更多的连续4个或更多的辅音。 – swbandit
乍看之下,如果字符串的长度足够大(25-80也可以),那么怎么计算每个字母的频率并将这个分布与典型的英语语言进行比较。 –