skrypt do przeszukania, porównania, podobieństw (ale nie 1:1)

0

mam taki dziwny problem, mianowicie potrzeba skrypt/kod, który przeszuka 1 linijki i porówna ze sobą. Ale żeby nie było tak prosto, to warunkiem jest, że muszą być rozbudowane funkcje tego przeszukania, np. "zgodność i podobieństwo w 70%".
podam przykłady:

pracujemy na plikach *.txt (zwykłe dane tekstowe), w każdym z tych plików jest 1 linijka = 1 wartość nazwa. Np:

czerwony kapturek idzie przez las
szklanka wody jest pusta
pada deszcz, grzmi burza
czarna komórka leży na stole
w lesie jest kapturek koloru czerwonego
kapturkowi czerwonemu dobrze jest w lesie 

i teraz tak
-1 linijka = 1 wartość do przeszukania

  • linijek w pliku może być nawet 15 000
  • każda linijka ma od 1 znaku do 50, włącznie ze spacjami i przecinkami (znaki używane przez ludzi gdy pisza teksty, czyli w sumie utf-8).

Zależy mi, żeby skrypt wyłapał, że linijka 1 i dwie ostatnie są do siebie podobne, ale nie identyczne. Zauważmy, że linijki różnią się np. gramatyką, ale w sumie ich treść może być zbliżona.
i teraz fajnie byłoby, żeby np. w skrypcie dało się ustawiać jakieś bardziej zaawansowane paramety dotyczące analizy składni, w sensie, żeby te podobieństwa wyłapał nawet na poziomie 30%.

reasumując: wyłapanie wszystkiego (linijek w *.txt) co jest w jakimś stopniu podobne, ale nie identyczne (NIE: 1 do 1). No i określamy stopień podobieństwa (np. na podstawie pojedynczych słów, cząstek słów w całej linijce) - np. 50%.

jak się za to zabrać, jakiej biblioteki python/php użyć, jakiego softu? (tylko rzeczy konsolowe)

0

Musisz przeprowadzić analizę leksykalną a następnie stemmerem doprowadzić do formy podstawowej. Potem musisz opracować jakąś metodę porównywania powstałych drzew w celu znalezienia podobieństw.

Przykładowo dla obu podanych zdań

  1. sentence.dot.png
  2. sentence.dot.2.png

Tutaj widzimy, że mamy to samo drzewo dla podmiotu, ale różne dla orzeczenia.

0

hmm, czyli wygląda to na bardziej skomplikowanie niż myślałem.

a np. coś takiego:
czerwony a czerwonemu - tak naprawdę mamy człony podobne, te słowa są identyczne w powiedzmy 70-80%
jest w lesie a w lesie jest - odwrócona kolejność, ale to też podobne jest

chodzi, żeby tego typu rzeczy wyłapywać. Oczywiście też porównanie słow jeden do jeden (kapturek tutaj i tutaj).

jeszcze jest taka kwestia, że wyrażenia 1 oraz dwa ostanie mają podobną ilość znaków - od 35 do 45. Też to jest jeden z czynników.

natomiast analiza składniowa pokazana u góry byłaby przydatna, ale niestety nie mam czasu/energii żeby to zaimplementować.
W ogóle to zahacza trochę o język naturalny i sztuczną inteligencję.

EDIT:
coś takiego znalazłem, będę jutro testował :
https://secure.php.net/manual/en/function.similar-text.php
ale już w komentarzach piszą, że daje różne wyniki ;) zobaczy się
tutaj rozkminy na SO:
https://stackoverflow.com/questions/16520646/how-to-check-a-partial-similarity-of-two-strings-in-php
https://stackoverflow.com/questions/14136349/how-does-similar-text-work?noredirect=1&lq=1

3
  1. Stemmer / lematyzacja będzie tutaj dość przydatna. Jak chcesz iść na łatwizne to tutaj: http://galaxy.uci.agh.edu.pl/~korzycki/osi/odm.txt.gz masz uproszczony słownik odmian dla języka polskiego, załaduj sobie do mapy i możesz za jego pomocą lematyzować.
  2. Najprościej porównywać to za pomocą cosine similarity, jeśli zakładamy że "słownik" jest ten sam.
    Sama miara consinusowa jest dość trywialna:
  • Mamy przestrzeń wektorową nad wszystkimi słowami w formach podstawowych, tzn każde słowo określa nam dodatkowy "wymiar"
  • Każde zdanie jest wektorem w tej przestrzeni gdzie współrzędne określają które słowo i ile razy występuje w zdaniu
  • Podobieństwo dwóch zdań to cosinus kąta między dwoma wektorami, liczony z iloczynu skalarnego

Więc jeśli masz np. słownik ala, ma, kota, sierotka, rysia mamy przestrzeń 5-wymiarową i zdanie ala ma kota jest w tej przestrzeni wektorem [1,1,1,0,0] a zdanie sierotka ma rysia jest [0,1,0,1,1] i teraz podobieństwo tych dwóch zdań to:
[1,1,1,0,0]*[0,1,0,1,1] = |[1,1,1,0,0]|*|[0,1,0,1,1]|*cos(alfa)
co daje nam
cos(alfa) = (0+1+0+0+0)/sqrt(3)*sqrt(3) = 1/3
Podczas gdy np. podobieństwo zdania ala ma rysia (wektor [1,1,0,0,1]) będzie
cos(alfa) = (1+1+0+0+0)/3 = 2/3

Jak widać ala ma kota jest wyraźnie bardziej podobne do ala ma rysia niż to sierotka ma rysia.

  1. Gdybyś chciał robić porównanie "semantyczne", tzn stwierdzić że zdania ala ma kota oraz dziewczyka posiada kotowatego ssaka są zbliżone do siebie to wymagałoby to trochę bardziej skomplikowanego podejścia -> tzw topic modelingu albo latent semantic analysis a do tego trzeba już mieć na przykład kilka GB tekstu w danym języku :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1