2010-02-24 17 views
25

Supponiamo di avere un file di testo con il contenuto: "Je suis un beau homme ..."Come si dice in quale lingua è scritto un file di testo semplice?

l'altro con: "Io sono un uomo coraggioso"

il terzo con un testo in tedesco: "Guten morgen. Wie geht's?"

Come scriviamo una funzione che ci dirà: con una tale probabilità il testo nel primo file è in inglese, nel secondo abbiamo francese ecc.?

Collegamenti a libri/soluzioni pronte per l'uso. Scrivo in Java, ma posso imparare Python se necessario.

I miei commenti

  1. C'è un piccolo commento Ho bisogno di aggiungere. Il testo può contenere frasi in diverse lingue, come parte di tutto o come risultato di un errore. Nella letteratura classica abbiamo molti esempi, perché i membri dell'aristocrazia erano multilingue. Quindi la probabilità descrive meglio la situazione, poiché molte parti del testo sono in una lingua, mentre altre possono essere scritte in un'altra lingua.
  2. API Google - Connessione Internet. Preferirei non utilizzare funzioni/servizi remoti, poiché ho bisogno di farlo da solo o utilizzare una libreria scaricabile. Mi piacerebbe fare una ricerca su questo argomento.
+0

@EugeneP: il francese sarebbe più "Je suis un bel homme ...";) ma è improbabile che un rivelatore di linguaggio identifichi quell'errore (o almeno un uso molto raro). – SyntaxT3rr0r

+0

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

+2

Inoltre, spero che tu abbia già controllato questo: http://stackoverflow.com/questions/1383503/how-to-determine-the-natural-language-of- a-document –

risposta

19

C'è un pacchetto chiamato JLangDetect che sembra fare esattamente quello che vuoi:

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: come Kevin ha sottolineato, c'è una funzionalità simile in Nutch project fornito dal pacchetto org.apache.nutch.analysis.lang.

+0

perché non esiste un esempio tedesco? – Chris

+0

@Chris Beh, una bella domanda. Conosco solo una frase, vediamo se riesco a scriverla correttamente. – EugeneP

+0

Non lo so, ma il tedesco è elencato come lingua supportata –

0

Avete connessione a Internet se non allora Google Lingua API sarebbe perfetto per voi.

// 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... 

Se non ci sono altri metodi.

3

Cercare catene Markov.

Fondamentalmente sono necessari campioni statisticamente significativi delle lingue che si desidera riconoscere. Quando ottieni un nuovo file, vedi quali sono le frequenze di specifiche sillabe o fonemi e confronta il campione precalcolato. Scegli il più vicino.

5

Per i corpi di testo più grandi di solito si utilizza la distribuzione di lettere, digrammi e persino i trigrafi e si confronta con le distribuzioni conosciute per le lingue che si desidera rilevare.

Tuttavia, una singola frase è molto probabilmente troppo breve per fornire misure statistiche utili. Potresti avere più fortuna nell'abbinare le singole parole con un dizionario, quindi.

2

Sebbene sia una soluzione più complicata di quella che si sta cercando, è possibile utilizzare Vowpal Wabbit e addestrarlo con frasi di lingue diverse.

In teoria è possibile ottenere una lingua per ogni frase nei documenti.

http://hunch.net/~vw/

(Non fatevi ingannare dal "on-line" nel sottotitolo del progetto - questo è solo mathspeak per impara senza dover avere tutto il materiale didattico in memoria)

+0

Grazie per la risposta. – EugeneP

4

NGramJ sembra essere un po ' più up-to-date:

http://ngramj.sourceforge.net/

ha anche entrambi i profili carattere orientato e orientati ai byte, quindi dovrebbe essere in grado di identificare il set di caratteri troppo.

Per i documenti in più lingue è necessario identificare il set di caratteri (ICU4J ha un CharsetDetector che può farlo), quindi dividere il testo su qualcosa di risonabile come più interruzioni di riga o paragrafi se il testo è marcato.

