Skip to main content

Active Learning and Technology-Assisted Review library for Python

PyPI Python_version LicenseDOI


python-allib is a library that enables efficient data annotation with Active Learning on various types of datasets. Through the libraryinstancelib we support various machine learning algorithms and instance types. Besides canonical Active Learning, this library offers Technology-Assisted Review methods, which aid in making High-Recall Information Retrieval tasks more efficient.

© Michiel Bron, 2024

Quick tour of Technology-Assisted Review simulation

Load dataset

Load the dataset in an instancelib environment.

# Some imports
from pathlib import Path
from allib.benchmarking.datasets import TarDataset, DatasetType

POS = "Relevant"
NEG = "Irrelevant"
# Load a dataset in SYNERGY/ASREVIEW format
dataset_description = TarDataset(
  DatasetType.REVIEW, 
  Path("./allib/tests/testdataset.csv"))

# Get an instancelib Environment object
ds = dataset_description.env

ds
Environment(dataset=InstanceProvider(length=2019), 
   labels=LabelProvider(labelset=frozenset({'Relevant', 'Irrelevant'}), 
   length=0, 
   statistics={'Relevant': 0, 'Irrelevant': 0}), 
   named_providers={}, 
   length=2019, 
   typeinfo=TypeInfo(identifier=int, data=str, vector=NoneType, representation=str)) 

The ds object is currently loaded in TAR simulation mode. This means, that like the at the start of review process, there is no labeled data. This is visible in the statistics in the ds objects. However, as this is simulation mode, there is a ground truth available. This can be accessed as follows:

ds.truth
LabelProvider(labelset=frozenset({'Relevant', 'Irrelevant'}), 
   length=2019, 
   statistics={'Relevant': 101, 'Irrelevant': 1918})

In Active Learning, we are dealing with a partially labeled dataset. There are two InstanceProvider objects inside the ds object that maintain the label status:

print(f"Unlabeled: {ds.unlabeled}, Labeled: {ds.labeled}")
Unlabeled: InstanceProvider(length=2019), Labeled: InstanceProvider(length=0)

Basic operations

The ds object supports all instancelib operations, for example, dividing the dataset in a train and test set.

train, test = ds.train_test_split(ds.dataset, train_size=0.70)
print(f"Train: {train}, Test: {test}")
Train: InstanceProvider(length=1413), Test: InstanceProvider(length=606)

Train a ML model

We can also train Machine Learning methods on the ground truth data in ds.truth.

from sklearn.pipeline import Pipeline 
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer
from instancelib.analysis.base import prediction_viewer
import instancelib as il
pipeline = Pipeline([
     ('vect', CountVectorizer()),
     ('tfidf', TfidfTransformer()),
     ('clf', LogisticRegression()),
     ])

model = il.SkLearnDataClassifier.build(pipeline, ds)
model.fit_provider(train, ds.truth)

With the method prediction_viewer we can view the predictions as a Pandas dataframe.

# Show the three instances with the highest probability to be Relevant
df = prediction_viewer(model, test, ds.truth).sort_values(
    by="p_Relevant", ascending=False
)
df.head(3)
  0%|          | 0/4 [00:00<?, ?it/s]

  0%|          | 0/4 [00:00<?, ?it/s]
data label prediction p_Irrelevant p_Relevant
175 A randomized trial of a computer-based interve... Relevant Irrelevant 0.639552 0.360448
1797 Computerized decision support to reduce potent... Relevant Irrelevant 0.737130 0.262870
956 Improvement of intraoperative antibiotic proph... Relevant Irrelevant 0.762803 0.237197

Although the predicition probabilities are below 0.50, some of the top ranked documents have a ground truth label relevant.

Active Learning

We can integrate the model in an Active Learning method. A simple TAR method is AutoTAR.

from allib.activelearning.autotar import AutoTarLearner

al = AutoTarLearner(ds, model, POS, NEG, k_sample=100, batch_size=20)

To kick-off the process, we need some labeled data. Let’s give it some training data.

pos_instance = al.env.dataset[28]
neg_instance = al.env.dataset[30]
al.env.labels.set_labels(pos_instance, POS)
al.env.labels.set_labels(neg_instance, NEG)
al.set_as_labeled(pos_instance)
al.set_as_labeled(neg_instance)

Next, we can retrieve the instance that should be labeled next with the following command.

next_instance = next(al)
# next_instance is an Instance object.
# Representation contains a human-readable string version of the instance
print(
    f"{next_instance.representation[:60]}...\n"
    f"Ground Truth Labels: {al.env.truth[next_instance]}"
)
  0%|          | 0/11 [00:00<?, ?it/s]

Oral quinolones in hospitalized patients: an evaluation of a...
Ground Truth Labels: frozenset({'Relevant'})

Simulation

Using the ground truth data, we can further simulate the TAR process in an automated fashion:

