2010-02-24 22 views
25

Załóżmy, że mamy plik tekstowy z zawartością: „Je suis un homme beau ...”Jak sprawdzić, w jakim języku jest napisany zwykły tekst?

nawzajem: „Jestem dzielnym człowiekiem”

trzeci z tekstem w języku niemieckim: "Guten morgen. Wie geht's?"

Jak napisać funkcję, która by nam powiedziała: z takim prawdopodobieństwem tekst w pierwszym pliku jest w języku angielskim, w drugim mamy francuski itp?

Linki do książek/gotowe rozwiązania są mile widziane. Piszę w Javie, ale w razie potrzeby mogę nauczyć się Pythona.

Moje komentarze

  1. Jest jeden mały komentarz trzeba dodać. Tekst może zawierać wyrażenia w różnych językach, jako część całości lub w wyniku pomyłki. W klasycznej literaturze mamy wiele przykładów, ponieważ członkowie arystokracji byli wielojęzyczni. Tak więc prawdopodobieństwo lepiej opisuje sytuację, ponieważ większość części tekstu jest w jednym języku, podczas gdy inne mogą być zapisane w innym.
  2. Google API - połączenie internetowe. Wolałbym nie używać funkcji/usług zdalnych, ponieważ muszę to zrobić samodzielnie lub użyć biblioteki do pobrania. Chciałbym przeprowadzić badania na ten temat.
+0

@EugeneP: francuski byłby bardziej "Je suis un bel homme ...";), ale wykrywacz języka jest mało prawdopodobne, aby zauważyć ten błąd (lub co najmniej bardzo rzadkie wykorzystanie). – SyntaxT3rr0r

+0

@WizardOfOdds Je suis un bonhomme alors, merci, quand meme;) – EugeneP

+2

Ponadto, miej nadzieję, że już sprawdziłeś to: http://stackoverflow.com/questions/1383503/how-to-determine-the-natural-language-of- a-document –

Odpowiedz

19

Jest to pakiet o nazwie JLangDetect który wydaje się robić dokładnie to, co chcesz:

langof("un texte en français") = fr : OK 
langof("a text in english") = en : OK 
langof("un texto en español") = es : OK 
langof("un texte un peu plus long en français") = fr : OK 
langof("a text a little longer in english") = en : OK 
langof("a little longer text in english") = en : OK 
langof("un texto un poco mas largo en español") = es : OK 
langof("J'aime les bisounours !") = fr : OK 
langof("Bienvenue à Montmartre !") = fr : OK 
langof("Welcome to London !") = en : OK 
// ... 

Edit: Kevin zauważył, nie ma podobną funkcjonalność w Nutch project dostarczane przez pakiet org.apache.nutch.analysis.lang.

+0

dlaczego nie ma niemieckiego przykładu? – Chris

+0

@ Chris Cóż, dobre pytanie. Znam tylko jedną frazę, zobaczmy, czy potrafię ją poprawnie napisać. – EugeneP

+0

Nie wiem, ale niemiecki jest wymieniony jako obsługiwany język –

0

Czy masz połączenie z Internetem, jeśli nie wtedy Google Język API byłby idealny dla ciebie.

// This example request includes an optional API key which you will need to 
// remove or replace with your own key. 
// Read more about why it's useful to have an API key. 
// The request also includes the userip parameter which provides the end 
// user's IP address. Doing so will help distinguish this legitimate 
// server-side traffic from traffic which doesn't come from an end-user. 
URL url = new URL(
    "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&" 
    + "q=Paris%20Hilton&key=INSERT-YOUR-KEY&userip=USERS-IP-ADDRESS"); 
URLConnection connection = url.openConnection(); 
connection.addRequestProperty("Referer", /* Enter the URL of your site here */); 

String line; 
StringBuilder builder = new StringBuilder(); 
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
while((line = reader.readLine()) != null) { 
builder.append(line); 
} 

JSONObject json = new JSONObject(builder.toString()); 
// now have some fun with the results... 

Jeśli nie, istnieją inne metody.

3

Sprawdź łańcuchy Markowa.

Zasadniczo potrzebujesz statystycznie istotnych próbek języków, które chcesz rozpoznać. Kiedy otrzymasz nowy plik, sprawdź, jakie są częstotliwości określonych sylab lub fonemów i porównaj wstępnie obliczoną próbkę. Wybierz najbliższy.

5

W przypadku większych tekstów zazwyczaj używasz dystrybucji liter, dwuznaków, a nawet trigrafii i porównujesz ze znanymi dystrybucjami dla języków, które chcesz wykryć.

Jedno zdanie jest jednak zbyt krótkie, aby dostarczyć użytecznych statystycznych miar. Możesz mieć więcej szczęścia w dopasowywaniu pojedynczych słów ze słownikiem.

2

Chociaż bardziej skomplikowane rozwiązanie niż szukasz, możesz użyć Vowpal Wabbit i ćwiczyć go ze zdaniami z różnych języków.

Teoretycznie można uzyskać język dla każdego zdania w dokumentach.

