Теги: Python, Машинное обучение, Искусственный интеллект, Поисковая система, Обработка естественного языка, Наука о данных, Курс AppliedAI, A26, DataTorch

Чтобы реализовать Bag of the word, мы должны сначала определить, во сколько вам обходится семантическое сходство.

Прежде чем начать с Bag of words, позвольте мне объяснить вам несколько терминов:

1-грамм, 2-грамм, 3-грамм, n-грамм.

1 грамм разбивает слова пробелом.

пример:

query = «сегодня мы изучаем машинное обучение»

1 грамм: «сегодня», «мы», «учимся», «машина», «учимся»

по поводу 2 грамм: «сегодня мы», «изучаем», «изучаем машину», «машинное обучение»

по поводу 3 грамм: «сегодня мы изучаем», «изучаем машинное обучение», «изучаем машинное обучение»

это набор слов, который мы будем называть биграммой.

В нашем примере мы рассмотрим случай, когда порядок не имеет значения.

Чтобы сделать это как можно более дешевым, мы возьмем только биграмм. Если такой терпеливый читатель, как вы, имеет достаточно вычислений, я рекомендую перейти на 3 грамма без заказа.

без порядка в смысле наша биграмма будет увеличиваться.

2-грамма: «сегодня мы», «мы сегодня», «мы учимся», «изучаем мы», «изучаем машину», «машинное исследование», «машинное обучение», «обучающаяся машина»

3-грамм: «сегодня мы изучаем», «сегодня изучаем мы», «изучаем сегодня мы», «изучаем мы сегодня», «мы сегодня изучаем», «мы сегодня изучаем», «изучаем машину»,
«мы изучаем машины», «изучаем мы машины», «изучаем машины мы», «машины изучаем мы», «машины изучаем мы», «изучаем машинное обучение», «изучаем машины обучения», «машины изучаем обучение», «машины изучение обучения», «обучение учебной машины», «обучение учебной машины»

если мы берем 1 грамм, 2 грамма и 3 грамма вместе, то мы должны объединить их все.

Чем больше вы идете, тем более затратным в вычислительном отношении становится, позвольте мне объяснить вам, почему!

«Мешок слов» основан на стратегии, согласно которой, когда мы получаем слово, мы сначала преобразуем его в n-граммы. и каждая n-грамма теперь представляет собой столбец, и для каждой строки мы поставим 1, если это слово или пара слов присутствуют.

Например, возьмем 2 грамма в одном направлении.

«викалп — хороший мальчик», «викалп учится машинному обучению»

поэтому общая биграмма будет иметь:

«викальп есть», «является собой», «хороший», «хороший мальчик», «учится», «обучающая машина», «машинное обучение»

не забывайте про 1 грамм, тогда наши итоговые столбцы станут:

«викальп», «есть», «а», «хороший», «мальчик», «обучается», «машина», «обучается», «викалп есть», «есть», «хороший», «хороший мальчик », «обучается», «обучающаяся машина», «машинное обучение»

Но конкретно для нашего случая, когда вам нужно создать очень хороший алгоритм, мы будем использовать наш словарь как без какой-либо конкретной направленности. это может быть в любой комбинации. наши комбинации:

«викальп», «это», «а», «хороший», «мальчик», «обучение», «машина», «обучение», «викалп это», «это викальп», «это», «а это », «хороший», «хороший», «хороший мальчик», «хороший мальчик», «обучение есть», «учится», «обучающая машина», «машинное обучение»

Давайте посетим часть реализации

getBiGram(query): функция, определяющая реализацию запроса.

Строка 3: она разделит строку по пробелу, хранящемуся в qu_array

Строка 7–9 выберет реализацию, где она будет проходить запрос один за другим и извлекать i-е слово, присоединенное к (i+1)-му слову, хранящемуся в qu_array2.

Строка 11: он суммирует оба массива (добавляя биграмм и 1 грамм вместе).

Строка 12: он преобразует список в набор и снова в список, что удалит повторяющиеся граммы.

Строка 13: мы возвращаем массив, содержащий 1 грамм и 2 грамма.

Теперь для каждой строки мы должны поддерживать набор слов (BOW), который будет поддерживать 1, где слово присутствует или нет. Нам приходит на ум вопрос, какова лучшая и быстрая логика, с помощью которой мы можем создать BOW, где каждая конкретная строка будет хранить 1 в конкретном индексе, а для остальных индексов он должен быть 0? строка за строкой он должен быть статичным, чтобы значения двух столбцов не смешивались.

Ответ поясняется ниже:

Мы должны создать словарь, который содержит индекс. индекс словаря — это не что иное, как номер столбца. Если конкретное слово появится в корпусе, словарь даст номер столбца с временной сложностью O(1). (Pss: это означает очень-очень быстро.)

Теперь нам нужно создать словарь

Строка 7: для каждого запроса во фрейме данных

Строка 11. as «getBigram» даст список биграмм. мы будем хранить в словаре, где значения длины словаря

