2009-11-11 11 views
5

Chciałbym znaleźć dobry sposób na znalezienie niektórych (pozwól, by były dwa) zdania w jakimś tekście. Co będzie lepsze - użyj regexp lub split-method? Twoje pomysły?znajdź kilka zdań

wnioskowane przez Jeremy Stein - istnieje kilka przykładów

Przykłady:

Wejście:

Pierwszą rzeczą do zrobienia jest stworzenie modelu komentarz. Stworzymy to w normalny sposób, ale z jedną niewielką różnicą. Gdybyśmy tylko tworzyli komentarze do artykułu, mielibyśmy pole liczbowe o nazwie article_id w modelu do przechowywania klucza obcego, ale w tym przypadku potrzebujemy czegoś bardziej abstrakcyjnego.

Pierwsze dwa zdania:

Pierwszą rzeczą do zrobienia jest stworzenie modelu komentarz. Stworzymy to w normalny sposób, ale z jedną niewielką różnicą.

Wejście:

Mr. T jest jednym oznaczać koleś. Nie chciałbym z nim walczyć.

Pierwsze dwa zdania:

Mr. T jest jednym oznaczać koleś. Nie chciałbym z nim walczyć.

Wejście:

D.C. snajper został stracony został stracony przez śmiertelny zastrzyk w więzieniu Virginia. Śmierć ogłoszono o 9:11 po południu. ET.

Pierwsze dwa zdania:

D.C. snajper został stracony został stracony przez śmiertelny zastrzyk w więzieniu Virginia. Śmierć ogłoszono o 9:11 po południu. ET.

Wejście:

W swoich uwagach końcowych, przeciwna adwokat powiedział, że „... w tym i wielu innych przypadkach, dwie krzywdy nie zrobić prawo.” Wydaje się, że jury zgodziło się.

Pierwsze dwa zdania:

W swoich uwagach końcowych, przeciwna adwokat powiedział, że „... w tym i wielu innych przypadkach, dwie krzywdy nie zrobić prawo.” Wydaje się, że jury zgodziło się.

