В зависимости от случая вам может быть интересно использовать один из следующих методов:
Метод 0: используйте API или библиотеку
Обычно с этими библиотеками возникает несколько проблем, потому что некоторые из них не подходят для небольших текстов, некоторые языки отсутствуют, они медленные, требуют подключения к Интернету, не бесплатны, ... Но в целом они подходят для большинства потребностей .
Метод 1: языковые модели
Языковая модель дает нам вероятность последовательности слов. Это важно, потому что позволяет нам надежно определять язык текста, даже если текст содержит слова на других языках (например: «Hola» означает «привет» на испанском языке » ).
Вы можете использовать N языковых моделей (по одной на каждый язык), чтобы оценить свой текст. Обнаруженный язык будет языком модели, которая дала вам наивысшую оценку.
Если вы хотите создать для этого простую языковую модель, я бы выбрал 1-грамм. Для этого вам нужно всего лишь подсчитать, сколько раз появлялось каждое слово из большого текста (например, Корпус Википедии на языке "X").
Тогда вероятность слова будет равна его частоте, деленной на общее количество проанализированных слов (сумма всех частот).
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")
Если текст для обнаружения довольно большой, я рекомендую выбрать N случайных слов, а затем использовать сумму логарифмов вместо умножения, чтобы избежать проблем с точностью с плавающей запятой.
P(s) = 0.03 * 0.01 * 0.014 = 0.0000042
P(s) = log10(0.03) + log10(0.01) + log10(0.014) = -5.376
Метод 2: пересекающиеся множества
Еще более простой подход - подготовить N наборов (по одному на каждый язык) из M самых часто встречающихся слов. Затем пересекайте свой текст с каждым набором. Набор с наибольшим количеством пересечений будет вашим обнаруженным языком.
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)
...
Метод 3: сжатие почтового индекса
Это скорее любопытство, чем что-либо еще, но вот оно ... Вы можете сжать свой текст (например, LZ77), а затем измерить расстояние zip относительно эталонного сжатого текста (целевой язык). Лично мне он не понравился, потому что он медленнее, менее точен и менее информативен, чем другие методы. Тем не менее, у этого метода могут быть интересные приложения. Чтобы узнать больше: языковые деревья и архивирование