установить функцию: она удалит избыточность; список: это сделает набор в виде списка; «Функция zip» будет принимать два аргумента и упаковывать их вместе, где первый аргумент — это полный запрос, а следующий аргумент — число от 0 до длины «full_qu», используя функцию «диапазон».

мы вернем этот словарь, поскольку мы должны использовать его во всей нашей реализации.

Строка 14–16 даст вам тестовый код, как это будет работать.

Давайте двинемся дальше и создадим логику для переноса каждой строки в ячейки BOW.

Строка 6: обрабатывает исключение словарного ключа. он вернет ключ, если он присутствует, иначе None, если нет. (В Python мы не можем оставить строку пустой, поэтому ключевое слово «pass» работает, если вы действительно ничего не хотите делать.)

Строка 13: это список нулей, длина которого равна количеству ключей в нашем уже подготовленном словаре биграмм.

Строка 15: для каждого значения в списке биграмм, сгенерированных из запроса, мы должны выполнить следующие шаги.

Строка 16–18 создаст список с именем ls, в котором присутствуют все значения из корпуса, он вернет список номеров столбцов и сохранит его в ls.

Строка 20–22: она поставит 1 везде, где в списке присутствуют значения столбцов.

что действительно даст вам корзину с несколькими 1 и 0, где 1 представляют, присутствует ли конкретное слово или нет.

Теперь нам нужно преобразовать эти строки в матрицу, содержащую BOW. Поскольку этот BOW имеет очень большой словарь, и большинство из них содержит 0 и очень мало единиц. см. рисунок (Рисунок 1. BOW для двух документов.) мы должны преобразовать матрицу в разреженную матрицу, иначе для плотной матрицы это будет пустая трата места.

чтобы преобразовать разреженную матрицу, мы должны импортировать «coo_matrix» из класса «sparse», который находится в пакете «scipy».

формат ввода описан ниже:

для матрицы, показанной на рисунке:

это будет:

ряд: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

столбец: [0, 1, 2, 3, 4, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 5, 6, 7, 8, 15, 16, 17, 18]

данные [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

Переходим к части реализации:

для каждого запроса в query_list,

Строка 13: мы извлекаем список в корзину

Строка 14: данные бина — все единицы.

Строка 15: row_numbers - это текущий индекс.

Строка 16: возврат индексов, столбцов и данных (единиц).

Перешел к кому? Передано в coo_matrix.

Строка 7: это синтаксис, в котором мы передаем значения, полученные из строки 2.

Строка 4–9: мы найдем теги в запросе. (Мы можем реализовать нашу собственную версию, чтобы найти теги и заменить их этими строками.)

Строка 12-14 найдет все документы для поиска в словаре. потому что, если присутствует несколько тегов, он объединит все эти документы.

Строка 19–27 найдет docid в кадре данных и передаст нам строку, над которой мы должны выполнить операции. (К сожалению, у меня не было времени выяснить, почему «x = df[df[«Id»]==doc_id] ” не работало, но это нормально, тем временем мы должны найти решение).

Строки с 29 по 33 являются исключительным условием, если мы не можем найти какие-либо строки во фрейме данных, который ранее был найден в той же базе данных. Мы добавим тело результата в список result_body (строка 34) и идентификаторы результатов в списки result_id (строка 35), чтобы продемонстрировать их позже.

Строки 38 и 39 преобразуют документы и запросы в бины, чтобы мы могли найти соответствие между ними.

Строка 40: найдет расстояние между двумя полями. на данный момент мы приняли его за базовое манхэттенское расстояние.

Строка 41–48: преобразует расстояние в стандартную форму, поэтому релевантность не должна влиять на нашу будущую реализацию. все будет работать, если вы пропустите эти строки, но мы узнаем о важности в нашей следующей серии блогов.

Строка 49: это отсортирует релевантность в порядке убывания и вернет индексы массива.

Строка 54-60 распечатает отсортированные документы.

Строка 60: вернет общее количество документов, которые нам нужно найти, и массив релевантности, чтобы мы могли использовать его в дальнейших вычислениях в будущем.

Спасибо вам, ребята! Надеюсь, вам понравился мой блог, и если вы зашли так далеко, не забудьте подписаться на меня. Я надеюсь, что пользовательская реализация Bag of words понятна, если не разделы комментариев всегда открыты для энтузиастов, таких как мы. Я надеюсь, что вы будете в курсе моей следующей серии, где мы будем выполнять еще несколько наших техник и объединять их вместе, чтобы увидеть прекрасные результаты.

Ребята, несколько вопросов для размышления:

  1. Как мы можем оптимизировать дальнейший поиск?
  2. Есть ли способ реализовать BOW в более эффективном пространстве?

Как всегда повторяю: я поделюсь кодом через несколько месяцев, но я хочу, чтобы вы, ребята, попробовали себя в этом путешествии по созданию поисковой системы. Оставайтесь голодными, оставайтесь безрассудными, следите за обновлениями!