2011-01-05 7 views
8

Estoy buscando una manera simple de detectar si un breve fragmento de texto, algunas oraciones, es inglés o no. Me parece que este problema es mucho más fácil que tratar de detectar un lenguaje arbitrario. ¿Hay algún software que pueda hacer esto? Estoy escribiendo en Python, y preferiría una biblioteca de Python, pero otra cosa estaría bien también. Probé con Google, pero luego me di cuenta de que el TOS no permitía las consultas automáticas.Detectando si el texto es inglés (a granel)

+1

posible duplicado de [Python - ¿puedo detectar código de lenguaje de cadena unicode?] (Http://stackoverflow.com/questions/4545977/python-can-i-detect-unicode-string-language-code) – ismail

+2

I ' Estoy pidiendo solo inglés aquí, a diferencia de ese hilo donde piden cualquier lenguaje arbitrario. – user449511

+0

Simplemente funciona bien para el inglés. – ismail

Respuesta

10

Leo un método para detectar langauge Enlgish mediante el uso de trigramas

http://en.wikipedia.org/wiki/Trigram

Usted puede ir sobre el texto, y tratar de detectar los trigramas más utilizados en el palabras. Si los más utilizados corresponden con la más usada entre palabras en inglés, el texto puede ser escrito en Inglés

tratar de buscar en este proyecto rubí:

https://github.com/feedbackmine/language_detector

+0

+1 para Trigams - muy bueno. –

+0

¡Gracias!Esta es una idea fácil de implementar. Puedo hacer una prueba rápida con un pequeño conjunto de texto de prueba para ver qué tan bien funciona. – user449511

+0

Esto va a requerir un gran lote de texto de muestra. OP podría no tener acceso a eso. – marcog

4

EDITAR: Esto no funcionará en este caso, ya que OP está procesando texto a granel que va en contra de los TOS de Google.

Utilice el Google Translate language detect API. ejemplo de Python desde la documentación:

url = ('https://ajax.googleapis.com/ajax/services/language/detect?' + 
     'v=1.0&q=Hola,%20mi%20amigo!&key=INSERT-YOUR-KEY&userip=INSERT-USER-IP') 
request = urllib2.Request(url, None, {'Referer': /* Enter the URL of your site here */}) 
response = urllib2.urlopen(request) 
results = simplejson.load(response) 
if results['responseData']['language'] == 'en': 
    print 'English detected' 
+0

"La API de detección de idioma de Google se debe utilizar para la detección de idioma generado por el usuario. Las consultas automáticas o por lotes de cualquier tipo están estrictamente prohibidas". Supongo que es por eso que el que hace la pregunta se refiere a los Términos del Servicio que también vio, y asumo que por lo tanto quiere detectar un idioma sin la intervención del usuario. –

+0

@tomlog Probablemente tengas razón. Pensé que se refería a raspar páginas de GT. @user, ¿puede confirmar si está procesando cadenas generadas por el usuario? – marcog

+0

Estaba consultando por lotes su API con mi texto y me negaron el acceso y me di cuenta de mi problema. No estoy usando cadenas generadas por el usuario. ¡Gracias! – user449511

1

Altough no tan bueno como propia de Google, He obtenido buenos resultados con Apache Nutch LanguageIdentifier, que viene con sus propios modelos de ngram prediseñados. Obtuve resultados bastante buenos en un gran corpus (50GB pdf, texto en su mayoría) de datos del mundo real en varios idiomas.

Está en Java, pero estoy seguro de que puede volver a leer los perfiles de ngram si desea volver a implementarlo en Python.

0

Hace poco escribí una solución para esto. Mi solución no es a prueba de tontos y no creo que sea computacionalmente viable para grandes cantidades de texto, pero me parece que funciona bien para oraciones pequeñas.

Suponga que tiene dos cadenas de texto:

  1. "LETMEBEGINBYSAYINGTHANKS"
  2. "UNGHSYINDJFHAKJSNFNDKUAJUD"

El objetivo es, pues, para determinar que es probable 1. 2. Inglés, mientras que no es . Intuitivamente, la forma en que mi mente determina esto es buscando los límites de palabras de las palabras en inglés en las oraciones (LET, ME, BEGIN, etc.). Pero esto no es sencillo desde el punto de vista computacional porque hay palabras superpuestas (BE, GIN, BEGIN, SAY, SAYING, GRAK, THANKS, etc.).

Mi método realiza lo siguiente:

  1. Tome la intersección de { known English words } y { all substrings of the text of all lengths }.
  2. Construye un gráfico de vértices, cuyas posiciones son los índices de inicio de las palabras en la oración, con los bordes dirigidos a las posiciones iniciales de la letra después del final de la palabra. Por ejemplo, (0) sería L, por lo que "LET" podría estar representado por (0) -> (3), donde (3) es M por lo que es "LET ME".
  3. Encuentra el número entero más grande n entre 0 y len(text) para el que existe una ruta directa desde el índice 0 al índice n.
  4. Divida ese número n por la longitud del texto para tener una idea aproximada de qué porcentaje del texto parece ser palabras consecutivas en inglés.

Tenga en cuenta que mi código asume que no hay espacios entre las palabras, pero imagino que podría adaptarlo para considerar los espacios con bastante facilidad. No es que para que funcione mi código necesita un archivo de lista de palabras en inglés. Obtuve uno de here, pero puede usar cualquier archivo de ese tipo, y me imagino que de esta manera esta técnica podría extenderse a otros idiomas también.

Aquí está el código:

from collections import defaultdict 

# This function tests what percent of the string seems to me to be maybe 
# English-language 
# We use an English words list from here: 
# https://github.com/first20hours/google-10000-english 
def englishness(maybeplaintext): 
    maybeplaintext = maybeplaintext.lower() 
    f = open('words.txt', 'r') 
    words = f.read() 
    f.close() 
    words = words.lower().split("\n") 
    letters = [c for c in maybeplaintext] 
    # Now let's iterate over letters and look for some English! 
    wordGraph = defaultdict(list) 
    lt = len(maybeplaintext) 
    for start in range(0, lt): 
     st = lt - start 
     if st > 1: 
      for length in range(2, st): 
       end = start + length 
       possibleWord = maybeplaintext[start:end] 
       if possibleWord in words: 
        if not start in wordGraph: 
         wordGraph[start] = [] 
        wordGraph[start].append(end) 
    # Ok, now we have a big graph of words. 
    # What is the shortest path from the first letter to the last letter, 
    # moving exclusively through the English language? 
    # Does any such path exist? 
    englishness = 0 
    values = set([a for sublist in list(wordGraph.values()) for a in sublist]) 
    numberVertices = len(set(wordGraph.keys()).union(values)) 
    for i in range(2, lt): 
     if isReachable(numberVertices, wordGraph, i): 
      englishness = i 
    return englishness/lt 

# Here I use my modified version of the technique from: 
# https://www.geeksforgeeks.org/ 
# find-if-there-is-a-path-between-two-vertices-in-a-given-graph/ 
def isReachable(numberVertices, wordGraph, end): 
    visited = [0] 
    queue = [0] 
    while queue: 
     n = queue.pop(0) 
     if n == end or n > end: 
      return True 
     for i in wordGraph[n]: 
      if not i in visited: 
       queue.append(i) 
       visited.append(i) 
    return False 

Y aquí es I/O para los ejemplos iniciales que di:

In [5]: englishness('LETMEBEGINBYSAYINGTHANKS') 
Out[5]: 0.9583333333333334 

In [6]: englishness('UNGHSYINDJFHAKJSNFNDKUAJUD') 
Out[6]: 0.07692307692307693 

Entonces, aproximadamente hablando, estoy 96% seguro de que LETMEBEGINBYSAYINGTHANKS es Inglés, y 8% seguro de que UNGHSYINDJFHAKJSNFNDKUAJUD es inglés. ¡Lo cual suena bien!

Para extender esto a piezas de texto mucho más grandes, mi sugerencia sería submuestrear subcadenas cortas aleatorias y verificar su "inglés". ¡Espero que esto ayude!

+0

Un profesor mío observó que mi técnica podría mejorarse yendo hacia atrás en lugar de avanzar a través del gráfico, asumiendo que la mayoría de las veces no miramos el inglés. Además, creo que se podría hacer una pequeña mejora con un método de búsqueda bisecado, para deshacerse de las comprobaciones innecesarias: el clima o no, esto mejoraría las cosas que probablemente dependan de la distribución de frecuencia de la inglésidad de la entrada. –

Cuestiones relacionadas