Хорошо, я не уверен, что именно вы хотите сделать.Но давайте все равно попробуем.
Во-первых, как работает N-грамм: N-граммы - довольно простые предикторы вероятности последовательности.Поскольку предложения - это просто последовательности слов, а слова - просто последовательность символов, обычно это прекрасно работает для строк:
Проблема: у вас есть список букв, и вы хотите узнать, какой будет следующая буква впоследовательность.
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-граммы зависитналичие конечного набора элементов (символов, слов, натуральных чисел и т. д.).Теперь, в ВАШЕМ примере, "vocabs" и "training_data" имеют едва ли общие числа.И я думаю, что вам действительно нужно набрать дистанцию между вашими словами.Я предполагаю, что из-за того, что вы сказали:
В примере, который я хотел показать, тренировочные "слова" (список из 3-х чисел) не совсем совпадают с "словами"в моем словаре, но они будут очень близки.
В этом случае будет слишком сложно показать это здесь, но вы можете измерить расстояние между
каждое числокаждый элемент в "vocabs"
и
каждый номер каждого элемента в каждой последовательности в "training_data"
, а затем сравните их и выберите меньшую оценку.
Если это не ответ на ваш вопрос, пожалуйста, переформулируйте или приведите больше примеров.В любом случае, удачи с этим.