Используя sklearn, как рассчитать косинусное сходство tf-idf между документами и запросом? - PullRequest
6 голосов
/ 14 апреля 2019

Моя цель - ввести 3 запроса и выяснить, какой запрос больше всего похож на набор из 5 документов.

До сих пор я вычислил tf-idf документов, выполнив следующие действия:

from sklearn.feature_extraction.text import TfidfVectorizer

def get_term_frequency_inverse_data_frequency(documents):
    allDocs = []
    for document in documents:
        allDocs.append(nlp.clean_tf_idf_text(document))
    vectorizer = TfidfVectorizer()
    matrix = vectorizer.fit_transform(allDocs)
    return matrix

def get_tf_idf_query_similarity(documents, query):
    tfidf = get_term_frequency_inverse_data_frequency(documents)

Проблема, с которой я столкнулся сейчас, заключается в том, что у меня есть tf-idf документов, какие операции я выполняю над запросом, чтобы найти косинусное сходство с документами?

Ответы [ 4 ]

3 голосов
/ 15 апреля 2019

Вот мое предложение:

  • Нам не нужно подгонять модель дважды.мы могли бы повторно использовать тот же векторизатор
  • функция очистки текста может быть подключена к TfidfVectorizer напрямую с использованием атрибута preprocessing.
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

vectorizer = TfidfVectorizer(preprocessor=nlp.clean_tf_idf_text)
docs_tfidf = vectorizer.fit_transform(allDocs)

def get_tf_idf_query_similarity(vectorizer, docs_tfidf, query):
    """
    vectorizer: TfIdfVectorizer model
    docs_tfidf: tfidf vectors for all docs
    query: query doc

    return: cosine similarity between query and all docs
    """
    query_tfidf = vectorizer.transform([query])
    cosineSimilarities = cosine_similarity(query_tfidf, docs_tfidf).flatten()
    return cosineSimilarities
1 голос
/ 14 апреля 2019

Вы можете сделать, как написал Нихал в своем ответе, или использовать алгоритм ближайших соседей из sklearn.Вы должны выбрать правильную метрику (косинус)

from sklearn.neighbors import NearestNeighbors
neigh = NearestNeighbors(n_neighbors=5, metric='cosine')
1 голос
/ 14 апреля 2019

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

Чтобы преобразовать запрос, я сначала подгонял егок матрице документа:

queryTFIDF = TfidfVectorizer().fit(allDocs)

Затем я преобразую его в форму матрицы:

queryTFIDF = queryTFIDF.transform([query])

И затем просто вычисляю косинусное сходство между всеми документами и моим запросом, используя sklearn.metrics.pairwise.cosine_simility function

cosineSimilarities = cosine_similarity(queryTFIDF, docTFIDF).flatten()

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

Полный код выглядит примерно так:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

def get_tf_idf_query_similarity(documents, query):
    allDocs = []
    for document in documents:
        allDocs.append(nlp.clean_tf_idf_text(document))
    docTFIDF = TfidfVectorizer().fit_transform(allDocs)
    queryTFIDF = TfidfVectorizer().fit(allDocs)
    queryTFIDF = queryTFIDF.transform([query])

    cosineSimilarities = cosine_similarity(queryTFIDF, docTFIDF).flatten()
    return cosineSimilarities
1 голос
/ 14 апреля 2019

Косинусное сходство - это косинус угла между векторами, которые представляют документы.

K(X, Y) = <X, Y> / (||X||*||Y||)

Ваша матрица tf-idf будет разреженной матрицей с размерами = нет.документов * нет.отдельных слов.

Для печати всей матрицы вы можете использовать todense()

print(tfidf.todense())

Каждая строка представляет векторное представление, соответствующее одному документу.Аналогично, каждый столбец соответствует количеству уникальных слов в корпусе tf-idf.

Между вектором и любым другим вектором парное сходство может быть вычислено из вашей матрицы tf-idf как:

from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(reference_vector, tfidf_matrix) 

Выходными данными будет массив длины = нет.документов, указывающих оценку сходства между вашим вектором ссылки и вектором, соответствующим каждому документу.Конечно, сходство между исходным вектором и самим собой будет равно 1. В целом это будет значение от 0 до 1.

Чтобы найти сходство между первым и вторым документами,

print(cosine_similarity(tfidf_matrix[0], tfidf_matrix[1]))

array([[0.36651513]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...