Comparação Difusa De Texto

o que eu estou me esforçando para completar é um programa que lê em um arquivo e vai comparar cada frase de acordo com a frase original. A frase que é uma correspondência perfeita com o original receberá uma pontuação de 1 e uma frase que é o oposto total receberá um 0. Todas as outras frases difusas receberão uma nota entre 1 e 0.

não sei qual a operação a usar para me permitir completar isto no Python 3.

incluí o texto da amostra em que o texto 1 é o original e as outras cadeias anteriores são as comparações.

Texto: Amostra

Texto 1: era uma noite escura e tempestuosa. Estava sozinho sentado numa cadeira vermelha. Eu não estava completamente sozinho como eu tinha três gatos.

Texto 20: foi uma noite turva e tempestuosa. Estava sozinha sentada numa cadeira vermelha. Eu não estava completamente sozinho como eu tinha três felinos // Should score high point but not 1

Texto 21: foi uma noite obscura e tempestuosa. Eu estava tudo sozinho sentado numa catedral carmesim. Eu não estava completamente sozinho como eu tinha três felinos // Should score lower than text 20

Texto 22: Eu estava sozinho sentado numa catedral carmesim. Eu não estava completamente sozinho como eu tinha três felinos. Foi uma noite obscura e tempestuosa. // Should score lower than text 21 but NOT 0

Texto 24: era uma noite escura e tempestuosa. Não estava sozinho. Não estava sentado numa cadeira vermelha. Eu tinha três gatos. / Devia marcar um 0!

Author: San Jacinto, 2012-04-30

4 answers

Há um pacote chamado fuzzywuzzy. Instalar através do pip:
pip install fuzzywuzzy

Utilização simples:

>>> from fuzzywuzzy import fuzz
>>> fuzz.ratio("this is a test", "this is a test!")
    96

O pacote foi construído em cima de difflib. Porque não usar isso? Além de ser um pouco mais simples, ele tem uma série de diferentes métodos de correspondência (como insensibilidade de ordem token, correspondência parcial de strings) que o tornam mais poderoso na prática. As funções process.extract são especialmente úteis: encontrar as melhores cadeias e rácios de correspondência a partir de um conjunto. Dos seus readme:

Razão Parcial

>>> fuzz.partial_ratio("this is a test", "this is a test!")
    100

Token Sort Ratio

>>> fuzz.ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    90
>>> fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    100

Token Set Ratio

>>> fuzz.token_sort_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear")
    84
>>> fuzz.token_set_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear")
    100

Processo

>>> choices = ["Atlanta Falcons", "New York Jets", "New York Giants", "Dallas Cowboys"]
>>> process.extract("new york jets", choices, limit=2)
    [('New York Jets', 100), ('New York Giants', 78)]
>>> process.extractOne("cowboys", choices)
    ("Dallas Cowboys", 90)
 83
Author: congusbongus, 2015-02-12 01:29:16

Existe um módulo na biblioteca-padrão (chamado difflib) isso pode comparar strings e retornar uma pontuação com base em sua similaridade. O SequenceMatcher as aulas devem fazer o que querem.

Editar: pequeno exemplo da linha de comandos de python:

>>> from difflib import SequenceMatcher as SM
>>> s1 = ' It was a dark and stormy night. I was all alone sitting on a red chair. I was not completely alone as I had three cats.'
>>> s2 = ' It was a murky and stormy night. I was all alone sitting on a crimson chair. I was not completely alone as I had three felines.'
>>> SM(None, s1, s2).ratio()
0.9112903225806451

HTH!

 74
Author: mac, 2012-04-30 12:13:28

fuzzyset é muito mais rápido do que fuzzywuzzy (difflib) tanto para indexar como para procurar.

from fuzzyset import FuzzySet
corpus = """It was a murky and stormy night. I was all alone sitting on a crimson chair. I was not completely alone as I had three felines
    It was a murky and tempestuous night. I was all alone sitting on a crimson cathedra. I was not completely alone as I had three felines
    I was all alone sitting on a crimson cathedra. I was not completely alone as I had three felines. It was a murky and tempestuous night.
    It was a dark and stormy night. I was not alone. I was not sitting on a red chair. I had three cats."""
corpus = [line.lstrip() for line in corpus.split("\n")]
fs = FuzzySet(corpus)
query = "It was a dark and stormy night. I was all alone sitting on a red chair. I was not completely alone as I had three cats."
fs.get(query)
# [(0.873015873015873, 'It was a murky and stormy night. I was all alone sitting on a crimson chair. I was not completely alone as I had three felines')]

Atenção: tenha cuidado para não misturar unicode e bytes no seu fuziset.

 11
Author: hobs, 2017-03-25 23:25:20

A tarefa chama-seIdentificação da paráfrase que é uma área activa de investigação no processamento da Linguagem Natural. Liguei vários artigos de última geração, muitos dos quais podem encontrar código de código aberto no GitHub.

Note que toda a pergunta respondida assume que há alguma similaridade de cadeia/superfície entre as duas sentenças enquanto na realidade duas sentenças com pouca similaridade de cadeia podem ser semanticamente semelhantes.

Se estás interessado nisso ... tipo de semelhança pode usar Skip-Thoughts. Instale o software de acordo com as guias do GitHub e vá para a secção de detecção de paráfrase em readme:
import skipthoughts
model = skipthoughts.load_model()
vectors = skipthoughts.encode(model, X_sentences)

Isto converte as suas frases (X_sentences) em vetores. Mais tarde você pode encontrar a semelhança de dois vetores por:

similarity = 1 - scipy.spatial.distance.cosine(vectors[0], vectors[1])

Onde estamos assumindo vetor [0] e Vetor1 são o vector correspondente a X_sentences[ 0], X_sentences1 que querias encontrar os resultados deles.

Existem outros modelos para converter uma sentença para um vetor que você pode encontrar aqui .

Uma vez convertidas as tuas frases em vectores, a semelhança é apenas uma questão de encontrar a semelhança Cosina entre esses Vectores.
 1
Author: Ash, 2016-11-23 02:40:05