contextual-langdetect
A context-aware language detection library that improves accuracy by considering document-level language patterns.
Use Case
This library is designed for processing corpora where individual lines or sentences might be in different languages, but with a strong prior that there are only one or two primary languages. It uses document-level context to improve accuracy in cases where individual sentences might be ambiguously detected.
For example, in a primarily Chinese corpus:
- Some sentences might be detected at an individual level as Japanese, but if they don't contain kana characters, they're likely Chinese
- Some sentences might be detected as Wu Chinese (wuu), but in a Mandarin context they're likely Mandarin
- The library uses the dominant language(s) in the corpus to resolve these ambiguities
This is particularly useful for:
- Transcriptions of bilingual conversations, including
- Language instruction texts and transcriptions
- Mixed-language documents where the majority language should inform ambiguous cases
Features
- Accurate language detection with confidence scores
- Context-aware detection that uses surrounding text to disambiguate
- Special case handling for commonly confused languages (e.g., Wu Chinese, Japanese without kana)
- Support for mixed language documents
Installation
pip install contextual-langdetect
Usage
contextual_detect
from contextual_langdetect import contextual_detect
# Process a document with context-awareness
sentences = [
"你好。", # Detected as ZH
"你好吗?", # Detected as ZH
"很好。", # Detected as JA when model=small
"我家也有四个,刚好。", # Detected as ZH
"那么现在天气很冷,你要开暖气吗?", # Detected as WUU
"Okay, fine I'll see you next week.", # English
"Great, I'll see you then.", # English
]
# Context-unaware language detection
languages = contextual_detect(sentences, context_correction=False)
print(languages)
# Output: ['zh', 'zh', 'ja', 'zh', 'wuu', 'en', 'en']
# Context-aware language detection
languages = contextual_detect(sentences)
print(languages)
# Output: ['zh', 'zh', 'zh', 'zh', 'zh', 'en', 'en']
# Context-aware detection with language biasing
# Specify expected languages to improve detection in ambiguous cases
languages = contextual_detect(sentences, languages=["zh", "en"])
print(languages)
# Output: ['zh', 'zh', 'zh', 'zh', 'zh', 'en', 'en']
# Force a specific language for all sentences
languages = contextual_detect(sentences, languages=["en"])
print(languages)
# Output: ['en', 'en', 'en', 'en', 'en', 'en', 'en']
Detailed results and configuration
Use contextual_detect_detailed to inspect the raw detector result, the final
language, confidence scores, probability maps, and the reason for a correction:
from contextual_langdetect import DetectionConfig, contextual_detect_detailed
config = DetectionConfig(
confidence_threshold=0.75,
language_bias=1.3,
)
results = contextual_detect_detailed(sentences, languages=["zh", "en"], config=config)
for result in results:
print(result.raw_language, result.language, result.correction_reason)
DetectionConfig also controls the bias-override threshold, document-context
probability threshold, primary-language ratio, and number of candidate
languages requested from the underlying detector.
count_by_language
def count_by_language(
sentences: Sequence[str],
languages: Sequence[LanguageCode] | None = None,
model: ModelSize = ModelSize.SMALL,
context_correction: bool = True,
*,
config: DetectionConfig = DEFAULT_CONFIG,
) -> dict[LanguageCode, int]
Given a batch of sentences, returns a dict mapping language codes to the number of sentences assigned to each language, using the contextual detection algorithm.
Example:
from contextual_langdetect.detection import count_by_language
sentences = [
"Hello world.",
"Bonjour le monde.",
"Hallo Welt.",
"Hello again.",
]
counts = count_by_language(sentences)
# Example output: {'en': 2, 'fr': 1, 'de': 1}
get_languages_by_count
def get_languages_by_count(
sentences: Sequence[str],
languages: Sequence[LanguageCode] | None = None,
model: ModelSize = ModelSize.SMALL,
context_correction: bool = True,
*,
config: DetectionConfig = DEFAULT_CONFIG,
) -> list[LanguageCode]
Given a batch of sentences, returns the detected language codes sorted by decreasing count, using the contextual detection algorithm.
Example:
from contextual_langdetect.detection import get_languages_by_count
sentences = [
"Hello world.",
"Bonjour le monde.",
"Hallo Welt.",
"Hello again.",
]
language_counts = get_languages_by_count(sentences)
# Example output: ['en', 'fr', 'de']
get_majority_language
def get_majority_language(
sentences: Sequence[str],
languages: Sequence[LanguageCode] | None = None,
model: ModelSize = ModelSize.SMALL,
context_correction: bool = True,
*,
config: DetectionConfig = DEFAULT_CONFIG,
) -> LanguageCode | None
Given a batch of sentences, returns the language code with the highest count (the majority language), or None if there are no sentences.
Example:
from contextual_langdetect.detection import get_majority_language
sentences = [
"Hello world.",
"Bonjour le monde.",
"Hallo Welt.",
"Hello again.",
]
majority_language = get_majority_language(sentences)
# Example output: 'en'
Dependencies
This library builds upon:
- LlmKira/fast-langdetect for base language detection
- fasttext-predict (transitively), which provides the FastText bindings
- FastText by Facebook, which these projects wrap
Development
For development instructions, see DEVELOPMENT.md.
Documentation
- Context-Aware Detection - Learn how the context-aware language detection algorithm works
My Related Projects
- add2anki - Browser extension to add
words and phrases to Anki language learning decks.
contextual-langdetectwas extracted from this. - audio2anki - Extract audio from video
files for creating Anki language flashcards.
add2ankiwas developed to support this and other tools.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
Oliver Steele (@osteele on GitHub)
Metadata
Release files for contextual-langdetect 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| contextual_langdetect-0.3.0.tar.gz | 55.9 kB | Without provenance | Details for contextual_langdetect-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| contextual_langdetect-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for contextual_langdetect-0.3.0-py3-none-any.whl |
Total release size: 65.1 kB
Release files / contextual_langdetect-0.3.0.tar.gz
| Download URL | contextual_langdetect-0.3.0.tar.gz |
|---|---|
| Size | 55.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3f67855d84415f39ab679c63a273dc813df5fdb5b3989a17edebfe870579e55a
|
|
BLAKE2b-256 checksum How to use checksums |
4d692ddef2cf5fe549ce659e8a70821e473d470661c0fb923f54093d645fe5ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.2
|
Release files / contextual_langdetect-0.3.0-py3-none-any.whl
| Download URL | contextual_langdetect-0.3.0-py3-none-any.whl |
|---|---|
| Size | 9.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4316cf8657f714099ce05fd8552c813c77fb3e8ff06bc6d491ec4f1317dc9beb
|
|
BLAKE2b-256 checksum How to use checksums |
4ff3d398572bb92097beb86b666b2912dd43ab04ff9ee61c729f435a0c20a848
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.6.2
|
Security for contextual-langdetect 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.