Dependendo do caso, você pode estar interessado em usar um dos seguintes métodos:
Método 0: Use uma API ou biblioteca
Normalmente, existem alguns problemas com essas bibliotecas porque algumas delas não são precisas para textos pequenos, faltam alguns idiomas, são lentas, exigem conexão com a Internet, não são gratuitas, ... Mas, de modo geral, elas atenderão à maioria das necessidades .
Método 1: modelos de linguagem
Um modelo de linguagem nos dá a probabilidade de uma sequência de palavras. Isso é importante porque nos permite detectar de forma robusta o idioma de um texto, mesmo quando o texto contém palavras em outros idiomas (por exemplo: "'Hola' significa 'Olá' em espanhol" ).
Você pode usar N modelos de idioma (um por idioma) para pontuar seu texto. O idioma detectado será o idioma do modelo que deu a você a maior pontuação.
Se você quiser construir um modelo de linguagem simples para isso, eu escolheria 1 grama. Para fazer isso, você só precisa contar o número de vezes que cada palavra de um grande texto (por exemplo, Wikipedia Corpus no idioma "X") apareceu.
Então, a probabilidade de uma palavra será sua frequência dividida pelo número total de palavras analisadas (soma de todas as frequências).
the 23135851162
of 13151942776
and 12997637966
to 12136980858
a 9081174698
in 8469404971
for 5933321709
...
=> P("'Hola' means 'hello' in spanish") = P("hola") * P("means") * P("hello") * P("in") * P("spanish")
Se o texto a ser detectado for muito grande, recomendo amostrar N palavras aleatórias e usar a soma dos logaritmos em vez de multiplicações para evitar problemas de precisão de ponto flutuante.
P(s) = 0.03 * 0.01 * 0.014 = 0.0000042
P(s) = log10(0.03) + log10(0.01) + log10(0.014) = -5.376
Método 2: Conjuntos de intersecção
Uma abordagem ainda mais simples é preparar N conjuntos (um por idioma) com as M primeiras palavras mais frequentes. Em seguida, cruze seu texto com cada conjunto. O conjunto com o maior número de cruzamentos será o seu idioma detectado.
spanish_set = {"de", "hola", "la", "casa",...}
english_set = {"of", "hello", "the", "house",...}
czech_set = {"z", "ahoj", "závěrky", "dům",...}
...
text_set = {"hola", "means", "hello", "in", "spanish"}
spanish_votes = text_set.intersection(spanish_set)
english_votes = text_set.intersection(english_set)
czech_votes = text_set.intersection(czech_set)
...
Método 3: compressão Zip
Isso é mais uma curiosidade do que qualquer outra coisa, mas aqui vai ... Você pode compactar seu texto (por exemplo, LZ77) e então medir a distância zip em relação a um texto compactado de referência (idioma de destino). Pessoalmente, não gostei porque é mais lento, menos preciso e menos descritivo do que outros métodos. No entanto, pode haver aplicações interessantes para este método. Para ler mais: Árvores de linguagem e compactação