kami-lib

HTR / OCR models evaluation agnostic Python package, originally based on the Kraken transcription system.

https://github.com/kami-tools-project/kami-lib

Science Score: 36.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    2 of 4 committers (50.0%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (16.0%) to scientific vocabulary
Last synced: 11 months ago · JSON representation

Repository

HTR / OCR models evaluation agnostic Python package, originally based on the Kraken transcription system.

Basic Info
  • Host: GitHub
  • Owner: KaMI-tools-project
  • License: mit
  • Language: Python
  • Default Branch: master
  • Homepage:
  • Size: 68.4 MB
Statistics
  • Stars: 9
  • Watchers: 0
  • Forks: 0
  • Open Issues: 0
  • Releases: 7
Created about 4 years ago · Last pushed over 3 years ago
Metadata Files
Readme License Citation

README.md

KaMI-lib (Kraken Model Inspector)

Python Version

KaMI-lib Tests Version License: MIT

HTR / OCR models evaluation agnostic Python package, originally based on the Kraken transcription system.

:electric_plug: Installation

User installation

Use pip to install package:

bash $ pip install kamilib

If you encounter some problems on Windows OS, you can use the stable version 0.1.2 (and you can open an issue), otherwise use the latest version.

Developer installation

  1. Create a local branch of the kami-lib project

bash $ git clone https://github.com/KaMI-tools-project/KaMi-lib.git

  1. Create a virtual environment

bash $ virtualenv -p python3.7 kami_venv

then

bash $ source kami_venv/bin/activate

  1. Install dependencies with the requirements file

bash $ pip install -r requirements.txt

  1. Run the tests

bash $ python -m unittest tests/*.py -v

:runner: Tutorial

An "end-to-end pipeline" example that uses Kamilib (written in French) is available at: Open In Colab

Tools build with KaMI-lib

A turn-key graphical interface : KaMI-app

:key: Quickstart

KaMI-lib can be used for different use cases with the class Kami().

First, import the KaMI-lib package :

python from kami.Kami import Kami

The following sections describe two use cases :

  • How to compare outputs from any automatic transcription system,
  • How to use KaMI-lib with a transcription prediction produced with a Kraken model.

Summary

  1. Compare a reference and a prediction, independently of the Kraken engine
  2. Evaluate the prediction of a model generated with the Kraken engine
  3. Use text preprocessing to get different scores
  4. Metrics options

5. Others

1. Compare a reference and a prediction, independently of the Kraken engine

KaMI-lib allows you to compare two strings or two text files by accessing them with their path.

```python

Define your string to compare.

reference_string = "Les 13 ans de Maxime ? taient, Dj terriblement, savants ! - La Cure, 1871. En avant, pour la lecture."

prediction_string = "Les 14a de Maxime ! taient, djteriblement, savants - La Cure, 1871. En avant? pour la leTTture."

Or specify the path to your text files.

reference_path = "reference.txt"

prediction_path = "prediction.txt"

Create a Kami() object and simply insert your data (string or raw text files)

k = Kami([referencestring, predictionstring]) `` you can retrieve the results as dict with the.board` attribute:

python print(k.scores.board) which returns a dictionary containing your metrics (see also Focus on metrics section further):

python {'levensthein_distance_char': 14, 'levensthein_distance_words': 8, 'hamming_distance': '', 'wer': 0.4, 'cer': 0.13333333333333333, 'wacc': 0.6, 'wer_hunt': 0.325, 'mer': 0.1320754716981132, 'cil': 0.17745383867832842, 'cip': 0.8225461613216716, 'hits': 92, 'substitutions': 5, 'deletions': 8, 'insertions': 1}

You can also access a specific metric, as follows:

python print(k.scores.wer)

2. Evaluate the prediction of a model generated with the Kraken engine

The Kami() object uses a ground truth (XML ALTO or XML PAGE format only, no text format), a transcription model and an image to evaluate prediction made by the Kraken engine.

Here is a simple example demonstrating how to use this method with a ground truth in ALTO XML:

```python

Define ground truth path (XML ALTO here)

altogt = "./datatest/lectaurepset/imagegtpage1/FRAN018716402L-0alto.xml"

Define transcription model path

model="./datatest/lectaurepset/models/mixtemrs_15.mlmodel"

Define image

image="./datatest/lectaurepset/imagegtpage1/FRAN018716402L-0.png"

Create a Kami() object and simply insert your data

k = Kami(alto_gt, model=model, image=image)
```

To retrieve the results as dict (.board attribute), as use case 1.:

python print(k.scores.board) which returns a dictionary containing your metrics (for more details on metrics see section ...):

python {'levensthein_distance_char': 408, 'levensthein_distance_words': 255, 'hamming_distance': '', 'wer': 0.3128834355828221, 'cer': 0.09150033639829558, 'wacc': 0.6871165644171779, 'wer_hunt': 0.29938650306748466, 'mer': 0.08970976253298153, 'cil': 0.1395071670835435, 'cip': 0.8604928329164565, 'hits': 4140, 'substitutions': 238, 'deletions': 81, 'insertions': 89}

Depending on the size of the ground truth file, the prediction process may take more or less time.

Kraken parameters can be modified: you can set the principal text direction with the text_direction parameter ("horizontal-lr", "horizontal-rl", "vertical-lr ", "vertical-rl". By default Kami uses "horizontal-lr".).

python k = Kami(alto_gt, model=model, image=image, text_direction="horizontal-lr")

3. Use text preprocessing to get different scores

KaMI-lib provides the possibility to apply textual transformations on the ground truth and the prediction before evaluating them. By doing so, scores can change according to the performance of the model used. This functionality allows a better made by the transdription model. For example, if removing all diacritics improves the scores, it probably means that the model is not good enough at transcribing them. By default no preprocessing is applied.

To preprocess the ground truth and the prediction, you can use apply_transforms parameter from Kami() class.

The apply_transforms parameter receives a character code corresponding to the transformations to be performed :

| Character code | Applied transformation |
|--- |--- | | D | remove digits | | U | uppercase | | L | lowercase | | P | remove punctuation (default list : !"#$%&'()*+, -./:;<=>?@[]^_`{|}~) | | X | remove diacritics |

You can combine these options as follows:

python k = Kami( [ground_truth, prediction], apply_transforms="XP" # Combine here : remove diacritics + remove punctuation )

It results in a dictionary of more complex scores (use built-in pprint module to create a human readable dict.), as follows:

```python import pprint

Get all scores

pprint.pprint(k.scores.board) ```

```python {'Lengthprediction': 2507, 'Lengthpredictiontransformed': 2405, 'Lengthreference': 2536, 'Lengthreferencetransformed': 2426, 'Totalcharremovedfromprediction': 102, 'Totalcharremovedfromreference': 110, 'Totaldiacriticsremovedfromprediction': 84, 'Totaldiacriticsremovedfromreference': 98, 'alltransforms': {'cer': 5.81, 'cil': 8.38, 'cip': 91.61, 'deletions': 48, 'hammingdistance': '', 'hits': 2312, 'insertions': 27, 'levenstheindistancechar': 141, 'levenstheindistancewords': 73, 'mer': 5.74, 'substitutions': 66, 'wacc': 82.28, 'wer': 17.71}, 'default': {'cer': 6.62, 'cil': 9.55, 'cip': 90.44, 'deletions': 59, 'hammingdistance': '', 'hits': 2398, 'insertions': 30, 'levenstheindistancechar': 168, 'levenstheindistancewords': 90, 'mer': 6.54, 'substitutions': 79, 'wacc': 79.54, 'wer': 20.45}, 'removediacritics': {'cer': 6.08, 'cil': 8.78, 'cip': 91.21, 'deletions': 49, 'hammingdistance': '', 'hits': 2379, 'insertions': 31, 'levenstheindistancechar': 152, 'levenstheindistancewords': 77, 'mer': 6.0, 'substitutions': 72, 'wacc': 82.05, 'wer': 17.94}, 'removepunctuation': {'cer': 6.37, 'cil': 9.25, 'cip': 90.74, 'deletions': 57, 'hammingdistance': '', 'hits': 2330, 'insertions': 25, 'levenstheindistancechar': 157, 'levenstheindistance_words': 86, 'mer': 6.31, 'substitutions': 75, 'wacc': 79.71, 'wer': 20.28}}

```

  • The 'default' key indicates the scores without any transformations;
  • The 'all_transforms' key indicates the scores with all transformations applied (here remove diacritics + remove punctuation).

If you have used text preprocessing, for example:

  • The 'remove_punctuation' key indicates the scores with removed punctuations only;
  • The 'remove_diacritics' key indicates the scores with removed diacritics only.

4. Metrics options

KaMI provides the possibility to weight differently the operations made between the ground truth and the prediction (as insertions, substitutions or deletions). By default this operations have a weight of 1.0. You can change these weigthts with the parameters in the Kami() class:

  • insertion_cost
  • substitution_cost
  • deletion_cost

Keep in mind that these weights are the basis for Levensthein distance computations and performance metrics like WER and CER, which can greatly influence final scores.

Example:

python k = Kami( [ground_truth, prediction], insertion_cost=1.0, substitution_cost=0.5, deletion_cost=1.0 )

Kami() class also provides score display settings :

  • truncate (bool) : Option to truncate result. Defaults to False.
  • percent (bool) : True if the user want to show result in percent else False. Defaults to False.
  • round_digits (str) : Set the number of digits after floating point in string form. Defaults to to '.01'

Example :

python k = Kami([ground_truth, prediction], apply_transforms="DUP", verbosity=False, truncate=True, percent=True, round_digits='0.01')

5. Others

For debugging you can pass the verbosity (defaults to False) parameter in the Kami() class, this displays execution logs.

:dart: Focus on metrics

Operations between strings

  • Hits: number of identical characters between the reference and the prediction.

  • Substitutions: number of substitutions (a character replaced by another) necessary to make the prediction match the reference.

  • Deletions: number of deletions (a character is removed) necessary to make the prediction match the reference.

  • Insertions: number of insertions (a character is added) necessary to make the prediction match the reference.

for each of these operations, except hits, a cost of 1 is assigned by default.

Distances

  • Levenshtein Distance (Char.): Levenshtein distance (sum of operations between character strings) at character level.

$$total \ substitutions{char} + total\ deletions{char} + total\ insertions_{char}$$

  • Levenshtein Distance (Words): Levenshtein distance (sum of operations between character strings) at word level.

$$total\ substitutions{word} + total\ deletions{word} + total\ insertions_{word}$$

  • Hamming Distance: A score if the strings' lengths match but their content is different; `` if the strings' lengths don't match.

Transcription performance (HTR/OCR)

The performance metrics are calculated with the Levenshtein distances mentioned above.

  • WER: Word Error Rate, proportion of words bearing at least one recognition error.

$$WER = \frac{total\ substitutions{word} + total\ deletions{word} + total\ insertions{word}}{N{word}}$$

where $N_{word}$ is a total of words in reference string.

corresponding to

$$WER = \frac{Levenshtein\ distance{word}}{N{word}}$$

It is generally between $[0, 1.0]$, the closer it is to $0$ the better the recognition. However, a bad recognition can lead to a $WER> 1.0$.

  • CER: Character Error Rate, proportion of characters erroneously transcribed. Generally more accurate than WER.

$$CER = \frac{total\ substitutions{char} + total\ deletions{char} + total\ insertions{char}}{N{char}}$$

where $N_{char}$ is a total of characters in reference string.

corresponding to

$$CER = \frac{Levenshtein\ distance{char}}{N{char}}$$

It is generally between $[0, 1.0]$, the closer it is to $0$ the better the recognition. However, a bad recognition can lead to a $CER> 1.0$.

  • Wacc: Word Accuracy, proportion of words bearing no recognition error.

$$Wacc = 1- WER$$

  • WER Hunt : reproduce the Word Error Rate experiment by Hunt (1990). Same principle as WER computation with a weighting of $0.5$ on insertions and deletions.

$$WER{Hunt} = \frac{S + 0.5I + 0.5D}{N{word}}$$

This metric shows the importance of customizing the weighting of operations made between strings as it depends heavily on the system and type of data used in an HTR/OCR project. In KaMI-lib, it is possible to modify the weigthts assigned to operations.

Experimental Metrics (metrics borrowed from Speech Recognition - ASR)

  • Match Error Rate

  • Character Information Lost

  • Character Information Preserve

:question: Do you have questions, bug report, features request or feedback?

Please use the issue templates:

:beetle: Bug report: here

:fireworks: Features request: here

if aforementioned cases does not apply, feel free to open an issue.

:black_nib: How to cite

@misc{Kami-lib, author = "Lucas Terriel (Inria - ALMAnaCH) and Alix Chagu (Inria - ALMAnaCH)", title = {Kami-lib - Kraken model inspector}, howpublished = {\url{https://github.com/KaMI-tools-project/KaMi-lib.git}}, year = {2021-2022} }

:octopus: License and contact

Distributed under MIT license. The dependencies used in the project are also distributed under compatible license.

Mail authors and contact: Alix Chagu (alix.chague@inria.fr) and Lucas Terriel (lucas.terriel@inria.fr)

Special thanks: Hugo Scheithauer (hugo.scheithauer@inria.fr)

KaMI-lib is developed and maintained by authors (2021-2023, first version named Kraken-Benchmark in 2020) with contributions of ALMAnaCH at Inria Paris.

forthebadge made-with-python

GitHub Events

Total
  • Watch event: 2
Last Year
  • Watch event: 2

Committers

Last synced: over 3 years ago

All Time
  • Total Commits: 210
  • Total Committers: 4
  • Avg Commits per committer: 52.5
  • Development Distribution Score (DDS): 0.214
Top Committers
Name Email Commits
Lucas Terriel l****l@i****r 165
alix.chague@inria.fr a****e@i****r 21
Lucaterre l****l@g****m 20
Lucas Terriel 4****e@u****m 4
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 12 months ago

All Time
  • Total issues: 0
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 0
  • Total pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Dependencies

requirements.txt pypi
  • kraken ==3.0.6
  • protobuf ==3.20.0
  • python-Levenshtein ==0.12.2
  • termcolor ==1.1.0
  • unidecode ==1.3.4
requirements_dev.txt pypi
  • kraken ==3.0.6 development
  • protobuf ==3.20.0 development
  • pylint ==2.14.5 development
  • pytest ==7.1.2 development
  • python-Levenshtein ==0.12.2 development
  • termcolor ==1.1.0 development
  • unidecode ==1.3.4 development
setup.py pypi
  • kraken ==3.0.6
  • protobuf ==3.20.0
  • python-Levenshtein ==0.12.2
  • termcolor ==1.1.0
  • unidecode ==1.3.4
.github/workflows/python-publish.yml actions
  • actions/checkout v2 composite
  • actions/setup-python v2 composite
.github/workflows/tests.yml actions
  • actions/checkout v2 composite
  • actions/setup-python v1 composite