Files
2026-07-13 12:49:22 +08:00

226 lines
8.0 KiB
ReStructuredText

.. _issue_manager_creating_your_own:
Creating Your Own Issues Manager
================================
This guide walks through the process of creating your own
:py:class:`IssueManager <cleanlab.datalab.internal.issue_manager.issue_manager.IssueManager>`
to detect a custom-defined type of issue alongside the pre-defined issue types in
:py:class:`Datalab <cleanlab.datalab.datalab.Datalab>`.
.. seealso::
- :py:meth:`register <cleanlab.datalab.internal.issue_manager_factory.register>`:
You can either use this function at runtime to register a new issue manager:
.. code-block:: python
from cleanlab.datalab.internal.issue_manager_factory import register
register(MyIssueManager) # Defaults to task="classification"
# register(MyIssueManagerForRegression, task="regression") # Alternative for regression tasks
or add as a decorator to the class definition (currently only works for classification tasks):
.. code-block:: python
@register
class MyIssueManager(IssueManager):
...
Prerequisites
-------------
As a starting point for this guide, we'll import the necessary things for the next section and create a dummy dataset.
.. note::
.. include:: ../optional_dependencies.rst
.. code-block:: python
import numpy as np
import pandas as pd
from cleanlab import IssueManager
# Create a dummy dataset
N = 20
data = pd.DataFrame(
{
"text": [f"example {i}" for i in range(N)],
"label": np.random.randint(0, 2, N),
},
)
Implementing IssueManagers
--------------------------
.. _basic_issue_manager:
Basic Issue Check
~~~~~~~~~~~~~~~~~
To create a basic issue manager, inherit from the
:py:class:`IssueManager <cleanlab.datalab.internal.issue_manager.issue_manager.IssueManager>` class,
assign a name to the class as the class-variable, `issue_name`, and implement the
:py:meth:`find_issues <cleanlab.datalab.internal.issue_manager.issue_manager.IssueManager.find_issues>` method.
The :py:meth:`find_issues <cleanlab.datalab.internal.issue_manager.issue_manager.IssueManager.find_issues>`
method should mark each example in the dataset as an issue or not with a boolean array.
It should also provide a score for each example in the dataset that quantifies the quality of the example
with regards to the issue.
.. code-block:: python
class Basic(IssueManager):
# Assign a name to the issue
issue_name = "basic"
def find_issues(self, **kwargs) -> None:
# Compute scores for each example
scores = np.random.rand(len(self.datalab.data))
# Construct a dataframe where examples are marked for issues
# and the score for each example is included.
self.issues = pd.DataFrame(
{
f"is_{self.issue_name}_issue" : scores < 0.1,
self.issue_score_key : scores,
},
)
# Score the dataset as a whole based on this issue type
self.summary = self.make_summary(score = scores.mean())
.. _intermediate_issue_manager:
Intermediate Issue Check
~~~~~~~~~~~~~~~~~~~~~~~~
To create an intermediate issue:
- Perform the same steps as in the :ref:`basic issue check <basic_issue_manager>` section.
- Populate the `info` attribute with a dictionary of information about the identified issues.
The information can be included in a report generated by :py:class:`Datalab <cleanlab.datalab.datalab.Datalab>`,
if you add any of the keys to the `verbosity_levels` class-attribute.
Optionally, you can also add a description of the type of issue this issue manager handles to the `description` class-attribute.
.. code-block:: python
class Intermediate(IssueManager):
issue_name = "intermediate"
# Add a dictionary of information to include in the report
verbosity_levels = {
0: [],
1: ["std"],
2: ["raw_scores"],
}
# Add a description of the issue
description = "Intermediate issues are a bit more involved than basic issues."
def find_issues(self, *, intermediate_arg: int, **kwargs) -> None:
N = len(self.datalab.data)
raw_scores = np.random.rand(N)
std = raw_scores.std()
threshold = min(0, raw_scores.mean() - std)
sin_filter = np.sin(intermediate_arg * np.arange(N) / N)
kernel = sin_filter ** 2
scores = kernel * raw_scores
self.issues = pd.DataFrame(
{
f"is_{self.issue_name}_issue" : scores < threshold,
self.issue_score_key : scores,
},
)
self.summary = self.make_summary(score = scores.mean())
# Useful information that will be available in the Datalab instance
self.info = {
"std": std,
"raw_scores": raw_scores,
"kernel": kernel,
}
Advanced Issue Check
~~~~~~~~~~~~~~~~~~~~
There could be different types of issues detected in a dataset. A local issue which affects individual data points in a dataset and can be tracked via `Datalab.issues` dataframe (to see which data points are exhibiting this type of issue). Alternatively, a global issue which affects the overall dataset but is not easily attributable to individual data points (hard to say one data point exhibits the issue but another does not). Even for global issues, we recommend trying to assign a per data point score (and boolean) if possible, see the Non-IID IssueManager as an example of this. Note that a global issue must have num_issues greater than 0 in its `issue_summary`, otherwise it won't show up in `Datalab.report()` by default.
Use with Datalab
----------------
We can create a
:py:class:`Datalab <cleanlab.datalab.datalab.Datalab>`
instance and run issue checks with the custom issue managers we created like so:
.. code-block:: python
from cleanlab.datalab.internal.issue_manager_factory import register
from cleanlab import Datalab
# Register the issue manager
for issue_manager in [Basic, Intermediate]:
register(issue_manager)
# Instantiate a datalab instance
datalab = Datalab(data, label_name="label")
# Run the issue check
issue_types = {"basic": {}, "intermediate": {"intermediate_arg": 2}}
datalab.find_issues(issue_types=issue_types)
# Print report
datalab.report(verbosity=0)
The report will look something like this:
.. code-block:: text
Here is a summary of the different kinds of issues found in the data:
issue_type score num_issues
basic 0.477762 2
intermediate 0.286455 0
(Note: A lower score indicates a more severe issue across all examples in the dataset.)
------------------------------------------- basic issues -------------------------------------------
Number of examples with this issue: 2
Overall dataset quality in terms of this issue: 0.4778
Examples representing most severe instances of this issue:
is_basic_issue basic_score
13 True 0.003042
8 True 0.058117
11 False 0.121908
15 False 0.169312
17 False 0.229044
--------------------------------------- intermediate issues ----------------------------------------
About this issue:
Intermediate issues are a bit more involved than basic issues.
Number of examples with this issue: 0
Overall dataset quality in terms of this issue: 0.2865
Examples representing most severe instances of this issue:
is_intermediate_issue intermediate_score kernel
0 False 0.000000 0.0
1 False 0.007059 0.009967
3 False 0.010995 0.087332
2 False 0.016296 0.03947
11 False 0.019459 0.794251