Создать модель N-граммы для пользовательского словаря - PullRequest
0 голосов
/ 12 декабря 2018

Я хочу создать модель N-Gram, которая не будет работать с «английскими словами».У меня есть собственный список слов, как показано ниже:

vocabs = [[0.364, 0.227, 0.376], [0.875, 0.785, 0.376], ........]

Что я пытаюсь сказать, так это то, что каждый элемент в моем списке слов должен рассматриваться как «слово» в моделях N-Gram.И мой обучающий набор данных будет иметь некоторые числа точно в том же формате, что и мой список слов, как показано ниже:

training_data = [[0.344, 0.219, 0.374], [0.846, 0.776, 0.376],........]

Примечание: В примере, который я хотел показать, тренировочные "слова" (список из 3 чисел) не совсем совпадаюткак «слова» в моем словаре, но они будут очень близки.

Теперь, мой вопрос, могу ли я построить модель N-Gram, которую можно тренировать, используя данные обучения?А позже используйте эту модель, чтобы предсказать вероятность появления нового «слова».

Я использую python и могу найти множество примеров N-Gram, используя " nltk "библиотека.Но проблема в том, что в большинстве случаев используются «английские слова».Так как я не очень знаком с N-Grams, эти примеры привели меня в замешательство.Я буду очень рад, если кто-нибудь ответит на мои вопросы и / или укажет несколько уроков для изучения N-граммы в целом (не относится к НЛП).

Спасибо.

Редактировать:

Просто, чтобы упростить вопрос, я попытаюсь объяснить его по-другому: у меня есть словарный запас, как показано ниже:

vocabs = [v1, v2, v3, ........ vn]

У меня также есть генератор двух последовательностей (SG).Оба они генерируют последовательность слов из моего словаря.

Моя цель - предсказать из потоковых данных: какой генератор в настоящее время генерирует последовательность (слова).

Теперь я хочу построить две N-граммовые модели (по одной для каждого SG), используя мои помеченные тренировочные данные (у меня уже есть некоторые помеченные данные из SG).Наконец, когда я передаю свои потоковые данные в модели и выбираю вероятный SG, сравнивая прогнозы из N-граммных моделей.Просто для ясности, если N-граммовая модель для SG1 дает более высокую вероятность, чем N-граммовая модель для SG2, я решу, что текущие потоковые данные генерируются SG1.

Надеюсь, что объяснение поможет понять моибеспокойство.Я действительно ценю усилия, чтобы ответить на этот вопрос.

Примечание: Если вы знаете какие-либо другие модели, которые могут решить эту проблему хорошо (лучше, чем модель N-граммы), пожалуйста, укажите их.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

В этом случае вы определенно можете использовать n-грамм.

Сначала позвольте мне убедиться, что я понял:

У вас есть словарь:

vocabs = [v0, v1, v2, v3, ........ vn]

и 2 генератора последовательностей, которые берут элементы из вашего вокаба и возвращают список последовательностей вокаба:

sg1 = [v0, v1, v2,v1, v3] sg2 = [v2, v4, v6, v2, v8]

Теперь, если я правильно понимаю, вы хотите использовать n-граммы для искусственной репликации и увеличения выходов sg1 и sg2:

ngramSg1 = [v0, v1, v3, v0, v1, v2, v1, v2, ...] ngramSg2 = [v2, v4, v6, v2, v8, v2, v6,v2, ...]

Затем вы хотите использовать модель ML, чтобы определить, из какого источника выводится н-грамм (либо SG1, либо SG2).Я прав?Я об этом говорю?

Если это похоже на то, что я описал, тогда вы сможете использовать код, который я написал в предыдущем ответе, или любую библиотеку n-грамм, которую вы хотите.Тем не менее, если я правильно понял, ваш словарный запас состоит из списков чисел, а не отдельных объектов.Если это так, то вы, вероятно, не найдете ни одной библиотеки, которая справится с этим.Это слишком специфично.Возможно, вам придется написать собственную версию генератора последовательностей на основе n-граммы.

Однако ваш случай выглядит довольно знакомым для встраивания слов (которые в основном представляют собой алгоритмы языковой обработки, которые используют векторы в качестве представления слов).Если вы еще не знаете о них, вы можете проверить word2vec , doc2vec или fastText компании gensim и либо принять их, либо адаптировать их.

0 голосов
/ 14 декабря 2018

Хорошо, я не уверен, что именно вы хотите сделать.Но давайте все равно попробуем.

Во-первых, как работает 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"

, а затем сравните их и выберите меньшую оценку.

Если это не ответ на ваш вопрос, пожалуйста, переформулируйте или приведите больше примеров.В любом случае, удачи с этим.

...