Как вычислить подобие косинуса с учетом 2 строк предложения? – Python

Из Python: tf-idf-cosine: чтобы найти сходство документа , можно вычислить сходство документа с помощью tf-idf cosine. Без импорта внешних библиотек, есть ли какие-либо способы вычисления косинусного сходства между двумя строками?

s1 = "This is a foo bar sentence ." s2 = "This sentence is similar to a foo bar sentence ." s3 = "What is this string ? Totally not related to the other two lines ." cosine_sim(s1, s2) # Should give high cosine similarity cosine_sim(s1, s3) # Shouldn't give high cosine similarity value cosine_sim(s2, s3) # Shouldn't give high cosine similarity value 

3 Solutions collect form web for “Как вычислить подобие косинуса с учетом 2 строк предложения? – Python”

Простая реализация pure-Python будет:

 import re, math from collections import Counter WORD = re.compile(r'\w+') def get_cosine(vec1, vec2): intersection = set(vec1.keys()) & set(vec2.keys()) numerator = sum([vec1[x] * vec2[x] for x in intersection]) sum1 = sum([vec1[x]**2 for x in vec1.keys()]) sum2 = sum([vec2[x]**2 for x in vec2.keys()]) denominator = math.sqrt(sum1) * math.sqrt(sum2) if not denominator: return 0.0 else: return float(numerator) / denominator def text_to_vector(text): words = WORD.findall(text) return Counter(words) text1 = 'This is a foo bar sentence .' text2 = 'This sentence is similar to a foo bar sentence .' vector1 = text_to_vector(text1) vector2 = text_to_vector(text2) cosine = get_cosine(vector1, vector2) print 'Cosine:', cosine 

Печать:

 Cosine: 0.861640436855 

Здесь описывается формула косинуса, используемая здесь .

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

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

Короткий ответ «нет, это невозможно сделать принципиально, что работает даже отдаленно». Это нерешенная проблема в исследованиях обработки естественного языка, а также, оказывается, является предметом моей докторской работы. Я очень кратко обобщу, где мы находимся, и укажем вам на несколько публикаций:

Значение слов

Важнейшим предположением здесь является то, что можно получить вектор, который представляет каждое слово в предложении в вопросе. Этот вектор обычно выбирается для захвата контекстов, в которые может появиться слово. Например, если мы рассматриваем только три контекста «есть», «красный» и «пушистый», слово «кошка» может быть представлено как [98, 1 , 87], потому что если бы вы читали очень длинный фрагмент текста (несколько миллиардов слов нередко по сегодняшнему стандарту), слово «кошка» появлялось бы очень часто в контексте «пушистых» и «съедающих», , но не так часто в контексте «красного». Точно так же «собака» может быть представлена ​​как [87,2,34], а «зонтик» может быть [1,13,0]. Представляя эти векторы как точки в трехмерном пространстве, «кошка» явно ближе к «собаке», чем к «зонтику», поэтому «кошка» также означает нечто более похожее на «собаку», чем на «зонтик».

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

 theory -> analysis, concept, approach, idea, method voice -> vocal, tone, sound, melody, singing james -> william, john, thomas, robert, george, charles 

Эти списки похожих слов были получены полностью без вмешательства человека – вы кормите текст и возвращаетесь через несколько часов.

Проблема с фразами

Вы можете спросить, почему мы не делаем то же самое для более длинных фраз, таких как «лисицы-лисицы любят фрукты». Это потому, что у нас недостаточно текста. Для того чтобы мы могли достоверно установить, что X похож на, нам нужно увидеть много примеров использования X в контексте. Когда X – это одно слово, например «голос», это не слишком сложно. Однако по мере того, как X становится длиннее, шансы найти естественные вхождения X экспоненциально медленнее. Для сравнения, Google имеет около 1B страниц, содержащих слово «лиса», а не одну страницу, содержащую «лисицы-лисицы», несмотря на то, что это совершенно правильное английское предложение, и все мы понимаем, что это значит.

Состав

Чтобы решить проблему разреженности данных, мы хотим выполнить композицию, т. Е. Взять векторы для слов, которые легко получить из реального текста, и объединить их таким образом, чтобы фиксировать их смысл. Плохая новость заключается в том, что до сих пор никто не смог сделать это хорошо.

Самый простой и очевидный способ – добавить или размножить отдельные векторы слов вместе. Это приводит к нежелательному побочному эффекту, что «кошки преследуют собак» и «собачьи кошки-кошки» означают то же самое для вашей системы. Кроме того, если вы умножаетесь, вы должны быть осторожны, или все предложения будут представлены в [0,0,0, …, 0], что победит точку.

дальнейшее чтение

Я не буду обсуждать более сложные методы композиции, которые были предложены до сих пор. Я предлагаю вам ознакомиться с «векторными космическими моделями слова« смысл слова »и фразой« обзор » Катрин Эрк. Это очень хороший обзор высокого уровня, чтобы вы начали. К сожалению, он не является бесплатным на веб-сайте издателя, отправьте его автору напрямую, чтобы получить копию. В этой статье вы найдете ссылки на многие более конкретные методы. Более понятными являются Митчел и Лапата (2008), Барони и Зампарелли (2010) .


Редактировать после комментария @vpekar: нижняя строка этого ответа заключается в том, чтобы подчеркнуть тот факт, что, хотя наивные методы существуют (например, сложение, умножение, поверхностное сходство и т. Д.), Они в корне ошибочны и в целом не следует ожидать большой производительности от их.

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

cos (q, d) = sim (q, d) = (q · d) / (| q || d |) = (sum (qi, di) / (sqrt (sum (qi2))) * (sqrt ( sum (vi2))) где i = 1 – v)

  • qi – вес tf-idf термина i в запросе.
  • di – tf-idf
  • вес термина i в документе. | Д | и | d | – длины q и d.
  • Это сходство косинусов q и d. , , , , , или, что то же самое, косинус угла между q и d.

Пожалуйста, не стесняйтесь просматривать мой код здесь . Но сначала вам нужно будет скачать пакет anaconda. Он автоматически установит вам путь python в Windows. Добавьте этот интерпретатор python в Eclipse.

Interesting Posts

Сортируйте массив numpy другим массивом вдоль определенной оси, используя меньше памяти

Чистый способ получить почти-LIFO поведение от многопроцессорности. Queue? (или даже просто * не * рядом с FIFO)

управление элементами пользовательского интерфейса в wxPython с использованием потоков

Проверьте, есть ли что-то «ожидание» возвращаемого значения функции

группировка радиокнопки в PyQt

Запустить Python из Powershell

RSA шифрует / расшифровывает между C и python

сравнить объект с пустым кортежем с оператором 'is' в Python 2.x

Как построить горизонтальную диаграмму в Bokeh (Python)

Создание документа SVG / XML без пространства имен ns0 с использованием Python ElementTree

Как хешировать большой объект (набор данных) в Python?

Левые собственные векторы, не дающие правильной (марковской) стационарной вероятности в scipy

Не работаю для меня

Python идентифицирует файл с наибольшим числом как часть имени файла

Удаление всех нечисловых символов из строки в Python

Python - лучший язык программирования в мире.