rule-auto-label 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rule_auto_label-0.1.0/.gitignore +30 -0
- rule_auto_label-0.1.0/LICENSE +21 -0
- rule_auto_label-0.1.0/PKG-INFO +148 -0
- rule_auto_label-0.1.0/README.md +120 -0
- rule_auto_label-0.1.0/pyproject.toml +45 -0
- rule_auto_label-0.1.0/src/auto_label/__init__.py +17 -0
- rule_auto_label-0.1.0/src/auto_label/__main__.py +5 -0
- rule_auto_label-0.1.0/src/auto_label/_data.py +294 -0
- rule_auto_label-0.1.0/src/auto_label/cli.py +374 -0
- rule_auto_label-0.1.0/src/auto_label/labeler.py +462 -0
- rule_auto_label-0.1.0/src/auto_label/models.py +303 -0
- rule_auto_label-0.1.0/src/auto_label/rules.py +235 -0
- rule_auto_label-0.1.0/tests/test_cli.py +140 -0
- rule_auto_label-0.1.0/tests/test_labeler.py +484 -0
- rule_auto_label-0.1.0/tests/test_readme.py +38 -0
- rule_auto_label-0.1.0/tests/test_regressions.py +382 -0
- rule_auto_label-0.1.0/tests/test_regressions_round2.py +484 -0
- rule_auto_label-0.1.0/tests/test_rules.py +154 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Virtual environments and scratch space used while building. Never committed:
|
|
2
|
+
# they are large, machine-specific, and rebuilt from pyproject.toml anyway.
|
|
3
|
+
_venvs/
|
|
4
|
+
_proof/
|
|
5
|
+
.venv*/
|
|
6
|
+
|
|
7
|
+
# Build output. Wheels are built by the release workflow from this source, so a
|
|
8
|
+
# wheel in git could silently differ from the code beside it.
|
|
9
|
+
dist/
|
|
10
|
+
build/
|
|
11
|
+
*.egg-info/
|
|
12
|
+
src/*.egg-info/
|
|
13
|
+
|
|
14
|
+
# Python noise
|
|
15
|
+
__pycache__/
|
|
16
|
+
*.py[cod]
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.mypy_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
|
|
21
|
+
# Local verification state, not source
|
|
22
|
+
verify_results.json
|
|
23
|
+
publish-log.txt
|
|
24
|
+
published.json
|
|
25
|
+
|
|
26
|
+
# Credentials. None of these belong here, and this line is the backstop.
|
|
27
|
+
.pypirc
|
|
28
|
+
.env
|
|
29
|
+
*.pem
|
|
30
|
+
*.key
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pranay Mahendrakar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: rule-auto-label
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Generate labels for text or tabular data from rules, then extend them with a lightweight ML model and an optional LLM hook
|
|
5
|
+
Project-URL: Homepage, https://pypi.org/project/rule-auto-label/
|
|
6
|
+
Project-URL: Author, https://pypi.org/user/pranaymahendrakar/
|
|
7
|
+
Author: Pranay Mahendrakar
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: labeling,labelling,llm,pandas,rules,scikit-learn,text-classification,weak-supervision
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Requires-Dist: numpy>=1.23
|
|
20
|
+
Requires-Dist: pandas>=1.5
|
|
21
|
+
Requires-Dist: scikit-learn>=1.1
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
24
|
+
Requires-Dist: readme-renderer[md]>=40; extra == 'dev'
|
|
25
|
+
Provides-Extra: parquet
|
|
26
|
+
Requires-Dist: pyarrow>=12; extra == 'parquet'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# rule-auto-label
|
|
30
|
+
|
|
31
|
+
> Installs as `rule-auto-label`; imports as `auto_label`. PyPI blocks the plain
|
|
32
|
+
> name `auto-label` as too close to the existing `autolabel` and `auto-labeler`.
|
|
33
|
+
|
|
34
|
+
Turn a few keyword, regex or query rules into labels for a whole text list or DataFrame: rules label what they can, a small model trained on those labels covers the rest, and an optional LLM callable takes the items nobody was sure about.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install rule-auto-label
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quickstart
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import auto_label
|
|
46
|
+
|
|
47
|
+
texts = ["Free prize, click now to claim it", "Team meeting at 10 in room B", "Win a free voucher today",
|
|
48
|
+
"Agenda for the meeting is attached", "Claim your prize before midnight", "Meeting notes from the team",
|
|
49
|
+
"Click now and claim your voucher", "Team notes from room B attached"]
|
|
50
|
+
result = auto_label.label(texts, {"spam": ["free", "prize", "win"], "work": ["meeting", "agenda"]})
|
|
51
|
+
print(result.summary())
|
|
52
|
+
print(result.to_frame())
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The last two items match no rule; the model trained on the first six labels them `spam` and `work`.
|
|
56
|
+
|
|
57
|
+
## What it does
|
|
58
|
+
|
|
59
|
+
- **Rules first.** `keywords` (case-insensitive whole words or phrases), `regex`, a pandas `query`
|
|
60
|
+
string for DataFrames, or any `func(item) -> bool`. A rule fires when every condition it carries holds.
|
|
61
|
+
- **Conflicts resolve by weight.** Each firing rule adds its `weight` to its label; the label with the
|
|
62
|
+
largest total wins, ties go to the rule added first. The rule confidence is the share of the winning
|
|
63
|
+
weight (1.0 when only one label fired). A negative weight vetoes.
|
|
64
|
+
- **A small model extends the rules.** TF-IDF + logistic regression for text; for a table, each column
|
|
65
|
+
is read for what it holds — free-text columns go through TF-IDF, genuine categories are one-hot
|
|
66
|
+
encoded, numbers are scaled — and `.notes` says which column was read as what. Columns that cannot
|
|
67
|
+
teach the model anything are left out and named there too: a near-unique column of whole numbers in
|
|
68
|
+
order is a row id rather than a measurement (an export sorted by type would otherwise let the id
|
|
69
|
+
outvote the text), and a column that is empty for every rule-labeled row has nothing to learn from.
|
|
70
|
+
Either way the model
|
|
71
|
+
trains on the rule-labeled items and is applied to the rest, with the predicted probability as
|
|
72
|
+
confidence. Training is skipped when fewer than 2 labels or fewer than 5 rule-labeled examples
|
|
73
|
+
exist, or when nothing is left to predict.
|
|
74
|
+
- **An optional LLM hook finishes the job.** Items still under `min_confidence` are passed to
|
|
75
|
+
`llm(text, candidate_labels)`; a returned label is used with source `"llm"`. If the callable raises,
|
|
76
|
+
the error is logged and the item stays as it was.
|
|
77
|
+
- **Anything else is left `None`.** `coverage` tells you how much was labeled.
|
|
78
|
+
- Text input: `list[str]`, a pandas `Series`, or a 1-D array. Tabular input: a `DataFrame`, a dict of
|
|
79
|
+
columns, or a path to `.csv` / `.parquet` (`pip install rule-auto-label[parquet]`). On tables, keyword and
|
|
80
|
+
regex rules see the string-like columns of each row joined by spaces; `func` gets the row as a
|
|
81
|
+
Series, whose `.name` is that row's label in your index.
|
|
82
|
+
- Deterministic (`random_state`), no network, no model downloads, logs through `logging`.
|
|
83
|
+
|
|
84
|
+
## API
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
auto_label.label(data, rules, *, labels=None, min_confidence=0.6, random_state=0, model=True, llm=None) -> LabelResult
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`rules` maps a label to a list of keywords, a regex string, a callable, a dict of `add_rule` keyword
|
|
91
|
+
arguments (`{"keywords": [...], "regex": ..., "query": ..., "func": ..., "weight": ...}`), or a list of
|
|
92
|
+
such dicts.
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
labeler = auto_label.Labeler(labels=None, min_confidence=0.6, random_state=0)
|
|
96
|
+
labeler.add_rule(label, *, keywords=None, regex=None, query=None, func=None, weight=1.0) # returns self
|
|
97
|
+
result = labeler.label(data, *, model=True, llm=None)
|
|
98
|
+
labeler.model_ # the fitted scikit-learn pipeline from the last call, or None
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`labels` (optional) is a closed set: rules must use one of them and LLM answers outside it are ignored.
|
|
102
|
+
|
|
103
|
+
`LabelResult`
|
|
104
|
+
|
|
105
|
+
| attribute / method | meaning |
|
|
106
|
+
| --- | --- |
|
|
107
|
+
| `.labels` | `list[str \| None]`, one per item |
|
|
108
|
+
| `.confidence` | `list[float]`; rule share, model probability, 1.0 for the LLM, 0.0 when unlabeled |
|
|
109
|
+
| `.source` | `list["rule" \| "model" \| "llm" \| None]` |
|
|
110
|
+
| `.coverage` | fraction of items that got a label |
|
|
111
|
+
| `.items`, `.index` | the original items (text, or a row dict) and the input index |
|
|
112
|
+
| `.counts`, `.source_counts` | items per label, items per source |
|
|
113
|
+
| `.to_frame()` | DataFrame `item, label, confidence, source` on the input index |
|
|
114
|
+
| `.to_dict()` | JSON-safe dict with totals, counts, notes and every record |
|
|
115
|
+
| `.summary()` | a few lines of human-readable text |
|
|
116
|
+
| `.model_trained`, `.notes` | whether the model ran, and what each stage did |
|
|
117
|
+
|
|
118
|
+
## CLI
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
auto-label tickets.csv --column text --rule billing=invoice,refund --rule bug=crash,error
|
|
122
|
+
auto-label lines.txt --regex urgent="(?i)asap|urgent" --json
|
|
123
|
+
auto-label orders.csv --query big="amount > 100" --rules more_rules.json --output labeled.csv
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`INPUT` is a `.csv` / `.parquet` file (tabular, or one text column with `--column`), a text file with
|
|
127
|
+
one item per line, or `-` for stdin. Repeat `--rule LABEL=kw1,kw2`, `--regex LABEL=PATTERN` and
|
|
128
|
+
`--query LABEL=EXPR` as needed, or put the same rules in a JSON file for `--rules`. By default the
|
|
129
|
+
summary is printed; `--json` prints `to_dict()`; `--output PATH` writes the labeled table as `.csv`
|
|
130
|
+
or `.parquet` (`pip install rule-auto-label[parquet]`), or the full result as `.json`. For tabular input
|
|
131
|
+
the written table is the input columns plus `label, confidence, source`, so it joins back to the
|
|
132
|
+
source file; if the input already uses one of those names, or `index`, the written column gets a free
|
|
133
|
+
one (`label_2`, `index_2`) so every header stays unique. The destination is replaced only once the
|
|
134
|
+
whole file has been written, so a write that fails leaves the file already at that path intact.
|
|
135
|
+
|
|
136
|
+
`--encoding` sets the encoding of the input, whether that is a CSV, a text file or piped stdin.
|
|
137
|
+
Without it everything is read as UTF-8 and undecodable bytes are replaced, with a warning both logged
|
|
138
|
+
and recorded in `.notes`. `--no-model`, `--min-confidence`, `--labels` and `--random-state` mirror the
|
|
139
|
+
Python API.
|
|
140
|
+
|
|
141
|
+
A text file is read one item per line; blank lines are skipped and each record keeps its 0-based
|
|
142
|
+
line number in the file as its index, so results map back to the source. `-` reads stdin the same
|
|
143
|
+
way, and decodes it as UTF-8 whatever the console's locale encoding happens to be, so the same bytes
|
|
144
|
+
give the same labels piped in as they do saved to a file.
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# rule-auto-label
|
|
2
|
+
|
|
3
|
+
> Installs as `rule-auto-label`; imports as `auto_label`. PyPI blocks the plain
|
|
4
|
+
> name `auto-label` as too close to the existing `autolabel` and `auto-labeler`.
|
|
5
|
+
|
|
6
|
+
Turn a few keyword, regex or query rules into labels for a whole text list or DataFrame: rules label what they can, a small model trained on those labels covers the rest, and an optional LLM callable takes the items nobody was sure about.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install rule-auto-label
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quickstart
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
import auto_label
|
|
18
|
+
|
|
19
|
+
texts = ["Free prize, click now to claim it", "Team meeting at 10 in room B", "Win a free voucher today",
|
|
20
|
+
"Agenda for the meeting is attached", "Claim your prize before midnight", "Meeting notes from the team",
|
|
21
|
+
"Click now and claim your voucher", "Team notes from room B attached"]
|
|
22
|
+
result = auto_label.label(texts, {"spam": ["free", "prize", "win"], "work": ["meeting", "agenda"]})
|
|
23
|
+
print(result.summary())
|
|
24
|
+
print(result.to_frame())
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The last two items match no rule; the model trained on the first six labels them `spam` and `work`.
|
|
28
|
+
|
|
29
|
+
## What it does
|
|
30
|
+
|
|
31
|
+
- **Rules first.** `keywords` (case-insensitive whole words or phrases), `regex`, a pandas `query`
|
|
32
|
+
string for DataFrames, or any `func(item) -> bool`. A rule fires when every condition it carries holds.
|
|
33
|
+
- **Conflicts resolve by weight.** Each firing rule adds its `weight` to its label; the label with the
|
|
34
|
+
largest total wins, ties go to the rule added first. The rule confidence is the share of the winning
|
|
35
|
+
weight (1.0 when only one label fired). A negative weight vetoes.
|
|
36
|
+
- **A small model extends the rules.** TF-IDF + logistic regression for text; for a table, each column
|
|
37
|
+
is read for what it holds — free-text columns go through TF-IDF, genuine categories are one-hot
|
|
38
|
+
encoded, numbers are scaled — and `.notes` says which column was read as what. Columns that cannot
|
|
39
|
+
teach the model anything are left out and named there too: a near-unique column of whole numbers in
|
|
40
|
+
order is a row id rather than a measurement (an export sorted by type would otherwise let the id
|
|
41
|
+
outvote the text), and a column that is empty for every rule-labeled row has nothing to learn from.
|
|
42
|
+
Either way the model
|
|
43
|
+
trains on the rule-labeled items and is applied to the rest, with the predicted probability as
|
|
44
|
+
confidence. Training is skipped when fewer than 2 labels or fewer than 5 rule-labeled examples
|
|
45
|
+
exist, or when nothing is left to predict.
|
|
46
|
+
- **An optional LLM hook finishes the job.** Items still under `min_confidence` are passed to
|
|
47
|
+
`llm(text, candidate_labels)`; a returned label is used with source `"llm"`. If the callable raises,
|
|
48
|
+
the error is logged and the item stays as it was.
|
|
49
|
+
- **Anything else is left `None`.** `coverage` tells you how much was labeled.
|
|
50
|
+
- Text input: `list[str]`, a pandas `Series`, or a 1-D array. Tabular input: a `DataFrame`, a dict of
|
|
51
|
+
columns, or a path to `.csv` / `.parquet` (`pip install rule-auto-label[parquet]`). On tables, keyword and
|
|
52
|
+
regex rules see the string-like columns of each row joined by spaces; `func` gets the row as a
|
|
53
|
+
Series, whose `.name` is that row's label in your index.
|
|
54
|
+
- Deterministic (`random_state`), no network, no model downloads, logs through `logging`.
|
|
55
|
+
|
|
56
|
+
## API
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
auto_label.label(data, rules, *, labels=None, min_confidence=0.6, random_state=0, model=True, llm=None) -> LabelResult
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`rules` maps a label to a list of keywords, a regex string, a callable, a dict of `add_rule` keyword
|
|
63
|
+
arguments (`{"keywords": [...], "regex": ..., "query": ..., "func": ..., "weight": ...}`), or a list of
|
|
64
|
+
such dicts.
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
labeler = auto_label.Labeler(labels=None, min_confidence=0.6, random_state=0)
|
|
68
|
+
labeler.add_rule(label, *, keywords=None, regex=None, query=None, func=None, weight=1.0) # returns self
|
|
69
|
+
result = labeler.label(data, *, model=True, llm=None)
|
|
70
|
+
labeler.model_ # the fitted scikit-learn pipeline from the last call, or None
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`labels` (optional) is a closed set: rules must use one of them and LLM answers outside it are ignored.
|
|
74
|
+
|
|
75
|
+
`LabelResult`
|
|
76
|
+
|
|
77
|
+
| attribute / method | meaning |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `.labels` | `list[str \| None]`, one per item |
|
|
80
|
+
| `.confidence` | `list[float]`; rule share, model probability, 1.0 for the LLM, 0.0 when unlabeled |
|
|
81
|
+
| `.source` | `list["rule" \| "model" \| "llm" \| None]` |
|
|
82
|
+
| `.coverage` | fraction of items that got a label |
|
|
83
|
+
| `.items`, `.index` | the original items (text, or a row dict) and the input index |
|
|
84
|
+
| `.counts`, `.source_counts` | items per label, items per source |
|
|
85
|
+
| `.to_frame()` | DataFrame `item, label, confidence, source` on the input index |
|
|
86
|
+
| `.to_dict()` | JSON-safe dict with totals, counts, notes and every record |
|
|
87
|
+
| `.summary()` | a few lines of human-readable text |
|
|
88
|
+
| `.model_trained`, `.notes` | whether the model ran, and what each stage did |
|
|
89
|
+
|
|
90
|
+
## CLI
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
auto-label tickets.csv --column text --rule billing=invoice,refund --rule bug=crash,error
|
|
94
|
+
auto-label lines.txt --regex urgent="(?i)asap|urgent" --json
|
|
95
|
+
auto-label orders.csv --query big="amount > 100" --rules more_rules.json --output labeled.csv
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`INPUT` is a `.csv` / `.parquet` file (tabular, or one text column with `--column`), a text file with
|
|
99
|
+
one item per line, or `-` for stdin. Repeat `--rule LABEL=kw1,kw2`, `--regex LABEL=PATTERN` and
|
|
100
|
+
`--query LABEL=EXPR` as needed, or put the same rules in a JSON file for `--rules`. By default the
|
|
101
|
+
summary is printed; `--json` prints `to_dict()`; `--output PATH` writes the labeled table as `.csv`
|
|
102
|
+
or `.parquet` (`pip install rule-auto-label[parquet]`), or the full result as `.json`. For tabular input
|
|
103
|
+
the written table is the input columns plus `label, confidence, source`, so it joins back to the
|
|
104
|
+
source file; if the input already uses one of those names, or `index`, the written column gets a free
|
|
105
|
+
one (`label_2`, `index_2`) so every header stays unique. The destination is replaced only once the
|
|
106
|
+
whole file has been written, so a write that fails leaves the file already at that path intact.
|
|
107
|
+
|
|
108
|
+
`--encoding` sets the encoding of the input, whether that is a CSV, a text file or piped stdin.
|
|
109
|
+
Without it everything is read as UTF-8 and undecodable bytes are replaced, with a warning both logged
|
|
110
|
+
and recorded in `.notes`. `--no-model`, `--min-confidence`, `--labels` and `--random-state` mirror the
|
|
111
|
+
Python API.
|
|
112
|
+
|
|
113
|
+
A text file is read one item per line; blank lines are skipped and each record keeps its 0-based
|
|
114
|
+
line number in the file as its index, so results map back to the source. `-` reads stdin the same
|
|
115
|
+
way, and decodes it as UTF-8 whatever the console's locale encoding happens to be, so the same bytes
|
|
116
|
+
give the same labels piped in as they do saved to a file.
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "rule-auto-label"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Generate labels for text or tabular data from rules, then extend them with a lightweight ML model and an optional LLM hook"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Pranay Mahendrakar" }]
|
|
14
|
+
keywords = ["labeling", "labelling", "weak-supervision", "text-classification", "rules", "pandas", "scikit-learn", "llm"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"pandas>=1.5",
|
|
26
|
+
"numpy>=1.23",
|
|
27
|
+
"scikit-learn>=1.1",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
# heavy or niche deps go here, never in `dependencies`
|
|
32
|
+
parquet = ["pyarrow>=12"]
|
|
33
|
+
# readme_renderer[md] is what PyPI renders the long description with: the test suite
|
|
34
|
+
# uses it to check the README tables survive the trip.
|
|
35
|
+
dev = ["pytest>=7", "readme_renderer[md]>=40"]
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
rule-auto-label = "auto_label.cli:main"
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://pypi.org/project/rule-auto-label/"
|
|
42
|
+
Author = "https://pypi.org/user/pranaymahendrakar/"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.wheel]
|
|
45
|
+
packages = ["src/auto_label"]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""auto-label: label text or tabular data from rules, a small model, and an optional LLM hook.
|
|
2
|
+
|
|
3
|
+
Quick use::
|
|
4
|
+
|
|
5
|
+
import auto_label
|
|
6
|
+
result = auto_label.label(texts, {"spam": ["free", "prize"], "work": ["meeting"]})
|
|
7
|
+
result.to_frame()
|
|
8
|
+
|
|
9
|
+
For control, build a :class:`Labeler`, add rules, then call ``.label(data)``.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from auto_label.labeler import Labeler, LabelResult, label
|
|
13
|
+
from auto_label.rules import Rule
|
|
14
|
+
|
|
15
|
+
__version__ = "0.1.0"
|
|
16
|
+
|
|
17
|
+
__all__ = ["Labeler", "LabelResult", "Rule", "label", "__version__"]
|