Skip to main content

Biblioteca de algoritmos de similitud para desambiguación de términos históricos

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

portada_s_index-0.1.21.tar.gz (43.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

portada_s_index-0.1.21-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

Details for the file portada_s_index-0.1.21.tar.gz.

File metadata

  • Download URL: portada_s_index-0.1.21.tar.gz
  • Upload date:
  • Size: 43.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for portada_s_index-0.1.21.tar.gz
Algorithm Hash digest
SHA256 d8169dd47d663787c4222828485a84dfaf6c8cb999e657d1d1920899f869d8ee
MD5 26ee340bc09216a73d0c4edc1891de11
BLAKE2b-256 d06ec309d8e9e8b6b685714efedaf5e31912edceedb2d5b19f295d39b9b86c6d

See more details on using hashes here.

File details

Details for the file portada_s_index-0.1.21-py3-none-any.whl.

File metadata

  • Download URL: portada_s_index-0.1.21-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.5 {"installer":{"name":"uv","version":"0.10.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for portada_s_index-0.1.21-py3-none-any.whl
Algorithm Hash digest
SHA256 c61b59ee26d31d844b98589835ea8fcb0f67398f61621f93a04875e84f08a789
MD5 2d78f60b99a638c0a7a132e95f88addc
BLAKE2b-256 ca7b132c9ed43bb45d24298d12575f39fb3e592ece9bc79ca1a14ff7226a64d8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page