from allib.stopcriterion.heuristic import AprioriRecallTarget
from allib.analysis.tarplotter import TarExperimentPlotter
from allib.analysis.experiments import ExperimentIterator
from allib.analysis.simulation import TarSimulator

recall95 = AprioriRecallTarget(POS, 0.95)
recall100 = AprioriRecallTarget(POS, 1.0)
criteria = {
    "Perfect95": recall95,
    "Perfect100": recall100,
}

# Then we can specify our experiment
exp = ExperimentIterator(al, POS, NEG, criteria, {})
plotter = TarExperimentPlotter(POS, NEG)
simulator = TarSimulator(exp, plotter)
simulator.simulate()
plotter.show()
  0%|          | 0/2019 [00:00<?, ?it/s]

  0%|          | 0/10 [00:00<?, ?it/s]

  0%|          | 0/10 [00:00<?, ?it/s]

  0%|          | 0/10 [00:00<?, ?it/s]

  0%|          | 0/10 [00:00<?, ?it/s]

  0%|          | 0/10 [00:00<?, ?it/s]

  0%|          | 0/10 [00:00<?, ?it/s]

  0%|          | 0/10 [00:00<?, ?it/s]

  0%|          | 0/9 [00:00<?, ?it/s]

  0%|          | 0/9 [00:00<?, ?it/s]

  0%|          | 0/9 [00:00<?, ?it/s]

  0%|          | 0/9 [00:00<?, ?it/s]

  0%|          | 0/8 [00:00<?, ?it/s]

  0%|          | 0/8 [00:00<?, ?it/s]

  0%|          | 0/7 [00:00<?, ?it/s]

  0%|          | 0/7 [00:00<?, ?it/s]

  0%|          | 0/7 [00:00<?, ?it/s]

  0%|          | 0/6 [00:00<?, ?it/s]

  0%|          | 0/5 [00:00<?, ?it/s]

  0%|          | 0/5 [00:00<?, ?it/s]

  0%|          | 0/4 [00:00<?, ?it/s]

  0%|          | 0/3 [00:00<?, ?it/s]

  0%|          | 0/2 [00:00<?, ?it/s]

  0%|          | 0/1 [00:00<?, ?it/s]

Command Line Interface

Besides importing the library, the code can be used to run some predefined experiments.

For a CSV in SYNERGY format:

python -m allib benchmark -m Review -d  ./path/to/dataset -t ./path/to/results/ -e AUTOTAR -r 42

For a dataset in TREC-style:

python -m allib benchmark -m Trec -d  ./path/to/dataset/ -t ./path/to/results/ -e AUTOTAR -r 42

Experiment options are:

  • AUTOTAR
  • AUTOSTOP
  • CHAO
  • TARGET
  • CMH

The -r option is used to supply a seed value that is given to a random generator.

Installation

See installation.md for an extended installation guide, especially for enabling the CHAO method. Short instructions are below.

Method Instructions
pip Install from PyPI via pip install python-allib.
Local Clone this repository and install via pip install -e . or locally run python setup.py install.

Releases

python-allib is officially released through PyPI.

See CHANGELOG for a full overview of the changes for each version.

Citation

Use this bibtex to cite this package, or go to ZENODO, to cite a specific version.

@software{bron_2024_108698682,
  author       = {Bron, Michiel},
  title        = {Python Package python-allib},
  month        = mar,
  year         = 2024,
  publisher    = {Zenodo},
  version      = {0.5.1},
  doi          = {10.5281/zenodo.10869682},
  url          = {https://doi.org/10.5281/zenodo.10869682}
}

Maintenance

Contributors

Metadata

Release files for python-allib 0.5.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-allib 0.5.3
File Size Uploaded
python_allib-0.5.3.tar.gz 1.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for python-allib 0.5.3
File Interpreter ABI Platform
python_allib-0.5.3-py3-none-any.whl Python 3 none any Details

Total release size: 2.7 MB

Release files / python_allib-0.5.3.tar.gz

Download URL python_allib-0.5.3.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
fd664a423be8f532e9e942741931a98eae3b659658a21140d0cf70d0cada94e4
BLAKE2b-256 checksum
How to use checksums
84fc49e2ea5ed8d31dd117335750aa47578f6a527acd7c02c47ac82720f8567b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.11.9

Release files / python_allib-0.5.3-py3-none-any.whl

Download URL python_allib-0.5.3-py3-none-any.whl
Size 1.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
2902f265d321648bd9a45ebbb22d3b2d79e099f26b2f7b49a6f949da0ca5f453
BLAKE2b-256 checksum
How to use checksums
8dbb41cfc40d691ff653d4ce819579417a24b1b178e8f40f2d482fcf60716c79
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.11.9

Release history Release notifications | RSS feed

This release

0.5.3 This release

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

1 release file

0.1.0.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page