Faceci, jak widać - nie jest tak łatwo określić dwa zdania z tekstu. :(

+0

Jaki jest twój wkład? Jak chcesz wyglądać Twoje wydruki? –

+0

dowolny tekst. Potrzebuję pierwszych 2 (lub nawet więcej) zdań tego tekstu. –

Odpowiedz

0

Jeśli wiesz, czego szukać zdania, Regex powinien robić dobrze szukając

((YOUR SENTENCE HERE)|(YOUR OTHER SENTENCE)){1} 

Podział prawdopodobnie zużyć sporo pamięci, jak również oszczędza rzeczy nie trzeba (cały tekst, który nie jest twoje zdanie) jak tylko Regex zapisuje zdanie jesteś poszukiwany (jeśli go znajdzie, oczywiście)

+0

Po prostu potrzebuję znaleźć 2 różne frazy w zaznaczonym tekście. Na przykład "Pierwszą rzeczą do zrobienia jest stworzenie modelu komentarza, który utworzymy w normalny sposób, ale z jedną niewielką różnicą. Gdybyśmy tylko tworzyli komentarze do artykułu, mielibyśmy pole liczby całkowitej o nazwie article_id in model do przechowywania klucza obcego, ale w tym przypadku będziemy potrzebować czegoś bardziej abstrakcyjnego. "- potrzebuję tylko 2 zdania -" Pierwsza rzecz ... "i" Stworzymy to ... " –

+0

Wszystkie zdania podzielone przez "." (Kropka i spacja). Potrzebuję tylko dwóch pierwszych. –

+0

Więc nie wiesz, jakie zdania, ale wiesz, że są dwa? Brzmiało to tak, jakbyś szukał dwóch konkretnych zdań. – Kobi

3
your_string = "First sentence. Second sentence. Third sentence" 
sentences = your_string.split(".") 
=> ["First sentence", " Second sentence", " Third sentence"] 

nie ma potrzeby, aby prosty kod skomplikowane.

Edytuj: Teraz, gdy wyjaśniłeś, że rzeczywiste dane wejściowe są bardziej złożone niż w pierwszym przykładzie, powinieneś zignorować tę odpowiedź, ponieważ nie uwzględnia ona przypadków skrajnych. Pierwsze spojrzenie na NLP powinno pokazać ci, do czego zmierzasz.

Niektóre z przypadków brzegowych, które widziałem w przeszłości, aby być nieco skomplikowane są:

  • Termin: Niektóre regiony używać dd.mm.rrrr
  • notowania: Choć był wzdychając — "Cokolwiek, zrób to teraz ... A tak przy okazji ...". To wystarczyło.
  • Jednostki: jechał na 138 km. podczas jazdy na autostradzie.

Jeśli zamierzasz analizować te teksty, powinieneś trzymać się z daleka od podziałów lub wyrażeń regularnych.

+0

ok, ale co z twoją_ciągarką = "Pierwsze zdanie ...... Drugie zdanie ... Trzecie zdanie" ??? może będzie lepiej zdań = your_string.split (".") ??? –

+0

mam na myśli z dodatkową przestrzenią –

+0

Musisz także martwić się o elipsy. – Garrett

1
irb(main):005:0> a = "The first sentence. The second sentence. And the third" 
irb(main):006:0> a.split(".")[0...2] 
=> ["The first sentence", " The second sentence"] 
irb(main):007:0> 

EDIT: oto w jaki sposób poradzić sobie z „To jest zdanie ...... i drugiego i kolejny ....” Przypadek:

irb(main):001:0> a = "This is the first sentence ....... And the second. Let's not forget the third" 
=> "This is the first sentence ....... And the second. Let's not forget the thir 
d" 
irb(main):002:0> a.split(/\.+/) 
=> ["This is the first sentence ", " And the second", " Let's not forget the thi rd"] 

I można stosować takie same operator zakresu: ..., aby wyodrębnić pierwsze 2.

+0

Wpadłeś w problem z "Panem Smithem pomógł pani Smith powiedzieć do dr Frankensteina o zwycięstwie H.M.S." – ealdent

+0

Być może najpierw potrzebna byłaby tokenizacja słowa. – Geo

0

Jeśli dzielisz fragment tekstu na zdania, to zaczyna się od określenia, które znaki mogą oddzielić zdania. Ogólnie rzecz biorąc, jest to !, ? i . (ale jeśli wszystko, co Cię interesuje, to . dla tekstów przetwarzanych przez ciebie, to po prostu idź z tym).

Teraz, ponieważ mogą one pojawiać się w cudzysłowie lub jako fragmenty skrótów, należy znaleźć każde wystąpienie tych znaków interpunkcyjnych i uruchomić jakiś rodzaj klasyfikatora uczenia maszynowego, aby określić, czy to wystąpienie rozpoczyna nowe zdanie, lub czy robi coś innego. Obejmuje to dane treningowe i odpowiednio skonstruowany klasyfikator. I nie będzie to w 100% dokładne, ponieważ prawdopodobnie nie ma sposobu, aby być w 100% dokładne.

Proponuję poszukać w literaturze technik segmentacji zdań i przyjrzeć się różnym zestawom narzędzi do przetwarzania języka naturalnego, które są tam dostępne. Tak naprawdę nie znalazłem jeszcze jednego dla Ruby, ale tak się składa, że ​​lubię OpenNLP (który jest w Javie).

1

Zazwyczaj będzie to pasowało do zdań.

/\S(?:(?![.?!]+\s).)*[.?!]+(?=\s|$)/m 

Dla przykładu dwóch zdań, weź pierwsze dwa mecze.

4

Jak już zauważyłeś, tokenizacja zdań jest nieco bardziej skomplikowana, niż mogłoby się wydawać. Więc równie dobrze możesz skorzystać z istniejących rozwiązań. Algorytm tonizacji zdania Punkt jest popularny w NLP, a w Pythonie Natural Language Toolkit jest dobra implementacja, którą opisują użycie here. Opisują również inne podejście here.

Prawdopodobnie istnieją inne implementacje lub można również przeczytać oryginalny paper opisujący algorytm Punkt: Kiss, Tibor i Strunk, Jan (2006): Wyjątkowe wykrywanie granic bez wyrażeń z wielojęzycznym zdaniami. Computational Linguistics 32: 485-525.

Możesz także przeczytać inne pytanie o przepełnienie stosu dotyczące tokenizacji zdań: here.

+0

Doskonała odpowiedź. –