Сходство между двумя текстовыми документами
Я смотрю на работу над проектом NLP, на любом языке (хотя Python будет моим предпочтением).
Я хочу написать программу, которая будет принимать два документа и определить, насколько они похожи.
Как я довольно новичок в этом и быстрый поиск google не указывает мне слишком много. Знаете ли вы какие-либо ссылки (веб-сайты, учебники, журнальные статьи), которые охватывают эту тему и могли бы мне помочь?
спасибо
7 ответов:
общий способ сделать это-преобразовать документы в векторы tf-idf, а затем вычислить косинусное сходство между ними. Любой учебник по информационному поиску (ИК) охватывает это. Увидеть ЭСП. введение в информационный поиск, который является бесплатным и доступен онлайн.
Tf-idf (и аналогичные преобразования текста) реализованы в пакетах Python Gensim и scikit-learn. В последнем пакете, вычисление косинусных сходств так же просто, как
from sklearn.feature_extraction.text import TfidfVectorizer documents = [open(f) for f in text_files] tfidf = TfidfVectorizer().fit_transform(documents) # no need to normalize, since Vectorizer will return normalized tf-idf pairwise_similarity = tfidf * tfidf.Tили, если документы являются простыми строками,
>>> vect = TfidfVectorizer(min_df=1) >>> tfidf = vect.fit_transform(["I'd like an apple", ... "An apple a day keeps the doctor away", ... "Never compare an apple to an orange", ... "I prefer scikit-learn to Orange"]) >>> (tfidf * tfidf.T).A array([[ 1. , 0.25082859, 0.39482963, 0. ], [ 0.25082859, 1. , 0.22057609, 0. ], [ 0.39482963, 0.22057609, 1. , 0.26264139], [ 0. , 0. , 0.26264139, 1. ]])хотя Gensim может иметь больше вариантов для такого рода задач.
см. также этот вопрос.
[отказ от ответственности: я участвовал в реализации scikit-learn tf-idf.]
идентично @larsman, но с некоторой предварительной обработкой
import nltk, string from sklearn.feature_extraction.text import TfidfVectorizer nltk.download('punkt') # if necessary... stemmer = nltk.stem.porter.PorterStemmer() remove_punctuation_map = dict((ord(char), None) for char in string.punctuation) def stem_tokens(tokens): return [stemmer.stem(item) for item in tokens] '''remove punctuation, lowercase, stem''' def normalize(text): return stem_tokens(nltk.word_tokenize(text.lower().translate(remove_punctuation_map))) vectorizer = TfidfVectorizer(tokenizer=normalize, stop_words='english') def cosine_sim(text1, text2): tfidf = vectorizer.fit_transform([text1, text2]) return ((tfidf * tfidf.T).A)[0,1] print cosine_sim('a little bird', 'a little bird') print cosine_sim('a little bird', 'a little bird chirps') print cosine_sim('a little bird', 'a big dog barks')
Это старый вопрос, но я обнаружил, что это можно легко сделать с Spacy. После того, как документ прочитан, простой api
similarityможно использовать для поиска косинусного сходства между векторами документа.import spacy nlp = spacy.load('en') doc1 = nlp(u'Hello hi there!') doc2 = nlp(u'Hello hi there!') doc3 = nlp(u'Hey whatsup?') print doc1.similarity(doc2) # 0.999999954642 print doc2.similarity(doc3) # 0.699032527716 print doc1.similarity(doc3) # 0.699032527716
вообще Косинус сходство между двумя документами используется в качестве меры сходства документов. В Java, вы можете использовать Lucene (Если ваша коллекция довольно большая) или LingPipe для этого. Основная концепция будет заключаться в подсчете терминов в каждом документе и вычислении точечного произведения векторов терминов. Библиотеки обеспечивают несколько улучшений по сравнению с этим общим подходом, например, используя обратные частоты документов и вычисляя векторы tf-idf. Если вы хотите сделать что-то copmlex, LingPipe также предоставляет методы для расчета сходства LSA между документами, что дает лучшие результаты, чем косинусное сходство. Для Python, вы можете использовать NLTK.
вот небольшое приложение, чтобы вы начали...
import difflib as dl a = file('file').read() b = file('file1').read() sim = dl.get_close_matches s = 0 wa = a.split() wb = b.split() for i in wa: if sim(i, wb): s += 1 n = float(s) / float(len(wa)) print '%d%% similarity' % int(n * 100)
вы можете попробовать эту онлайн-службу для сходства косинусного документа http://www.scurtu.it/documentSimilarity.html
import urllib,urllib2 import json API_URL="http://www.scurtu.it/apis/documentSimilarity" inputDict={} inputDict['doc1']='Document with some text' inputDict['doc2']='Other document with some text' params = urllib.urlencode(inputDict) f = urllib2.urlopen(API_URL, params) response= f.read() responseObject=json.loads(response) print responseObject
Если вы больше заинтересованы в измерении семантического сходства двух частей текста, я предлагаю взглянуть на этот проект gitlab. Вы можете запустить его в качестве сервера, есть также встроенные модели, которые вы можете легко использовать для измерения сходства двух фрагментов текста; хотя это, в основном, подготовленными для измерения сходства двух предложений, вы все еще можете использовать его в вашем случае.Это написано в Java, но вы можете запустить его в качестве RESTful-сервис.
другой вариант и есть Сходство DKPro которая представляет собой библиотеку с различным алгоритмом для измерения сходства текстов. Однако он также написан на java.
Comments