Пример нахождения косинусного расстония между текстами в sklearn

Косинусное расстояние — это распространенная метрика поиска схожих объектов, часто в разряженном пространстве. Поэтому косинусное расстоние часто применяют для сравнения текстов. Ниже приведу код для поиска наиболее похожего текста с помощью встроенных функций sklearn.
Пусть у нас есть большое количество текстов, предобработаем тексты с помощью tf-idf, после этого возьмем новый текст и найдем 3 самых похожих.

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import linear_kernel

# зададим массив текстов
some_texts = [
   'текст номер один',
   'текст следующий под номером два',
   'третий набор слов',
   'что-то ещё для полноценного дата-сета',
   'пример текстового документа',
]
df = pd.DataFrame({'texts': some_texts})

# А к данному тексту будем искать наиболее похожий из заданного выше набора
find_nearest_to = "текст номер три"

# формирование весов tf-idf
tfidf = TfidfVectorizer()
mx_tf = tfidf.fit_transform(some_texts)
new_entry = tfidf.transform([find_nearest_to])

# расчет косинусного расстояния
cosine_similarities = linear_kernel(new_entry, mx_tf).flatten()

# запишем все попарные результаты сравнений
df['cos_similarities'] = cosine_similarities
# и отсортируем по убыванию (т.к. cos(0)=1)
df = df.sort_values(by=['cos_similarities'], ascending=[0])

# Выведем 3 самых близких результата
for index, row in df[0:3].iterrows():
    print(row['texts'], row['cos_similarities'])
# output:
# текст номер один 0.7891589913464455
# текст следующий под номером два 0.23490553492076713
# третий набор слов 0.0

Заметим, что в данном примере мы не использовали cosine_similarity, а почему-то взяли linear_kernel. Дело в том, что когда вектора нормализованы (а они нормализованы после TfidfVectorizer) результат будет одинаковый, однако linear_kernel требует меньше вычислительной мощности и вычислится быстрее. Особенно это будет хорошо заметно на больших данных. Если же вектора не нормализованы, то правильно использовать sklearn.metrics.pairwise.cosine_similarity .

Пример также можно рассматривать как рекомендательную систему на большом корпусе каких-то объектов, работает быстро и хорошо подходит для бейзлайна. В случае с объектами не текстовыми, рекомендуется также попробовать использовать CountVectorizer, вместо TfidfVectorizer.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>