Python - tf-idf предсказывает сходство нового документа

Вдохновленный этим ответом, Я пытаюсь найти косинусное сходство между обученным обученным векторизатором tf-idf и новым документом и вернуть аналогичные документы.

Приведенный ниже код находит косинусное сходство первого вектора, а не нового запроса.

>>> from sklearn.metrics.pairwise import linear_kernel
>>> cosine_similarities = linear_kernel(tfidf[0:1], tfidf).flatten()
>>> cosine_similarities
array([ 1.        ,  0.04405952,  0.11016969, ...,  0.04433602,
    0.04457106,  0.03293218])

Поскольку мои данные о поездах огромны, перебирать весь обученный векторизатор кажется плохой идеей. Как я могу вывести вектор нового документа и найти связанные документы, такие же, как в приведенном ниже коде?

>>> related_docs_indices = cosine_similarities.argsort()[:-5:-1]
>>> related_docs_indices
array([    0,   958, 10576,  3277])
>>> cosine_similarities[related_docs_indices]
array([ 1.        ,  0.54967926,  0.32902194,  0.2825788 ])

person Shlomi Schwartz    schedule 25.09.2016    source источник
comment
хотя могут быть и лучшие решения, линейный поиск не обязательно плохая идея и может быть быстрым, если его правильно реализовать, насколько велик ваш набор данных? какой уровень времени запроса будет приемлемым?   -  person elyase    schedule 26.09.2016


Ответы (3)


Эту проблему можно частично решить, объединив модель векторного пространства (которая является подобием tf-idf и косинусом) вместе с логической моделью. Это концепции теории информации, и они используются (и хорошо объясняются) в ElasticSearch - неплохая поисковая система.

Идея проста: вы храните свои документы в виде перевернутых индексов. Это можно сравнить со словами в конце книги, содержащими ссылку на страницы (документы), на которых они были упомянуты.

Вместо вычисления вектора tf-idf для всего документа он будет вычислять его только для документов, которые имеют хотя бы одно (или задают порог) общих слов. Это можно просто сделать, перебирая слова в запрашиваемом документе, находя документы, которые также имеют это слово, используя инвертированный индекс, и вычисляя сходство для них.

person DJanssens    schedule 26.09.2016

Вам следует взглянуть на gensim. Пример стартового кода выглядит так:

from gensim import corpora, models, similarities

dictionary = corpora.Dictionary(line.lower().split() for line in open('corpus.txt'))
corpus = [dictionary.doc2bow(line.lower().split()) for line in open('corpus.txt')]

tfidf = models.TfidfModel(corpus)
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=12)

Во время прогнозирования вы сначала получаете вектор для нового документа:

doc = "Human computer interaction"
vec_bow = dictionary.doc2bow(doc.lower().split())
vec_tfidf = tfidf[vec_bow]

Затем получите сходства (отсортированные по наиболее похожим):

sims = index[vec_tfidf] # perform a similarity query against the corpus
print(list(enumerate(sims))) # print (document_number, document_similarity) 2-tuples

Он выполняет линейное сканирование, как вы и хотели, но у них более оптимизированная реализация. Если скорости не хватает, то можно поискать примерное сходство (Annoy, Falconn, NMSLIB).

person elyase    schedule 26.09.2016
comment
Спасибо за ответ, я посмотрю и отправлю ответ - person Shlomi Schwartz; 26.09.2016
comment
Мой ноутбук разбился. Я не знаю причину - person Mehdi Golzadeh; 17.01.2020

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

На первом этапе вы группируете свои документы в несколько групп (например, 50 кластеров), затем у каждого кластера есть репрезентативный документ (который содержит некоторые слова, которые имеют некоторую полезную информацию о его кластере)
На втором этапе для вычисления косинусного сходства между новым документом и набором данных вы перебираете всех представителей (50 чисел) и находите наиболее близких представителей (например, 2 представителя)
На последнем шаге вы можете просмотреть все документы в выбранном представителе и найти ближайшее косинусное сходство

С помощью этой техники вы можете уменьшить количество циклов и улучшить производительность. Вы можете прочитать больше о технологиях в некоторых главах этой книги: http://nlp.stanford.edu/IR-book/html/htmledition/irbook.html

person Masoud    schedule 25.09.2016
comment
стоит отметить, что это просто эвристика, которая не гарантирует правильного результата (может произвольно отклоняться от результатов, полученных при истинном поиске по одному) - person lejlot; 25.09.2016