Сходство Python Spacy без цикла?

1

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

Я успешно создал код, чтобы использовать стандартную функцию сходства в Spacy, однако, поскольку он просматривает массивный список документов, добавляя оценку подобия к pandas df, это занимает слишком много времени.

Есть ли способ вернуть 5 самых похожих документов без добавления цикла и панд? Причина в том, что этот метод возвращает наиболее разумные 5 лучших документов по сравнению с другими (радость слова вложения!)

#load relevant libraries
    import pandas as pd
    import numpy as np
    import spacy
#load spacy model
nlp=spacy.load('Z:\\en_core_web_lg-2.0.0')
#
#Get Doc Corpus
dfCorpus = pd.read_csv('z:\DocumentCorpus.csv', delimiter=',')
##get top 5 using spacy similarity function 
SearchStringCosine = nlp(input('Enter search term:'))
computed_similarities = []
for i in dfCorpus.CorpusInput_Unqiue:
   doc=nlp(i)
   computed_similarities.append((i, SearchStringCosine.similarity(doc)))
computed_similarities = sorted(computed_similarities, key=lambda item: -item[1])
computed_similarities = pd.DataFrame(computed_similarities,columns=   ['CorpusInput_Unique','Score'])
print(computed_similarities[:5]) 
Теги:
machine-learning
python-3.x
similarity
spacy

2 ответа

1

Вычисление косинусного подобия - простая линейная алгебраическая операция, которая может быть эффективно распараллелена. По сути, вы хотите вычислить cos (x, y) = x⋅y/(| x || y |), где ⋅ оператор внутреннего произведения. Вместо того, чтобы перебирать разные xs для заданного y, вместо этого вы могли бы нормализовать y-вектор и x-матрицу, а затем выполнить простой вектор-матричный продукт. Более конкретно, пусть X - ваша матрица векторов векторов размерности Nx300 (N количество документов, 300 количество функций) и y - ваш вектор сравнения размерности (300):

vector_norms = np.array([np.sqrt(np.sum(np.square(v))) for v in X])
X = (X.T / vector_norms).T
similarities = np.matmul(X, y) 
# ... perform index sorting as usual

Это может быть записано в библиотеке линейных алгебр с ускорением GPU, если требуется большая эффективность.

  • 0
    ВАУ, спасибо за отличный быстрый ответ! Я попробую и дам вам знать, как у меня дела. еще раз спасибо.
  • 0
    Мне так и не удалось заставить это работать. Перепробовал так много вариантов, но никогда не мог заставить сходство вызывать на работу, несмотря на нормализацию моего корпуса и условий поиска.
Показать ещё 2 комментария
0

Для тех, кто ищет решение для этого, я нашел, что лучшим методом было рассортировать мой файл с применением spacy vector nlp(), тогда цикл работает почти мгновенно при ссылке на doc_list!

dfCorpusDescr = dfCorpus.fieldname
doc_list={i: nlp(i) for i in dfCorpus}
with open("filename.pickle", 'wb') as pfile:
    pickle.dump(doc_list, pfile, protocol=pickle.HIGHEST_PROTOCOL)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню