portada-s-index
Biblioteca de algoritmos de similitud para desambiguación de términos históricos.
Diseñada para resolver el problema de normalizar términos ruidosos provenientes de OCR o transcripción manuscrita contra listas de entidades conocidas con sus variantes controladas (voces). Cada término evaluado recibe una clasificación basada en un sistema de votos entre múltiples algoritmos configurables.
Instalación
# Algoritmos léxicos y fonéticos (instalación base)
pip install portada-s-index
# Con embeddings densos (Tex2Vec / SentenceTransformers)
pip install "portada-s-index[with-embeddings]"
# Con FastText
pip install "portada-s-index[with-fasttext]"
# Con ByT5
pip install "portada-s-index[with-byt5]"
# Todo incluido
pip install "portada-s-index[all]"
Uso básico
from portada_s_index import SimilarityService
from portada_s_index.data import VoiceList
# 1. Definir las entidades conocidas con sus variantes
voices = {
"BERGANTIN": ["bergantín", "bgn", "berg.", "brigantine", "brig", "br"],
"BOMBARDA": ["bombarda", "bombarde", "bom", "bomb"],
"BALANDRA": ["balandra", "balandro", "bal.", "baland."],
}
voice_list = VoiceList.from_dict("ship_type", voices)
# 2. Configurar los algoritmos
config = {
"version": 2,
"normalize": True,
"consensus": {
"min_votes": 2,
"require_levenshtein_ocr": True
},
"algorithms": {
"levenshtein_ocr": {
"enabled": True,
"threshold": 0.75,
"gray_zone": [0.71, 0.749],
"params": {"confusion_cost": 0.4}
},
"jaro_winkler": {
"enabled": True,
"threshold": 0.85,
"gray_zone": [0.80, 0.849],
"params": {"prefix_weight": 0.1}
},
"ngram_2": {
"enabled": True,
"threshold": 0.63,
"gray_zone": [0.60, 0.629],
"params": {"n": 2}
},
}
}
# 3. Crear el servicio
service = SimilarityService.from_dict(config)
# 4. Evaluar términos
terms = [
{"term": "brig", "frequency": 34},
{"term": "bergt", "frequency": 8},
{"term": "xyz99", "frequency": 1},
]
results = service.evaluate(terms, voice_list)
La configuración también puede cargarse desde un archivo JSON:
service = SimilarityService.from_file("config.json")
Formato de entrada y salida
Entrada — términos
[
{"term": "brig", "frequency": 34},
{"term": "bergt", "frequency": 8},
]
Entrada — voces
# Desde dict
VoiceList.from_dict("ship_type", {
"BERGANTIN": ["bergantín", "bgn", "brig"],
"BOMBARDA": ["bombarda", "bom"],
})
# Desde archivo .txt con formato jerárquico
VoiceList.from_txt("ship_type", "listas/lista_barcos.txt")
Formato del .txt:
BERGANTIN:
- bergantín
- bgn
- brig
BOMBARDA:
- bombarda
- bom
Salida — JSON de resultado por término
{
"term": "bergt",
"frequency": 8,
"normalized": "bergt",
"exact_match": false,
"classification": "CONSENSUS",
"entity": "BERGANTIN",
"voice": "berg",
"votes": 3,
"algorithm_scores": [
{
"algorithm": "levenshtein_ocr",
"best_voice": "berg",
"best_entity": "BERGANTIN",
"score": 0.8,
"threshold": 0.75,
"voted": true,
"in_gray_zone": false
},
{
"algorithm": "jaro_winkler",
"best_voice": "berg",
"best_entity": "BERGANTIN",
"score": 0.96,
"threshold": 0.85,
"voted": true,
"in_gray_zone": false
},
{
"algorithm": "ngram_2",
"best_voice": "berg",
"best_entity": "BERGANTIN",
"score": 0.75,
"threshold": 0.63,
"voted": true,
"in_gray_zone": false
}
]
}
Clasificaciones
| Clasificación | Condición |
|---|---|
EXACT |
El término normalizado existe directamente como voz conocida |
CONSENSUS |
≥ min_votes algoritmos votan por la misma entidad |
WEAK |
≥ 2 votos por una entidad pero sin cumplir todos los requisitos |
ONE_VOTE |
Solo 1 algoritmo votó a favor |
GRAY_ZONE |
Ningún voto pero al menos 1 algoritmo en zona de incertidumbre |
REJECTED |
Sin coincidencias significativas |
Algoritmos disponibles
| Clave JSON | Tipo | Descripción | Dependencia |
|---|---|---|---|
levenshtein_ocr |
Léxico | Levenshtein con costo reducido para confusiones OCR | — |
levenshtein_ratio |
Léxico | Levenshtein estándar normalizado | — |
jaro_winkler |
Léxico | Jaro-Winkler con peso de prefijo configurable | — |
ngram_2 |
Léxico | Jaccard de bigramas de caracteres | — |
ngram_3 |
Léxico | Jaccard de trigramas de caracteres | — |
ngram_4 |
Léxico | Jaccard de cuatrigramas de caracteres | — |
phonetic_dm |
Fonético | Double Metaphone | metaphone |
soundex |
Fonético | Soundex clásico | jellyfish |
semantica |
Semántico | Jaccard sobre tokens normalizados | — |
text2vec |
Semántico | Coseno de vectores TF de n-gramas de caracteres | — |
semantic_model |
Embedding | Embeddings densos (Tex2Vec / SentenceTransformers) | with-embeddings |
fasttext |
Embedding | Embeddings FastText de subpalabras | with-fasttext |
byt5 |
Embedding | Embeddings ByT5 byte-level | with-byt5 |
Configuración detallada
Cada algoritmo se configura de forma independiente en el JSON:
{
"version": 2,
"normalize": true,
"consensus": {
"min_votes": 2,
"require_levenshtein_ocr": true
},
"algorithms": {
"levenshtein_ocr": {
"enabled": true,
"threshold": 0.75,
"gray_zone": [0.71, 0.749],
"params": {
"confusion_cost": 0.4
}
},
"jaro_winkler": {
"enabled": true,
"threshold": 0.85,
"gray_zone": [0.8, 0.849],
"params": {
"prefix_weight": 0.1
}
},
"ngram_2": {
"enabled": true,
"threshold": 0.63,
"gray_zone": [0.6, 0.629],
"params": {
"n": 2
}
},
"phonetic_dm": {
"enabled": false,
"threshold": 0.85,
"gray_zone": [0.8, 0.849],
"params": {}
}
}
}
| Campo | Descripción |
|---|---|
normalize |
Aplica normalización de texto antes de comparar |
consensus.min_votes |
Mínimo de algoritmos que deben coincidir en la misma entidad |
consensus.require_levenshtein_ocr |
Si true, levenshtein_ocr debe estar entre los votantes |
algorithms.*.enabled |
Activa o desactiva el algoritmo |
algorithms.*.threshold |
Score mínimo para que el algoritmo emita un voto |
algorithms.*.gray_zone |
Rango [piso, techo] de incertidumbre, por debajo del umbral |
algorithms.*.params |
Parámetros específicos del algoritmo |
Cache de modelos
Los modelos de embeddings se cachean automáticamente:
- En memoria: el modelo se carga una sola vez por sesión.
- En disco: los embeddings de las voces se guardan en
~/.portada_s_index/cache/y se reutilizan entre ejecuciones. Si la lista de voces o el modelo cambian, el cache se invalida solo.
from portada_s_index import ModelCache
# Ver modelos en memoria
print(ModelCache.models_in_memory())
# Ver embeddings en disco
print(ModelCache.embeddings_on_disk())
# Limpiar cache
ModelCache.clear_model()
ModelCache.clear_embeddings()
Licencia
MIT
Metadata
Release files for portada-s-index 0.2.3
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 |
|---|---|---|---|---|
| portada_s_index-0.2.3.tar.gz | 265.2 kB | Without provenance | Details for portada_s_index-0.2.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| portada_s_index-0.2.3-py3-none-any.whl | Python 3 | none | any | Details for portada_s_index-0.2.3-py3-none-any.whl |
Total release size: 299.6 kB
Release files / portada_s_index-0.2.3.tar.gz
| Download URL | portada_s_index-0.2.3.tar.gz |
|---|---|
| Size | 265.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d495cece89159a1e706e0db7812e0279c70d78be43dd853e5b7350e971a1d1c5
|
|
BLAKE2b-256 checksum How to use checksums |
0ed1e5f5efd8aeca8c40bc761e2ef7cf4c74451d28f7adef70f76ac8a8963e49
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / portada_s_index-0.2.3-py3-none-any.whl
| Download URL | portada_s_index-0.2.3-py3-none-any.whl |
|---|---|
| Size | 34.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
62aa870b1dffac54ba12c74098e47b4de96fcf05677ebe4b2ec3fbcdd17f09d5
|
|
BLAKE2b-256 checksum How to use checksums |
7fc1afc305a856721db71da91603b447e6f1c1a560dcbd7ae2bbeddf69d294a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for portada-s-index 0.2.3
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.