首先,謝謝你,你的問題讓我感興趣再加上我正在尋找一些有趣的訓練。下面我已經在你的帖子的評論中提到了我的想法,以及@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也可以),那麼怎麼計算每個字母的頻率並將這個分佈與典型的英語語言進行比較。 –