+0

Grazie per la risposta. – EugeneP

4

Prova Nutch's Language Identifier. È formato con i profili n-gram di lingue e il profilo delle lingue disponibili è abbinato al testo di input. La cosa interessante è che puoi aggiungere più lingue, se necessario.

+0

Utilizziamo l'identificatore della lingua di nutch con ottimi risultati. È un'implementazione standard di un modello di bigram che funziona per le lingue che condividono un set di caratteri. –

2

Se sei interessato al meccanismo con cui è possibile eseguire il rilevamento della lingua, ti rimando al seguente article (basato su python) che utilizza un metodo (molto) ingenuo ma è una buona introduzione a questo problema in particolare e machine learning (solo una parolona) in generale.

Per le implementazioni java, JLangDetect e Nutch, come suggerito dagli altri poster, sono piuttosto buoni. Date anche un'occhiata a Lingpipe, JTCL e NGramJ.


Per il problema in cui si dispone di più lingue nella stessa pagina, è possibile utilizzare un rilevatore di condanna di confine per tagliare una pagina in frasi e quindi tentare di identificare la lingua di ogni frase. Supponendo che una frase contenga solo una (primaria) lingua, si dovrebbero comunque ottenere buoni risultati con una qualsiasi delle suddette implementazioni.

Nota: un rilevatore di limiti di frase (SBD) è teoricamente specifico del linguaggio (problema dell'uovo di gallina poiché è necessario l'uno per l'altro). Ma per le lingue basate su script latini (inglese, francese, tedesco, ecc.) Che utilizzano principalmente periodi (tranne esclamazioni, ecc.) Per delimitare le frasi, otterrete risultati accettabili anche se utilizzate una SBD progettata per l'inglese. Ho scritto un SBD inglese basato su regole che ha funzionato molto bene per il testo francese. Per le implementazioni, dai un'occhiata a OpenNLP.

Un'opzione alternativa all'uso della SBD è quello di utilizzare una finestra scorrevole di dire 10 gettoni (delimitata da spazi bianchi) per creare un pseudo-frase (PS) e cercare di identificare il confine in cui la lingua cambia. Questo ha lo svantaggio che se il tuo intero documento ha n token, eseguirai approssimativamente n-10 operazioni di classificazione su stringhe di lunghezza 10 token ciascuna. Nell'altro approccio, se la frase media ha 10 token, avresti eseguito approssimativamente n/10 operazioni di classificazione. Se n = 1000 parole in un documento, stai confrontando 990 operazioni contro 100 operazioni: una differenza di ordine di grandezza.


Se si hanno brevi frasi (meno di 20 caratteri), la precisione della rilevazione della lingua è scarsa nella mia esperienza. Soprattutto nel caso di nomi propri e nomi uguali in lingue come "cioccolato". Per esempio. "New York" è una parola inglese o francese se compare in una frase francese?

0

I modelli bigram funzionano bene, sono semplici da scrivere, semplici da addestrare e richiedono solo una piccola quantità di testo per il rilevamento. L'identificatore del linguaggio nutch è un'implementazione java che abbiamo trovato e utilizzata con un wrapper sottile.

Abbiamo avuto problemi con un modello bigram per CJK misto e testo in inglese (ad esempio un tweet è prevalentemente giapponese, ma ha una sola parola inglese). Questo è ovvio in retrospettiva dal considerare la matematica (il giapponese ha molti più caratteri, quindi le probabilità di ogni coppia data sono basse). Penso che potresti risolvere questo con qualche più complicato confronto log-lineare, ma ho imbrogliato e ho usato un semplice filtro basato su set di caratteri che sono unici per certe lingue (cioè se contiene solo Han unificato, quindi è cinese, se contiene alcuni Kana giapponese e Han unificato, quindi è giapponese).

Problemi correlati