chaine 3.13.1__cp311-cp311-macosx_11_0_arm64.whl

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.

Potentially problematic release.


This version of chaine might be problematic. Click here for more details.

Files changed (68) hide show
  1. chaine/__init__.py +2 -0
  2. chaine/_core/crf.cpp +19854 -0
  3. chaine/_core/crf.cpython-311-darwin.so +0 -0
  4. chaine/_core/crf.pyx +271 -0
  5. chaine/_core/crfsuite/COPYING +27 -0
  6. chaine/_core/crfsuite/README +183 -0
  7. chaine/_core/crfsuite/include/crfsuite.h +1077 -0
  8. chaine/_core/crfsuite/include/crfsuite.hpp +649 -0
  9. chaine/_core/crfsuite/include/crfsuite_api.hpp +406 -0
  10. chaine/_core/crfsuite/include/os.h +65 -0
  11. chaine/_core/crfsuite/lib/cqdb/COPYING +28 -0
  12. chaine/_core/crfsuite/lib/cqdb/include/cqdb.h +518 -0
  13. chaine/_core/crfsuite/lib/cqdb/src/cqdb.c +639 -0
  14. chaine/_core/crfsuite/lib/cqdb/src/lookup3.c +1271 -0
  15. chaine/_core/crfsuite/lib/cqdb/src/main.c +184 -0
  16. chaine/_core/crfsuite/lib/crf/src/crf1d.h +354 -0
  17. chaine/_core/crfsuite/lib/crf/src/crf1d_context.c +788 -0
  18. chaine/_core/crfsuite/lib/crf/src/crf1d_encode.c +1020 -0
  19. chaine/_core/crfsuite/lib/crf/src/crf1d_feature.c +382 -0
  20. chaine/_core/crfsuite/lib/crf/src/crf1d_model.c +1085 -0
  21. chaine/_core/crfsuite/lib/crf/src/crf1d_tag.c +582 -0
  22. chaine/_core/crfsuite/lib/crf/src/crfsuite.c +500 -0
  23. chaine/_core/crfsuite/lib/crf/src/crfsuite_internal.h +233 -0
  24. chaine/_core/crfsuite/lib/crf/src/crfsuite_train.c +302 -0
  25. chaine/_core/crfsuite/lib/crf/src/dataset.c +115 -0
  26. chaine/_core/crfsuite/lib/crf/src/dictionary.c +127 -0
  27. chaine/_core/crfsuite/lib/crf/src/holdout.c +83 -0
  28. chaine/_core/crfsuite/lib/crf/src/json.c +1497 -0
  29. chaine/_core/crfsuite/lib/crf/src/json.h +120 -0
  30. chaine/_core/crfsuite/lib/crf/src/logging.c +85 -0
  31. chaine/_core/crfsuite/lib/crf/src/logging.h +49 -0
  32. chaine/_core/crfsuite/lib/crf/src/params.c +370 -0
  33. chaine/_core/crfsuite/lib/crf/src/params.h +84 -0
  34. chaine/_core/crfsuite/lib/crf/src/quark.c +180 -0
  35. chaine/_core/crfsuite/lib/crf/src/quark.h +46 -0
  36. chaine/_core/crfsuite/lib/crf/src/rumavl.c +1178 -0
  37. chaine/_core/crfsuite/lib/crf/src/rumavl.h +144 -0
  38. chaine/_core/crfsuite/lib/crf/src/train_arow.c +409 -0
  39. chaine/_core/crfsuite/lib/crf/src/train_averaged_perceptron.c +237 -0
  40. chaine/_core/crfsuite/lib/crf/src/train_l2sgd.c +491 -0
  41. chaine/_core/crfsuite/lib/crf/src/train_lbfgs.c +323 -0
  42. chaine/_core/crfsuite/lib/crf/src/train_passive_aggressive.c +442 -0
  43. chaine/_core/crfsuite/lib/crf/src/vecmath.h +360 -0
  44. chaine/_core/crfsuite/swig/crfsuite.cpp +1 -0
  45. chaine/_core/crfsuite_api.pxd +67 -0
  46. chaine/_core/liblbfgs/COPYING +22 -0
  47. chaine/_core/liblbfgs/README +71 -0
  48. chaine/_core/liblbfgs/include/lbfgs.h +745 -0
  49. chaine/_core/liblbfgs/lib/arithmetic_ansi.h +142 -0
  50. chaine/_core/liblbfgs/lib/arithmetic_sse_double.h +303 -0
  51. chaine/_core/liblbfgs/lib/arithmetic_sse_float.h +312 -0
  52. chaine/_core/liblbfgs/lib/lbfgs.c +1531 -0
  53. chaine/_core/tagger_wrapper.hpp +58 -0
  54. chaine/_core/trainer_wrapper.cpp +32 -0
  55. chaine/_core/trainer_wrapper.hpp +26 -0
  56. chaine/crf.py +505 -0
  57. chaine/logging.py +214 -0
  58. chaine/optimization/__init__.py +10 -0
  59. chaine/optimization/metrics.py +129 -0
  60. chaine/optimization/spaces.py +394 -0
  61. chaine/optimization/trial.py +103 -0
  62. chaine/optimization/utils.py +119 -0
  63. chaine/training.py +184 -0
  64. chaine/typing.py +18 -0
  65. chaine/validation.py +43 -0
  66. chaine-3.13.1.dist-info/METADATA +348 -0
  67. chaine-3.13.1.dist-info/RECORD +68 -0
  68. chaine-3.13.1.dist-info/WHEEL +5 -0
