好的,我不确定你到底想做什么。不过我们还是试试吧。
首先,N-gram 是如何工作的:
N-gram 是序列概率的非常简单的预测器。由于句子只是单词序列,单词只是字符序列,因此它通常适用于字符串:
问题:你有一个字母列表,你想找出序列中的下一个字母是什么。
letterSequence = ['a', 'b', None]
如果你有一堆字母按顺序排列,你可以记下这些序列是什么:
training_data = ['a', 'b', 'c',
'a', 'b', 'c',
'a', 'b', 'd',
'a', 'b', 'f',
'b', 'c', 'd']
乍一看,你可以看到序列 'a','b','c' 的概率是 'a','b','d' 或 'a' 的概率的两倍','b','f'。
我们要做的是统计相同序列在training_data中出现的次数,然后选择出现频率更高的那个。
def makeNestedDict(aDict, listOfKeys):
if len(listOfKeys) == 0:
if aDict != {}: return aDict
return 0
if listOfKeys[0] not in aDict:
aDict[listOfKeys[0]] = {}
aDict[listOfKeys[0]] = makeNestedDict(aDict[listOfKeys[0]], listOfKeys[1:])
return aDict
def makeCoreferenceDict(ressource):
#we'll use 3-grams but we could have chosen any n for n-grams
ngramDict = {}
index = 0
#we make sure we won't go further than the length of the list
while (index+2) < len(ressource):
k1 = ressource[index]
k2 = ressource[index+1]
k3 = ressource[index+2]
ngramDict = makeNestedDict(ngramDict, [k1, k2, k3])
ngramDict[k1][k2][k3] += 1 #counting
index += 1
return ngramDict
def predict(unkSequence, ngramDict):
import operator
corefDict = ngramDict[unkSequence[0]][unkSequence[1]]
return max(corefDict.items(), key=operator.itemgetter(1))
############################################
ngramDict = makeCoreferenceDict(training_data)
#the most common letter that follows 'a', 'b' is...
predict(letterSequence, ngramDict)
>>> ('c', 2) #... is 'c' and it appears twice in the data
您还可以通过替换行(在 makeCoreferenceDict 函数中)来获得预测分数,而不是获得最常见的元素:
ngramDict[k1][k2][k3] += 1 #counting
与:
ngramDict[k1][k2][k3] += 1.0/float(len(ressource)) #add to the score
所以:
def showScore(unkSequence, ngramDict):
return ngramDict[unkSequence[0]][unkSequence[1]]
############################################
ngramDict = makeCoreferenceDict(training_data)
#the most common letter that follows 'a', 'b' is...
showScore(letterSequence, ngramDict)
>>> {'c': 0.13333333333333333, 'd': 0.06666666666666667, 'f': 0.06666666666666667}
现在,n-gram 方法依赖于有限的元素集(字符、单词、自然数等)。现在,在您的示例中,“vocabs”和“training_data”几乎没有任何共同点。而且我认为您真正需要的是获得单词之间的距离分数。我猜是因为你说的:
在我想展示的示例中,训练“单词”(3 个数字的列表)与我的词汇表中的“单词”并不完全相同,但它们会非常接近。
在这种情况下,在这里显示它有点太复杂了,但你可能想测量它们之间的距离
“词汇”中每个元素的每个数字
和
“training_data”中每个序列中每个元素的每个数字
然后比较它们并选择较小的分数。
如果这不是您问题的答案,请重新表述或给我们提供更多示例。
无论如何,祝你好运。