Как узнать язык строки с помощью Python? Библиотеки и алгоритмы
Определение языка, на котором написана строка текста, является важной задачей во многих приложениях: маршрутизация сообщений, перевод, анализ тональности, фильтрация контента. В Python существует несколько способов решения этой задачи, от простых эвристик до мощных библиотек машинного обучения.
Определение языка с помощью библиотеки langdetect
Как распознать язык текста с использованием langdetect?
Библиотека langdetect основана на алгоритме Google Language Detection. Она проста в использовании и обеспечивает хорошую точность для большинства языков.
Установка: pip install langdetect
from langdetect import detect
text1 = "Привет, как дела?"
lang1 = detect(text1)
print(lang1) # ru
text2 = "Hello, how are you?"
lang2 = detect(text2)
print(lang2) # enPython определить язык строки (определение языка строки в python)
ru en
номера телефонов python (работа с номерами телефонов в python)
Функция detect возвращает двухбуквенный код языка (ISO 639-1). Для получения вероятностей используется detect_langs.
Возможные проблемы:
- На очень коротких текстах (менее 10 символов) определение может быть неточным.
- При пустой строке возникает исключение
langdetect.lang_detect_exception.LangDetectException. Рекомендуется проверять длину текста перед вызовом. - Библиотека не поддерживает некоторые редкие языки.
Данный метод подходит для быстрого определения языка в скриптах и веб-приложениях, где требуется высокая скорость.
Как определить язык с помощью библиотеки langid?
langid – еще одна популярная библиотека, отличающаяся высокой скоростью и поддержкой 97 языков.
import langid
text = "Bonjour tout le monde"
lang, confidence = langid.classify(text)
print(f"Язык: {lang}, уверенность: {confidence}")
Язык: fr, уверенность: -0.0
Метод classify возвращает кортеж (код языка, оценка логарифмической вероятности). Чем больше значение, тем выше уверенность.
Проблемы: langid может ошибаться на смешанных языках или коротких фрагментах. Для получения только языка без вероятности используется langid.langid.rank.
Как использовать fastText для идентификации языка?
Библиотека fastText от Facebook предлагает предобученную модель для определения 176 языков. Требуется загрузить модель (около 1 ГБ).
import fasttext
model = fasttext.load_model('lid.176.bin')
text = "Esto es una prueba"
pred = model.predict(text)
print(pred)
(('__label__es',), array([0.999...]))
Результат содержит метку языка и вероятность. Модель показывает высокую точность даже на коротких текстах.
Проблемы: большой размер модели (1 ГБ) и время загрузки. Для повторного использования модель можно загружать один раз.
Как грубо определить язык по набору символов без внешних библиотек?
Для различения языков с разными алфавитами (русский, английский, арабский) можно использовать диапазоны Unicode.
def detect_lang_simple(text):
cyrillic = sum(1 for c in text if 'А' <= c <= 'я' or c in 'Ёё')
latin = sum(1 for c in text if 'a' <= c <= 'z' or 'A' <= c <= 'Z')
if cyrillic > latin:
return 'ru'
elif latin > cyrillic:
return 'en'
else:
return 'unknown'
print(detect_lang_simple("Привет"))
print(detect_lang_simple("Hello"))
ru en
Этот метод подходит для простых случаев, когда языки используют непересекающиеся алфавиты. Для смешанных текстов (например, английский с кириллическими именами) точность низкая.
Ошибка: не различает французский и английский, так как оба используют латиницу. Также не учитывает другие алфавиты.
Как определить язык с помощью Polyglot?
Polyglot – библиотека для обработки естественного языка, включающая детектор языка.
from polyglot.detect import Detector
text = "Ciao mondo"
try:
detector = Detector(text)
print(detector.language.code)
except Exception as e:
print(e)
Требуется установка дополнительных зависимостей (libicu).
Пакетное определение языка для списка строк с langdetect
from langdetect import detect, LangDetectException
texts = ["Hola amigo", "Buongiorno", "Guten Tag", "你好"]
for t in texts:
try:
lang = detect(t)
print(f"{t} -> {lang}")
except LangDetectException:
print(f"{t} -> ошибка")
Hola amigo -> es Buongiorno -> it Guten Tag -> de 你好 -> zh-cn
В этом примере обрабатывается список строк, и для каждой вызывается detect. Ошибки перехватываются, чтобы избежать прерывания при пустых или проблемных строках.
Определение языка с вероятностями с помощью detect_langs
from langdetect import detect_langs
text = "I love programming"
langs = detect_langs(text)
for lang in langs:
print(f"{lang.lang}: {lang.prob:.3f}")
en: 0.999 ...
Функция detect_langs возвращает список объектов с кодом языка и вероятностью. Позволяет увидеть несколько возможных вариантов и их уверенность.
Использование fastText с предзагруженной моделью
import fasttext
model = fasttext.load_model('lid.176.bin')
texts = ["Hola mundo", "Привет мир", "こんにちは"]
for t in texts:
pred = model.predict(t)[0][0].replace('__label__', '')
prob = model.predict(t)[1][0]
print(f"{t} -> {pred} (уверенность: {prob:.3f})")
Hola mundo -> es (уверенность: 0.999) Привет мир -> ru (уверенность: 1.000) こんにちは -> ja (уверенность: 0.997)
fastText требует загрузки предобученной модели. После загрузки вызов predict работает быстро и дает высокое качество даже на коротких фразах.
Простой детектор с определением письменности по Юникоду
import unicodedata
def detect_script(text):
scripts = {'Cyrillic': 0, 'Latin': 0, 'Arabic': 0, 'Hangul': 0}
for ch in text:
try:
script = unicodedata.name(ch).split(' ')[0] if ch.isalpha() else None
if script in scripts:
scripts[script] += 1
except ValueError:
pass
return max(scripts, key=scripts.get) if max(scripts.values()) > 0 else 'unknown'
print(detect_script("안녕하세요"))
print(detect_script("مرحبا"))
Hangul Arabic
Этот метод использует категории Юникода для определения преобладающей системы письма. Полезен для грубой классификации, когда языки имеют разные алфавиты.
Сравнение производительности langdetect и langid
import time
from langdetect import detect as ldetect
import langid
text = "This is a sample text to measure performance." * 1000
start = time.time()
for _ in range(100):
ldetect(text)
print("langdetect:", time.time() - start)
start = time.time()
for _ in range(100):
langid.classify(text)
print("langid:", time.time() - start)
langdetect: 0.45 langid: 0.32
Результаты могут варьироваться в зависимости от системы, но langid часто оказывается быстрее на длинных текстах. Для производственных нагрузок стоит учитывать это различие.