http://hunch.net/~vw/

(Nie daj się nabrać na „online” w napisy projektu - to tylko mathspeak dla uczy się bez konieczności posiadania cały materiał do nauki w pamięci)

+0

Dziękuję za odpowiedź. – EugeneP

4

NGramJ wydaje się być nieco bardziej up-to-date:

http://ngramj.sourceforge.net/

posiada również oba profile postaci zorientowanej i bajt zorientowanych, więc powinien być w stanie zidentyfikować zestaw znaków zbyt.

W przypadku dokumentów w wielu językach należy zidentyfikować zestaw znaków (ICU4J ma CharsetDetector, który może to zrobić), a następnie podzielić tekst na coś rezonansowalnego, jak wiele podziałów linii lub akapitów, jeśli tekst jest zaznaczony.

+0

Dziękuję za odpowiedź. – EugeneP

4

Wypróbuj Nutch's Language Identifier. Jest wyszkolony z n-gramowymi profilami języków, a profil dostępnych języków jest dopasowywany do tekstu wejściowego. Interesujące jest to, że możesz dodać więcej języków, jeśli potrzebujesz.

+0

Używamy identyfikatora języka Nutcha z bardzo dobrymi wynikami. Jest to standardowa implementacja modelu bigram, który działa na języki dzielące zestaw znaków. –

2

Jeśli jesteś zainteresowany mechanizmu, dzięki któremu wykrywanie języka może być wykonane, odsyłam do poniższego article (python based), który korzysta z (bardzo) metody naiwne, ale jest to dobry wstęp do tego problemu w szczególności i uczenie maszynowe (tylko wielkie słowo) w ogóle.

Dla implementacji java, JLangDetect i Nutch sugerowane przez inne plakaty są całkiem dobre. Zobacz także: Lingpipe, JTCL i NGramJ.


za problem gdzie masz wiele języków na tej samej stronie, można użyć detektora obwiedni zdanie posiekać stronę na zdania, a następnie próbować zidentyfikować języka każdym zdaniu. Zakładając, że zdanie zawiera tylko jeden (podstawowy) język, nadal powinieneś uzyskać dobre wyniki z dowolną z powyższych implementacji.

Uwaga: Detektor granicy zdań (SBD) jest teoretycznie specyficzny dla języka (problem jaj kurcząt, ponieważ potrzebny jest jeden dla drugiego). Jednak w przypadku języków opartych na alfabecie łacińskim (angielski, francuski, niemiecki itp.), Które przede wszystkim używają okresów (oprócz wykrzykników itp.) Do odgraniczania zdań, uzyskasz akceptowalne wyniki, nawet jeśli używasz SBD zaprojektowanego dla języka angielskiego. Napisałem oparty na regułach angielski SBD, który sprawdził się bardzo dobrze w przypadku francuskiego tekstu. W przypadku implementacji spójrz na OpenNLP.

Alternatywnym rozwiązaniem do korzystania z SBD jest użycie okno przesuwne z powiedzmy 10 żetony (spacje ograniczona), aby utworzyć pseudo-zdanie (PS) i spróbować zidentyfikować granicę, gdzie zmiany językowe. Ma to tę wadę, że jeśli cały dokument zawiera n tokenów, wykonasz w przybliżeniu operacje klasyfikacyjne n-10 na łańcuchach o długości 10 tokenów każdy. W drugim podejściu, jeśli przeciętne zdanie ma 10 żetonów, wykonalibyśmy operacje klasyfikacyjne w przybliżeniu n/10. Jeśli n = 1000 słów w dokumencie, porównujesz 990 operacji ze 100 operacjami: kolejność różnicy wielkości.


Jeśli masz krótkie frazy (poniżej 20 znaków), dokładność wykrywania języka jest słaba z mojego doświadczenia. Szczególnie w przypadku rzeczowników właściwych, a także rzeczowników, które są takie same w różnych językach, takich jak "czekolada". Na przykład. Czy "New York" to angielskie słowo lub francuskie słowo, jeśli pojawia się we francuskim zdaniu?

0

Modele bigram działają dobrze, są proste w pisaniu, proste w trenowaniu i wymagają tylko niewielkiej ilości tekstu do wykrycia. Identyfikator języka nutowego jest implementacją języka Java, którą znaleźliśmy i używamy z cienkim opakowaniem.

Mieliśmy problemy z bigramem dla mieszanego tekstu CJK i angielskiego (tweet jest w większości japoński, ale ma jedno angielskie słowo). Jest to oczywiste z perspektywy czasu, patrząc na matematykę (Japończycy mają o wiele więcej znaków, więc prawdopodobieństwo danej pary jest niskie). Myślę, że mógłbyś rozwiązać to z bardziej skomplikowanym log-liniowym porównaniem, ale oszukałem i użyłem prostego filtru opartego na zestawach znaków, które są unikalne dla pewnych języków (tj. Jeśli zawiera tylko zunifikowany Han, to jest chiński, jeśli zawiera jakieś Japoński kana i zunifikowany Han, potem japoński).

Powiązane problemy