¿Hay alguna forma algorítmica de distinguir palabras multisilábicas de palabras de una sola sílaba en inglés?

Obviamente, lo más preciso es utilizar un diccionario de pronunciación como The CMU Pronunciando Dictionary. Sin embargo, es bastante fácil escribir una cuenta heurística de sílabas con una precisión de ~ 90% (y probablemente más alta para distinguir palabras monosilábicas de palabras polisilábicas). Aquí hay un trabajo rápido de diez minutos.

Una primera estimación trivial, que tiene una precisión de ~ 75% en las palabras en CMUdict (excluyendo nombres), es solo contar grupos de vocales. Contar y como vocal mejora el resultado.

def syllables_vowel_clusters(word):
return len(re.findall("[aeiouy]+", word))

Esto se puede mejorar un poco al manejar ciertas combinaciones de vocales que generalmente resultan en múltiples sílabas:

def syllables_better_vowel_clusters(word):
return len(re.findall("[aeiouy]+", word))
+ len(re.findall("eo|ia|iu|[^qg]ua|[^qg]uo", word))
+ len(re.findall("[aeiou]y[aeiou]", word))

Para mejorar esto mucho más (hasta ~ 93%), podemos agregar una docena de sufijos comunes con conteos explícitos de sílabas. Comprobar los extremos de la palabra antes del sufijo ayuda mucho (por ejemplo, -es generalmente solo agrega una sílaba si sigue a una sibilante).

class Suffix(object):
def __init__(self, suffix, syllables, condition=".*"):
self.suffix = suffix
self.syllables = syllables
self.condition = condition
def matches(self, word):
return word.endswith(self.suffix) and re.search(self.condition, word[:-len(self.suffix)])

sufijos = [
Sufijo (“le”, 1, “[^ aeiouy] $”), Sufijo (“les”, 1, “[^ aeiouy] $”),
Sufijo (“ue”, 0, “[qg] $”), Sufijo (“ues”, 0, “[qg] $”),
Sufijo (“e”, 0, “[^ aeiouy] $”), Sufijo (“es”, 0, “[^ aeiouygcszxh] $ | [^ sc] h $”),
Sufijo (“ed”, 0, “[^ aeioutd] $”), Sufijo (“s”, 0, “[^ aeiousz] $”),
Sufijo (“ing”, 1), Sufijo (“ly”, 1), Sufijo (“ful”, 1), Sufijo (“ismo”, 2)]

def syllables_suffixes (palabra):
sílabas = 0; hecho = falso
mientras no está hecho:
hecho = verdadero
para sufijo en sufijos:
if suffix.matches (word):
sílabas + = sufijo.sílabos
palabra = palabra [: – len (sufijo.suffix)]
hecho = falso
return max (1, sílabas + syllables_better_vowel_clusters (word))

Esto ciertamente podría mejorarse con más esfuerzo, aunque con rendimientos decrecientes. En algún momento llegarás al límite de lo que es posible sin un diccionario: es difícil ver cómo se pueden distinguir pares como segue vs fugue y finance vs fiance.