chaine/training.py ADDED
@@ -0,0 +1,184 @@
1
+ """
2
+ chaine.training
3
+ ~~~~~~~~~~~~~~~
4
+
5
+ This module implements the high-level API to train a conditional random field.
6
+ """
7
+
8
+
9
+ from chaine.crf import HyperparameterOptimizer, Model, Trainer
10
+ from chaine.logging import Logger, set_verbosity
11
+ from chaine.typing import Filepath, Iterable, Labels, Sequence
12
+
13
+ LOGGER = Logger(__name__)
14
+
15
+
16
+ def train(
17
+ dataset: Iterable[Sequence],
18
+ labels: Iterable[Labels],
19
+ *,
20
+ model_filepath: Filepath = "model.chaine",
21
+ optimize_hyperparameters: bool = False,
22
+ optimization_sample_size: int | None = None,
23
+ verbose: int = 1,
24
+ **hyperparameters,
25
+ ) -> Model:
26
+ """Train a conditional random field.
27
+
28
+ Parameters
29
+ ----------
30
+ dataset : Iterable[Sequence]
31
+ Data set consisting of sequences of feature sets.
32
+ labels : Iterable[Labels]
33
+ Labels corresponding to each instance in the data set.
34
+ model_filepath : Filepath, optional (default=model.chaine)
35
+ Path to model location.
36
+ optimize_hyperparameters : bool
37
+ If True, optimize hyperparameters first.
38
+ optimization_sample_size : int | None
39
+ Number of instances to sample from the data set for hyperparameter optimization.
40
+ verbose : int
41
+ Controls the verbosity: the higher, the more messages.
42
+ algorithm : str
43
+ The following optimization algorithms are available:
44
+ * lbfgs: Limited-memory BFGS with L1/L2 regularization
45
+ * l2sgd: Stochastic gradient descent with L2 regularization
46
+ * ap: Averaged perceptron
47
+ * pa: Passive aggressive
48
+ * arow: Adaptive regularization of weights
49
+
50
+ Limited-memory BFGS Parameters (lbfgs)
51
+ --------------------------------------
52
+ min_freq : float, optional (default=0)
53
+ Threshold value for minimum frequency of a feature occurring in training data.
54
+ all_possible_states : bool, optional (default=False)
55
+ Generate state features that do not even occur in the training data.
56
+ all_possible_transitions : bool, optional (default=False)
57
+ Generate transition features that do not even occur in the training data.
58
+ max_iterations : int, optional (default=None)
59
+ Maximum number of iterations (unlimited by default).
60
+ num_memories : int, optional (default=6)
61
+ Number of limited memories for approximating the inverse hessian matrix.
62
+ c1 : float, optional (default=0)
63
+ Coefficient for L1 regularization.
64
+ c2 : float, optional (default=1.0)
65
+ Coefficient for L2 regularization.
66
+ epsilon : float, optional (default=1e-5)
67
+ Parameter that determines the condition of convergence.
68
+ period : int, optional (default=10)
69
+ Threshold value for iterations to test the stopping criterion.
70
+ delta : float, optional (default=1e-5)
71
+ Top iteration when log likelihood is not greater than this.
72
+ linesearch : str, optional (default="MoreThuente")
73
+ Line search algorithm used in updates:
74
+ * MoreThuente: More and Thuente's method
75
+ * Backtracking: Backtracking method with regular Wolfe condition
76
+ * StrongBacktracking: Backtracking method with strong Wolfe condition
77
+ max_linesearch : int, optional (default=20)
78
+ Maximum number of trials for the line search algorithm.
79
+
80
+ SGD with L2 Parameters (l2sgd)
81
+ ------------------------------
82
+ min_freq : float, optional (default=0)
83
+ Threshold value for minimum frequency of a feature occurring in training data.
84
+ all_possible_states : bool, optional (default=False)
85
+ Generate state features that do not even occur in the training data.
86
+ all_possible_transitions : bool, optional (default=False)
87
+ Generate transition features that do not even occur in the training data.
88
+ max_iterations : int, optional (default=None)
89
+ Maximum number of iterations (1000 by default).
90
+ c2 : float, optional (default=1.0)
91
+ Coefficient for L2 regularization.
92
+ period : int, optional (default=10)
93
+ Threshold value for iterations to test the stopping criterion.
94
+ delta : float, optional (default=1e-5)
95
+ Top iteration when log likelihood is not greater than this.
96
+ calibration_eta : float, optional (default=0.1)
97
+ Initial value of learning rate (eta) used for calibration.
98
+ calibration_rate : float, optional (default=2.0)
99
+ Rate of increase/decrease of learning rate for calibration.
100
+ calibration_samples : int, optional (default=1000)
101
+ Number of instances used for calibration.
102
+ calibration_candidates : int, optional (default=10)
103
+ Number of candidates of learning rate.
104
+ calibration_max_trials : int, optional (default=20)
105
+ Maximum number of trials of learning rates for calibration.
106
+
107
+ Averaged Perceptron Parameters (ap)
108
+ -----------------------------------
109
+ min_freq : float, optional (default=0)
110
+ Threshold value for minimum frequency of a feature occurring in training data.
111
+ all_possible_states : bool, optional (default=False)
112
+ Generate state features that do not even occur in the training data.
113
+ all_possible_transitions : bool, optional (default=False)
114
+ Generate transition features that do not even occur in the training data.
115
+ max_iterations : int, optional (default=None)
116
+ Maximum number of iterations (100 by default).
117
+ epsilon : float, optional (default=1e-5)
118
+ Parameter that determines the condition of convergence.
119
+
120
+ Passive Aggressive Parameters (pa)
121
+ ----------------------------------
122
+ min_freq : float, optional (default=0)
123
+ Threshold value for minimum frequency of a feature occurring in training data.
124
+ all_possible_states : bool, optional (default=False)
125
+ Generate state features that do not even occur in the training data.
126
+ all_possible_transitions : bool, optional (default=False)
127
+ Generate transition features that do not even occur in the training data.
128
+ max_iterations : int, optional (default=None)
129
+ Maximum number of iterations (100 by default).
130
+ epsilon : float, optional (default=1e-5)
131
+ Parameter that determines the condition of convergence.
132
+ pa_type : int, optional (default=1)
133
+ Strategy for updating feature weights:
134
+ * 0: PA without slack variables
135
+ * 1: PA type I
136
+ * 2: PA type II
137
+ c : float, optional (default=1)
138
+ Aggressiveness parameter (used only for PA-I and PA-II).
139
+ error_sensitive : bool, optional (default=True)
140
+ Include square root of predicted incorrect labels into optimization routine.
141
+ averaging : bool, optional (default=True)
142
+ Compute average of feature weights at all updates.
143
+
144
+ Adaptive Regularization of Weights Parameters (arow)
145
+ ----------------------------------------------------
146
+ min_freq : float, optional (default=0)
147
+ Threshold value for minimum frequency of a feature occurring in training data.
148
+ all_possible_states : bool, optional (default=False)
149
+ Generate state features that do not even occur in the training data.
150
+ all_possible_transitions : bool, optional (default=False)
151
+ Generate transition features that do not even occur in the training data.
152
+ max_iterations : int, optional (default=None)
153
+ Maximum number of iterations (100 by default).
154
+ epsilon : float, optional (default=1e-5)
155
+ Parameter that determines the condition of convergence.
156
+ variance : float, optional (default=1)
157
+ Initial variance of every feature weight.
158
+ gamma : float, optional (default=1)
159
+ Trade-off between loss function and changes of feature weights.
160
+
161
+ Returns
162
+ -------
163
+ Model
164
+ A conditional random field trained on the dataset.
165
+ """
166
+ set_verbosity(verbose)
167
+
168
+ if optimize_hyperparameters:
169
+ if hyperparameters:
170
+ LOGGER.warning(f"Specified hyperparameters will be overwritten: {hyperparameters}")
171
+
172
+ # optionally tune hyperparameters first
173
+ optimizer = HyperparameterOptimizer()
174
+ results = optimizer.optimize_hyperparameters(dataset, labels, optimization_sample_size)
175
+
176
+ # use hyperparameters of the best run
177
+ hyperparameters = results[0]["hyperparameters"]
178
+
179
+ # initialize trainer and start training
180
+ trainer = Trainer(**hyperparameters)
181
+ trainer.train(dataset, labels, model_filepath=str(model_filepath))
182
+
183
+ # load and return the trained model
184
+ return Model(model_filepath)
chaine/typing.py ADDED
@@ -0,0 +1,18 @@
1
+ """
2
+ chaine.typing
3
+ ~~~~~~~~~~~~~
4
+
5
+ A collection of type hints.
6
+ """
7
+
8
+ from os import PathLike
9
+ from pathlib import Path
10
+ from typing import Any, Iterable, Iterator
11
+
12
+ Sequence = Iterable[dict[str, str | int | float | bool]]
13
+ Labels = Iterable[str]
14
+ Filepath = Path | PathLike | str
15
+ Sentence = list[str]
16
+ Tags = list[str]
17
+ Features = dict[str, float | int | str | bool]
18
+ Dataset = dict[str, dict[str, Any]]
chaine/validation.py ADDED
@@ -0,0 +1,43 @@
1
+ """
2
+ chaine.validation
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ This module implements functions to validate input sequences (either for training or inference).
6
+ """
7
+
8
+ from chaine.typing import Sequence
9
+
10
+ # supported feature value data types
11
+ TYPES = (str, int, float, bool)
12
+
13
+
14
+ def is_valid_sequence(sequence: Sequence) -> bool:
15
+ """Check if the given sequence has valid input format.
16
+
17
+ Parameters
18
+ ----------
19
+ sequence : Sequence
20
+ Sequence to validate.
21
+
22
+ Returns
23
+ -------
24
+ bool
25
+ True if sequence is valid, False otherwise.
26
+ """
27
+ return isinstance(sequence, list) and all(is_valid_token(token) for token in sequence)
28
+
29
+
30
+ def is_valid_token(token: dict) -> bool:
31
+ """Check if the given token has valid input format.
32
+
33
+ Parameters
34
+ ----------
35
+ token : dict
36
+ Token to validate.
37
+
38
+ Returns
39
+ -------
40
+ bool
41
+ True if sequence is valid, False otherwise.
42
+ """
43
+ return isinstance(token, dict) and all(isinstance(value, TYPES) for value in token.values())
@@ -0,0 +1,348 @@
1
+ Metadata-Version: 2.1
2
+ Name: chaine
3
+ Version: 3.13.1
4
+ Summary: Linear-chain conditional random fields for natural language processing
5
+ Author: Severin Simmler
6
+ Author-email: s.simmler@snapaddy.com
7
+ Requires-Python: >=3.10,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Chaine
16
+
17
+ [![downloads](https://static.pepy.tech/personalized-badge/chaine?period=total&units=international_system&left_color=black&right_color=black&left_text=downloads)](https://pepy.tech/project/chaine)
18
+ [![downloads/month](https://static.pepy.tech/personalized-badge/chaine?period=month&units=abbreviation&left_color=black&right_color=black&left_text=downloads/month)](https://pepy.tech/project/chaine)
19
+ [![downloads/week](https://static.pepy.tech/personalized-badge/chaine?period=week&units=abbreviation&left_color=black&right_color=black&left_text=downloads/week)](https://pepy.tech/project/chaine)
20
+
21
+ Chaine is a modern, fast and lightweight Python library implementing **linear-chain conditional random fields**. Use it for sequence labeling tasks like [named entity recognition](https://en.wikipedia.org/wiki/Named-entity_recognition) or [part-of-speech tagging](https://en.wikipedia.org/wiki/Part-of-speech_tagging).
22
+
23
+ The main goals of this project are:
24
+
25
+ - **Usability**: Designed with special focus on usability and a beautiful high-level API.
26
+ - **Efficiency**: Performance critical parts are written in C and thus [blazingly fast](http://www.chokkan.org/software/crfsuite/benchmark.html). Loading a model from disk and retrieving feature weights for inference is optimized for both [speed and memory](http://www.chokkan.org/software/cqdb/).
27
+ - **Persistency**: No `pickle` or `joblib` is used for serialization. A trained model will be compatible with all versions for eternity, because the underlying C library will not change. I promise.
28
+ - **Compatibility**: There are wheels for Linux, macOS and Windows. No compiler needed.
29
+ - **Minimalism**: No code bloat, no external dependencies.
30
+
31
+ Install the latest stable version from [PyPI](https://pypi.org/project/chaine):
32
+
33
+ ```
34
+ pip install chaine
35
+ ```
36
+
37
+ ### Table of contents
38
+
39
+ - [Algorithms](#algorithms)
40
+ - [Usage](#usage)
41
+ - [Features](#features)
42
+ - [Training](#training)
43
+ - [Hyperparameters](#hyperparameters)
44
+ - [Inference](#inference)
45
+ - [Weights](#weights)
46
+ - [Credits](#credits)
47
+
48
+ ## Algorithms
49
+
50
+ You can train models using the following methods:
51
+
52
+ - Limited-Memory BFGS ([Nocedal 1980](https://www.jstor.org/stable/2006193))
53
+ - Orthant-Wise Limited-Memory Quasi-Newton ([Andrew et al. 2007](https://www.microsoft.com/en-us/research/publication/scalable-training-of-l1-regularized-log-linear-models/))
54
+ - Stochastic Gradient Descent ([Shalev et al. 2007](https://www.google.com/url?q=https://www.cs.huji.ac.il/~shais/papers/ShalevSiSr07.pdf))
55
+ - Averaged Perceptron ([Collins 2002](https://aclanthology.org/W02-1001.pdf))
56
+ - Passive Aggressive ([Crammer et al. 2006](https://jmlr.csail.mit.edu/papers/v7/crammer06a.html))
57
+ - Adaptive Regularization of Weight Vectors ([Mejer et al. 2010](https://aclanthology.org/D10-1095.pdf))
58
+
59
+ Please refer to the paper by [Lafferty et al.](https://repository.upenn.edu/cgi/viewcontent.cgi?article=1162&context=cis_papers) for a general introduction to **conditional random fields** or the respective chapter in [Speech and Language Processing](https://web.stanford.edu/~jurafsky/slp3/8.pdf).
60
+
61
+ ## Usage
62
+
63
+ Training and using a **conditional random field** for inference is easy as:
64
+
65
+ ```python
66
+ >>> import chaine
67
+ >>> tokens = [[{"index": 0, "text": "John"}, {"index": 1, "text": "Lennon"}]]
68
+ >>> labels = [["B-PER", "I-PER"]]
69
+ >>> model = chaine.train(tokens, labels)
70
+ >>> model.predict(tokens)
71
+ [['B-PER', 'I-PER']]
72
+ ```
73
+
74
+ > You can control verbosity with the argument `verbose`, where `0` will set the log level to `ERROR`, `1` to `INFO` (which is the default) and `2` to `DEBUG`.
75
+
76
+ ### Features
77
+
78
+ One token in a sequence is represented as a dictionary with describing feature names as keys and respective values of type string, integer, float or boolean:
79
+
80
+ ```python
81
+ {
82
+ "text": "John",
83
+ "num_characters": 4,
84
+ "relative_index": 0.0,
85
+ "is_number": False,
86
+ }
87
+ ```
88
+
89
+ One sequence is represented as a list of feature dictionaries:
90
+
91
+ ```python
92
+ [
93
+ {"text": "John", "num_characters": 4},
94
+ {"text": "Lennon", "num_characters": 6}
95
+ ]
96
+ ```
97
+
98
+ One data set is represented as an iterable of a list of feature dictionaries:
99
+
100
+ ```python
101
+ [
102
+ [
103
+ {"text": "John", "num_characters": 4},
104
+ {"text": "Lennon", "num_characters": 6}
105
+ ],
106
+ [
107
+ {"text": "Paul", "num_characters": 4},
108
+ {"text": "McCartney", "num_characters": 9}
109
+ ],
110
+ ...
111
+ ]
112
+ ```
113
+
114
+ This is the expected input format for training. For inference, you can also process a single sequence rather than a batch of multiple sequences.
115
+
116
+ #### Generators
117
+
118
+ Depending on the size of your data set, it probably makes sense to use generators. Something like this would be totally fine for both training and inference:
119
+
120
+ ```python
121
+ ([extract_features(token) for token in tokens] for tokens in dataset)
122
+ ```
123
+
124
+ Assuming `dataset` is a generator as well, only one sequence is loaded into memory at a time.
125
+
126
+ ### Training
127
+
128
+ You can either use the high-level function to train a model (which also loads and returns it):
129
+
130
+ ```python
131
+ >>> import chaine
132
+ >>> chaine.train(tokens, labels)
133
+ ```
134
+
135
+ or the lower-level `Trainer` class:
136
+
137
+ ```python
138
+ >>> from chaine import Trainer
139
+ >>> trainer = Trainer()
140
+ ```
141
+
142
+ A `Trainer` object has a method `train()` to learn states and transitions from the given data set. You have to provide a filepath to serialize the model to:
143
+
144
+ ```python
145
+ >>> trainer.train(tokens, labels, model_filepath="model.chaine")
146
+ ```
147
+
148
+ ### Hyperparameters
149
+
150
+ Before training a model, you might want to find out the ideal hyperparameters first. You can just set the respective argument to `True`:
151
+
152
+ ```python
153
+ >>> import chaine
154
+ >>> model = chaine.train(tokens, labels, optimize_hyperparameters=True)
155
+ ```
156
+
157
+ > This might be very memory and time consuming, because 5-fold cross validation for each of the 10 trials for each of the algorithms is performed.
158
+
159
+ or use the `HyperparameterOptimizer` class and have more control over the optimization process:
160
+
161
+ ```python
162
+ >>> from chaine import HyperparameterOptimizer
163
+ >>> from chaine.optimization import L2SGDSearchSpace
164
+ >>> optimizer = HyperparameterOptimizer(trials=50, folds=3, spaces=[L2SGDSearchSpace()])
165
+ >>> optimizer.optimize_hyperparameters(tokens, labels, sample_size=1000)
166
+ ```
167
+
168
+ This will make 50 trials with 3-fold cross validation for the Stochastic Gradient Descent algorithm and return a sorted list of hyperparameters with evaluation stats. The given data set is downsampled to 1000 instances.
169
+
170
+ <details>
171
+ <summary>Example of a hyperparameter optimization report</summary>
172
+
173
+ ```json
174
+ [
175
+ {
176
+ "hyperparameters": {
177
+ "algorithm": "lbfgs",
178
+ "min_freq": 0,
179
+ "all_possible_states": true,
180
+ "all_possible_transitions": true,
181
+ "num_memories": 8,
182
+ "c1": 0.9,
183
+ "c2": 0.31,
184
+ "epsilon": 0.00011,
185
+ "period": 17,
186
+ "delta": 0.00051,
187
+ "linesearch": "Backtracking",
188
+ "max_linesearch": 31
189
+ },
190
+ "stats": {
191
+ "mean_precision": 0.4490952380952381,
192
+ "stdev_precision": 0.16497993418839532,
193
+ "mean_recall": 0.4554858934169279,
194
+ "stdev_recall": 0.20082402876210334,
195
+ "mean_f1": 0.45041435392087253,
196
+ "stdev_f1": 0.17914435056760908,
197
+ "mean_time": 0.3920876979827881,
198
+ "stdev_time": 0.0390961164333519
199
+ }
200
+ },
201
+ {
202
+ "hyperparameters": {
203
+ "algorithm": "lbfgs",
204
+ "min_freq": 5,
205
+ "all_possible_states": true,
206
+ "all_possible_transitions": false,
207
+ "num_memories": 9,
208
+ "c1": 1.74,
209
+ "c2": 0.09,
210
+ "epsilon": 0.0008600000000000001,
211
+ "period": 1,
212
+ "delta": 0.00045000000000000004,
213
+ "linesearch": "StrongBacktracking",
214
+ "max_linesearch": 34
215
+ },
216
+ "stats": {
217
+ "mean_precision": 0.4344436335328176,
218
+ "stdev_precision": 0.15542689556199216,
219
+ "mean_recall": 0.4385174258109041,
220
+ "stdev_recall": 0.19873733310765845,
221
+ "mean_f1": 0.43386496201052716,
222
+ "stdev_f1": 0.17225578421967264,
223
+ "mean_time": 0.12209572792053222,
224
+ "stdev_time": 0.0236177196325414
225
+ }
226
+ },
227
+ {
228
+ "hyperparameters": {
229
+ "algorithm": "lbfgs",
230
+ "min_freq": 2,
231
+ "all_possible_states": true,
232
+ "all_possible_transitions": true,
233
+ "num_memories": 1,
234
+ "c1": 0.91,
235
+ "c2": 0.4,
236
+ "epsilon": 0.0008400000000000001,
237
+ "period": 13,
238
+ "delta": 0.00018,
239
+ "linesearch": "MoreThuente",
240
+ "max_linesearch": 43
241
+ },
242
+ "stats": {
243
+ "mean_precision": 0.41963433149859447,
244
+ "stdev_precision": 0.16363544501259455,
245
+ "mean_recall": 0.4331173486012196,
246
+ "stdev_recall": 0.21344965207006913,
247
+ "mean_f1": 0.422038027332145,
248
+ "stdev_f1": 0.18245844823319127,
249
+ "mean_time": 0.2586916446685791,
250
+ "stdev_time": 0.04341208573100539
251
+ }
252
+ },
253
+ {
254
+ "hyperparameters": {
255
+ "algorithm": "l2sgd",
256
+ "min_freq": 5,
257
+ "all_possible_states": true,
258
+ "all_possible_transitions": true,
259
+ "c2": 1.68,
260
+ "period": 2,
261
+ "delta": 0.00047000000000000004,
262
+ "calibration_eta": 0.0006900000000000001,
263
+ "calibration_rate": 2.9000000000000004,
264
+ "calibration_samples": 1400,
265
+ "calibration_candidates": 25,
266
+ "calibration_max_trials": 23
267
+ },
268
+ "stats": {
269
+ "mean_precision": 0.2571428571428571,
270
+ "stdev_precision": 0.43330716823151716,
271
+ "mean_recall": 0.01,
272
+ "stdev_recall": 0.022360679774997897,
273
+ "mean_f1": 0.01702127659574468,
274
+ "stdev_f1": 0.038060731531911314,
275
+ "mean_time": 0.15442829132080077,
276
+ "stdev_time": 0.051750737506044905
277
+ }
278
+ }
279
+ ]
280
+ ```
281
+ </details>
282
+
283
+ ### Inference
284
+
285
+ The high-level function `chaine.train()` returns a `Model` object. You can load an already trained model from disk by initializing a `Model` object with the model's filepath:
286
+
287
+ ```python
288
+ >>> from chaine import Model
289
+ >>> model = Model("model.chaine")
290
+ ```
291
+
292
+ You can predict labels for a batch of sequences:
293
+
294
+ ```python
295
+ >>> tokens = [
296
+ ... [{"index": 0, "text": "John"}, {"index": 1, "text": "Lennon"}],
297
+ ... [{"index": 0, "text": "Paul"}, {"index": 1, "text": "McCartney"}],
298
+ ... [{"index": 0, "text": "George"}, {"index": 1, "text": "Harrison"}],
299
+ ... [{"index": 0, "text": "Ringo"}, {"index": 1, "text": "Starr"}]
300
+ ... ]
301
+ >>> model.predict(tokens)
302
+ [['B-PER', 'I-PER'], ['B-PER', 'I-PER'], ['B-PER', 'I-PER'], ['B-PER', 'I-PER']]
303
+ ```
304
+
305
+ or only for a single sequence:
306
+
307
+ ```python
308
+ >>> model.predict_single(tokens[0])
309
+ ['B-PER', 'I-PER']
310
+ ```
311
+
312
+ If you are interested in the model's probability distribution for a given sequence, you can:
313
+
314
+ ```python
315
+ >>> model.predict_proba_single(tokens[0])
316
+ [[{'B-PER': 0.99, 'I-PER': 0.01}, {'B-PER': 0.01, 'I-PER': 0.99}]]
317
+ ```
318
+
319
+ > Use the `model.predict_proba()` method for a batch of sequences.
320
+
321
+ ### Weights
322
+
323
+ After loading a trained model, you can inspect the learned transition and state weights:
324
+
325
+ ```python
326
+ >>> model = Model("model.chaine")
327
+ >>> model.transitions
328
+ [{'from': 'B-PER', 'to': 'I-PER', 'weight': 1.430506540616852e-06}]
329
+ >>> model.states
330
+ [{'feature': 'text:John', 'label': 'B-PER', 'weight': 9.536710877105517e-07}, ...]
331
+ ```
332
+
333
+ You can also dump both transition and state weights as JSON:
334
+
335
+ ```python
336
+ >>> model.dump_states("states.json")
337
+ >>> model.dump_transitions("transitions.json")
338
+ ```
339
+
340
+ ## Credits
341
+
342
+ This project makes use of and is partially based on:
343
+
344
+ - [CRFsuite](https://github.com/chokkan/crfsuite)
345
+ - [libLBFGS](https://github.com/chokkan/liblbfgs)
346
+ - [python-crfsuite](https://github.com/scrapinghub/python-crfsuite)
347
+ - [sklearn-crfsuite](https://github.com/TeamHG-Memex/sklearn-crfsuite)
348
+
@@ -0,0 +1,68 @@
1
+ chaine/logging.py,sha256=ecMug4UjT-tRwjNqFNlrAaElJFUyzncbPzEz1-EKDg8,5256
2
+ chaine/crf.py,sha256=N6s6BhuQtzslHvbItP58kT-TygSkue5nmyGcgO4SEyA,18003
3
+ chaine/__init__.py,sha256=TzYwbQ05GnL1zGl5Y981lpn1SJZNs-9g-H1rDSsQQQI,97
4
+ chaine/typing.py,sha256=F5YEabzjTGcWdT1oVvc7kOoQgrF9YM28IWKt7cSv7TA,393
5
+ chaine/training.py,sha256=l9gRS29jAAbPLvPbxrxMuJ89sPYg5B5cJJc7vl71bgU,8401
6
+ chaine/validation.py,sha256=_kL7gELOpGAtSZk_MCAB0OP2iaMNNXOYVfnAn71u5dM,995
7
+ chaine/_core/crf.cpython-311-darwin.so,sha256=dQJtjAWkM7vcUlqoASmO6H3M1VSuG0CQu8Em-A5Qk5Q,396344
8
+ chaine/_core/crf.cpp,sha256=cJudgXE_R6A59tibSVNBVhV5yKAdpqKcn5C_a6HrG4I,817453
9
+ chaine/_core/trainer_wrapper.hpp,sha256=k0qxNF1Zc1jUWSl8jGsk6lEV87HvrcX368Ld0X2QpCU,573
10
+ chaine/_core/tagger_wrapper.hpp,sha256=Kp3-WuWptf_x1asr33PHFiuCFDKAjBE7Ux_Y-jms5-A,1312
11
+ chaine/_core/crf.pyx,sha256=4fPdpCqtKxE7_yQ6d__FDmRnHpRMebYTVL8xfgH-fi4,9093
12
+ chaine/_core/crfsuite_api.pxd,sha256=mXqxaXbqsu5EwnO10aCwNdaDHldunz_ctPjss7zJJKc,2003
13
+ chaine/_core/trainer_wrapper.cpp,sha256=cWch9SUpmvU6ob70witv9JGZBo3Ffk8FyYZmOSYfoyw,745
14
+ chaine/_core/liblbfgs/README,sha256=DFtDex47VeGMerhoN3r6NRpIyrA6X-dAlg3iod49wWM,2645
15
+ chaine/_core/liblbfgs/COPYING,sha256=BttaPmruwflyFQDw2kp1zLW0I-6sjAbcXHKLoIP5gxE,1113
16
+ chaine/_core/liblbfgs/include/lbfgs.h,sha256=Epq0BMDwOfEkCUaJDAJA9UoumXzh8pchDt_qg5D-caA,32846
17
+ chaine/_core/liblbfgs/lib/arithmetic_sse_float.h,sha256=y4GHzZ_gKv9lQr7z-PWvNt1Ef8qM_Wb0wRoyInvrN6g,13356
18
+ chaine/_core/liblbfgs/lib/arithmetic_ansi.h,sha256=z-kxgT3MLFPutBirvGzmtY27YRKwBuDgOx15n-7wxOc,3427
19
+ chaine/_core/liblbfgs/lib/arithmetic_sse_double.h,sha256=kbRsNxVGimCU0GBu5ntBaqLpcJvHMv519ayirq4Oq6g,13805
20
+ chaine/_core/liblbfgs/lib/lbfgs.c,sha256=NXJaMFR3msc-fvZGshul3urGNhCcMrmVtupF5fZFo34,43705
21
+ chaine/_core/crfsuite/README,sha256=dfFr9_hpGb_-5bRx-OGb8A4HOv1TkvkbbiQC2zJ5LiM,7973
22
+ chaine/_core/crfsuite/COPYING,sha256=yJTvUnFVB_ihql1gLeHlmkfAGB7f6_Cj8BYPa5A66SM,1535
23
+ chaine/_core/crfsuite/swig/crfsuite.cpp,sha256=mlIpS4rUgAqoC92rmnY62H-eOOcvIeyGeelpZlfXfOM,24
24
+ chaine/_core/crfsuite/include/crfsuite_api.hpp,sha256=bT7PenKkHZEO6C4YwH7K-531JoRBc6ZYUb8xna-WZ3w,14098
25
+ chaine/_core/crfsuite/include/os.h,sha256=LwiRwgaake0zBqA-fAp9Ik7t3eblOOyY78spMUmsJ6Q,2238
26
+ chaine/_core/crfsuite/include/crfsuite.h,sha256=vFWIxhig8SblpqI9LtB8UbijMPKcz6fZTpi6N2kCAPU,38631
27
+ chaine/_core/crfsuite/include/crfsuite.hpp,sha256=yHKNeRiewwjM4ssBMqox_3_C3Mgn4Di6rF6zTihA2k0,18593
28
+ chaine/_core/crfsuite/lib/crf/src/crf1d_context.c,sha256=KyKlCgG2XZQ-ve16J78C2qBPKs2KUuhBrGbBWue23f4,22618
29
+ chaine/_core/crfsuite/lib/crf/src/dictionary.c,sha256=GlCNRabrGVZdh-SA6btiblt7ecDefy88QtHbdFBXW1M,3878
30
+ chaine/_core/crfsuite/lib/crf/src/json.c,sha256=x6x-POaCJTHeVHoOGo_-3C_uUHDW2neHVVZnGyGcVMs,29211
31
+ chaine/_core/crfsuite/lib/crf/src/train_arow.c,sha256=p5Qf33ugcmee-z-diCcqSI9bWu4u445RvLxrG9NVejs,10858
32
+ chaine/_core/crfsuite/lib/crf/src/train_averaged_perceptron.c,sha256=sAzgkJuOj9lv_3hSpu_lwIBkGM3dM8XHg04l4z87Xgw,6704
33
+ chaine/_core/crfsuite/lib/crf/src/dataset.c,sha256=Mtq3NmVjtGaCMGW3akiDOEOw8Z-JqYkZqykTRsDUbbA,3254
34
+ chaine/_core/crfsuite/lib/crf/src/crf1d_feature.c,sha256=NzK63VSV9iWLLcIWxYpj2US4kqhBkDm_HpGVeSJef7M,10589
35
+ chaine/_core/crfsuite/lib/crf/src/quark.h,sha256=xvI4sPC6plv4id91ZInIWf3lQXSdBtEIfJmxr_-fiOA,1983
36
+ chaine/_core/crfsuite/lib/crf/src/params.h,sha256=Amz1OcAybVJNCe-A6sqQpOsGk8VebMZhGzJIpUOMv20,3754
37
+ chaine/_core/crfsuite/lib/crf/src/crf1d_tag.c,sha256=KKj_8rS9C8FMKrmi0C5I2q9p8UYvKAG2IMPJl9r3tAU,16748
38
+ chaine/_core/crfsuite/lib/crf/src/vecmath.h,sha256=XaBpZ2sDfjSYS9kS0xSaiTb43Hwi4MN7JANY12Z8imo,9913
39
+ chaine/_core/crfsuite/lib/crf/src/crfsuite_internal.h,sha256=BOORaOdxhK5lQcOwwLXJ0BuwkS3a6XUNT-g0wGRGEsI,7547
40
+ chaine/_core/crfsuite/lib/crf/src/train_l2sgd.c,sha256=RVuMLL-mp8llsZAiKS0yXvOdLkusux4wcGkxQCrl0aw,13947
41
+ chaine/_core/crfsuite/lib/crf/src/holdout.c,sha256=60rLL5VCzH7ULgR_ZhtjmEkj8Zc_YGSayzCRrc5J8hE,2865
42
+ chaine/_core/crfsuite/lib/crf/src/logging.h,sha256=ULplqPJhoMR1TGkKqUBzIBbQplS3YiqRcBYFRwOCCFY,2063
43
+ chaine/_core/crfsuite/lib/crf/src/crfsuite_train.c,sha256=uqlp55WD4ke60j4V52f8nMtHEFzqTvx5Wougffad2kk,8549
44
+ chaine/_core/crfsuite/lib/crf/src/rumavl.h,sha256=70L36qSMLW6VTrYgfGkTqI-aAD8jzMs6qPTd1YlG9Pc,5536
45
+ chaine/_core/crfsuite/lib/crf/src/crf1d_encode.c,sha256=ouVuCPfrY6Q1UzJDRxcxRnIGaw6EEBxGm2i5CfvPpkI,29224
46
+ chaine/_core/crfsuite/lib/crf/src/json.h,sha256=UqWIwZam8GSX58XI5zOzZqHoFI40V79b6CBw416aKFs,3389
47
+ chaine/_core/crfsuite/lib/crf/src/crf1d.h,sha256=WNsBYaw34iNO6ZdRai1gp1WV_YDkU6qV5drLpFbj6kk,10712
48
+ chaine/_core/crfsuite/lib/crf/src/train_passive_aggressive.c,sha256=8e17ZrO3AwiSVuDtKmag_0piGIzNwMRUImv5ogMJUqM,11565
49
+ chaine/_core/crfsuite/lib/crf/src/quark.c,sha256=HIwp_nWyUkEvalvtxDTLTD2ivzyRTEJcs2SQTbr_7J4,4842
50
+ chaine/_core/crfsuite/lib/crf/src/params.c,sha256=eCrpuNmYSKQBE0qZkUaO4e1ZAqBo7hVHP4uUH0c9dlM,10019
51
+ chaine/_core/crfsuite/lib/crf/src/crfsuite.c,sha256=NbIIYrMAmQGoy0-vPmUZRiLJUN0yVRSRqbH2iCbYN6Y,14080
52
+ chaine/_core/crfsuite/lib/crf/src/train_lbfgs.c,sha256=faXl6eX5iVhuXOAvpuwBKxMkRwN_bE-96SQwWJGRtCQ,9447
53
+ chaine/_core/crfsuite/lib/crf/src/crf1d_model.c,sha256=TC-MNEnvphQYSsaRYATun5J9_Fmrn9zolfmn3xYpLHg,26694
54
+ chaine/_core/crfsuite/lib/crf/src/rumavl.c,sha256=oJwD9UETztAWh24F336WQ1RYZu_1rg818MEfpHWk68E,33987
55
+ chaine/_core/crfsuite/lib/crf/src/logging.c,sha256=m4s_RGdtRttzx6UhTVxOtK7Aq3c3XCG0SK4efF6i7J4,2640
56
+ chaine/_core/crfsuite/lib/cqdb/COPYING,sha256=2AbX0dSRC8C9CY6VlwHWItkSHfJnmOdEIZ0HVvoOZ-E,1573
57
+ chaine/_core/crfsuite/lib/cqdb/include/cqdb.h,sha256=qgEklRcZaYbqy52UQ8U3IIjlu8iyhR-PGyDzyyP48Bw,18728
58
+ chaine/_core/crfsuite/lib/cqdb/src/lookup3.c,sha256=vItwg4xz2L-ETuNdjp-ciX2Y4s7BeQq7poltS7iWQkQ,36564
59
+ chaine/_core/crfsuite/lib/cqdb/src/cqdb.c,sha256=3FRltjneWVXB1xcO5SLB0XBD2iH8EjWoWiKCtkt5N1w,17268
60
+ chaine/_core/crfsuite/lib/cqdb/src/main.c,sha256=5XaF59oBpDrdzysph4yQlqD99oRp--ExwWTysKD4STc,4982
61
+ chaine/optimization/metrics.py,sha256=m1csn5S5TrKYpvj6xGMlgIqoWqN9U-YTNwS5oXka4VQ,3716
62
+ chaine/optimization/trial.py,sha256=Hcee5DfOp91oQt7VKHPw80XQpuIWfykmFCBXr1-UONY,3566
63
+ chaine/optimization/__init__.py,sha256=VO4uQB6WjE3YSQyYkjIT_MvyifxoEGcwVMqj86Sbq_o,257
64
+ chaine/optimization/spaces.py,sha256=V9B2YtO4borD6UgC55_vuchxrM0E5gVqiW_Ky5g1WaM,17797
65
+ chaine/optimization/utils.py,sha256=2IdNfH0amKND6XQvwTCH3iMz3GPRVeCrrKkJ4cJklRo,3297
66
+ chaine-3.13.1.dist-info/RECORD,,
67
+ chaine-3.13.1.dist-info/WHEEL,sha256=MXJJ0F8jKJHeo3gqIKHGj-OCEmv0SmzrqL2y5h0WyCk,106
68
+ chaine-3.13.1.dist-info/METADATA,sha256=ZJlOLAhb2T6kJLFhOAS1RD1Wizf0NB-249R9BVPyo18,12465
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 1.9.1
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-macosx_11_0_arm64
5
+